OpenAPI spec
- Written for
- + Written for
- Deprecated
- + Deprecated
- Applies to
- + Applies to
OpenAPI spec
The entire /v1 Developer API is described by a hand-written OpenAPI 3.1 document, served live from the running server rather than checked in as a static file that can drift from the actual route handlers.
GET /v1/openapi.jsoncurl https://api.cookiemunch.net/v1/openapi.jsonThis is the one unauthenticated route on the /v1 surface (besides the routes' own OPTIONS preflights) — no API key required, so tooling (API explorers, SDK generators, CI schema-diff checks) can fetch it freely.
Where it lives
The document is assembled in packages/server/src/openapi.ts (buildOpenApiDocument()) from three cohesive sibling modules in the same package:
openapi-shared.ts— reusable helpers and parameter/response fragments (e.g. thecbidpath parameter, the standard error response) shared across operations so they aren't redefined per-path.openapi-schemas.ts—components.schemas: the typed shapes forSite,ConsentRecord,DsarRequest,Vendor,RopaEntry,WebhookSubscription, and the rest of the resources.openapi-paths.ts—paths: every/v1/*route with its method(s), parameters, request body, and response schema.
dev-api.ts imports buildOpenApiDocument directly and serves its return value as JSON on GET /v1/openapi.json — there's no build step, code generator, or route-decorator system producing this file. It's a plain TypeScript object that a human keeps in lockstep with dev-api.ts / dev-api-sites.ts by hand, which is also why its shape (operation IDs, schema names) can be relied on to be stable rather than regenerated per-build.
{
"openapi": "3.1.0",
"info": {
"title": "Cookie Munch Developer API",
"version": "1.0.0",
"description": "Stable, versioned developer API for Cookie Munch. Authenticate every request with an API key (`Authorization: Bearer fck_…` or `X-API-Key: fck_…`). The organization is derived from the key — never pass an orgId."
},
"servers": [{ "url": "/" }],
"security": [{ "ApiKeyBearer": [] }, { "ApiKeyHeader": [] }],
"components": { "securitySchemes": { "...": "..." }, "schemas": { "...": "..." } },
"paths": { "...": "..." }
}(servers[0].url defaults to /, i.e. relative to wherever you fetched the document from; pass ?serverUrl=https://api.cookiemunch.net semantics aren't exposed via query string today — the field simply reflects the deployment the document was built for.)
Security schemes
Two equivalent schemes are declared on the document — pick whichever your tooling models more naturally; the server accepts either header on every actual request regardless of which one a generated client happens to use:
Scheme | Type | How |
|---|---|---|
|
|
|
|
|
|
Every operation lists both under security, except GET /v1/openapi.json itself, which declares security: [] (matching that it's the one public route).
What's covered
The document enumerates every /v1/* path: sites (CRUD, verification, brand extraction, config, v2 flow ops, snippet), consent (stats, log, export, chain verification, subject export/erasure, receipts), cross-device subject lookup, cookies and scans, A/B results, brand kits, the banner library, preference records, DSAR, vendors, RoPA, org members, API keys, usage, and webhooks. It does not document the dashboard's session-authenticated /api/v1/* routes or the embed's public, unauthenticated routes (/config, /consent.js, consent ingest, the cookie-declaration feed) — this spec is scoped to the API-key-authenticated Developer API only.
Generating a client
Point any OpenAPI-3.1-compatible generator at the live document to produce a typed client in a language other than TypeScript. With openapi-typescript:
npx openapi-typescript https://api.cookiemunch.net/v1/openapi.json -o cookiemunch.d.tsOr with openapi-generator-cli for other languages:
npx @openapitools/openapi-generator-cli generate \
-i https://api.cookiemunch.net/v1/openapi.json \
-g python \
-o ./cookiemunch-clientBoth approaches produce request/response types and, depending on the generator, a full HTTP client — useful when you're not on Node/TypeScript, or when you want codegen wired into a CI schema-diff check (fetch the document on each deploy, fail the build if a field your integration depends on disappears).
Note: if you're on TypeScript/JavaScript, prefer the hand-written
@cookiemunch/sdkinstead of generating a client from this spec. It ships richer types (enums, discriminated unions, a typedCookieMunchApiError) than a generic OpenAPI codegen produces, and is released from the same monorepo as the server, so it tracks the API without a regeneration step. The@cookiemunch/mcpserver is in turn built on top of the SDK, not on generated OpenAPI code.
Versioning
The document's info.version reflects the /v1 surface's semantic version (currently 1.0.0 by default in buildOpenApiDocument, overridable by the caller that constructs it). Because the API prefix itself is /v1, a breaking change would ship under a new prefix and a new document rather than mutating this one's meaning underneath existing integrations — additive fields and new optional parameters can appear within the current document without a version bump.
Next: Authentication & scopes if you haven't issued a key yet, or Sites to start making real calls.