Docs

OpenAPI spec

AdminUpdated Sep 15, 2026

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.json
curl https://api.cookiemunch.net/v1/openapi.json

This 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. the cbid path parameter, the standard error response) shared across operations so they aren't redefined per-path.

  • openapi-schemas.tscomponents.schemas: the typed shapes for Site, ConsentRecord, DsarRequest, Vendor, RopaEntry, WebhookSubscription, and the rest of the resources.

  • openapi-paths.tspaths: 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

ApiKeyBearer

http / bearer

Authorization: Bearer fck_<hex>

ApiKeyHeader

apiKey / header

X-API-Key: fck_<hex>

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.ts

Or 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-client

Both 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/sdk instead of generating a client from this spec. It ships richer types (enums, discriminated unions, a typed CookieMunchApiError) 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/mcp server 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.

Was this page helpful?