Docs

Sites

AdminUpdated Sep 15, 2026

Sites

A site (identified by its cbid, a "Cookie Munch ID") is one domain or app property protected by a banner. This page covers creating, listing, and managing sites themselves, plus the site-scoped utility endpoints that aren't part of banner config or the consent log: domain verification, brand extraction, the install snippet, the cookie declaration, and cookie scanning.

All endpoints below require the sites scope: sites:read for every GET, sites:write for POST/DELETE. A key with no scopes claim (a legacy full-access key) can call all of them regardless. Cross-org access is structurally impossible — the org is derived from the API key, never passed as a parameter — so a cbid belonging to another org behaves exactly like an unknown one: a plain 404, never a 403.

GET /v1/sites

List every site in your org. There is no pagination; this returns the full collection.

curl https://api.cookiemunch.net/v1/sites \
  -H "Authorization: Bearer fck_…" \
  -H "User-Agent: Mozilla/5.0"
[
  {
    "cbid": "acme-com-9f3k",
    "orgId": "org_9k2m",
    "domain": "acme.com",
    "platform": "web",
    "verified": true,
    "verifyToken": "fcv_7a2e9c1b4d8f0e2a1c3b5d7f",
    "verifyMethod": "dns",
    "verifiedAt": 1719858421000
  }
]
import { createCookieMunch } from '@cookiemunch/sdk';
const fc = createCookieMunch({ apiKey: process.env.FC_KEY, baseUrl: 'https://api.cookiemunch.net' });
const sites = await fc.sites.list();

POST /v1/sites

Create a site.

Field

Type

Required

Description

domain

string

yes

The domain to protect, e.g. "acme.com".

cbid

string

no

Custom site identifier. The server generates one (dv-…) when omitted.

platform

web | ios | android | amp | other

no

The property type. Any other value, or omission, defaults to "web".

curl -X POST https://api.cookiemunch.net/v1/sites \
  -H "Authorization: Bearer fck_…" \
  -H "User-Agent: Mozilla/5.0" \
  -H "Content-Type: application/json" \
  -d '{ "domain": "acme.com" }'
{ "cbid": "dv-m3x8k2q1-a9f2b3c8", "orgId": "org_9k2m", "domain": "acme.com", "platform": "web" }

201 on success. 400 if domain is missing/blank. 409 if the requested cbid is already claimed — the message is intentionally generic ("could not create site") and never confirms whether the cbid belongs to your org or someone else's.

const site = await fc.sites.create({ domain: 'acme.com' });

GET /v1/sites/:cbid

curl https://api.cookiemunch.net/v1/sites/acme-com-9f3k \
  -H "Authorization: Bearer fck_…" \
  -H "User-Agent: Mozilla/5.0"
{
  "cbid": "acme-com-9f3k",
  "orgId": "org_9k2m",
  "domain": "acme.com",
  "platform": "web",
  "verified": true,
  "verifyToken": "fcv_7a2e9c1b4d8f0e2a1c3b5d7f",
  "verifyMethod": "dns",
  "verifiedAt": 1719858421000
}

Field

Description

cbid

Site identifier — use it in every sub-resource path below.

domain

The registered domain.

platform

web, ios, android, amp, or other.

verified

Whether domain ownership has been proven. consent/export and receipt require verified: true.

verifyToken

The token (fcv_ + 24 hex chars) to place per your chosen verification method. Generated at create time.

verifyMethod

Which method last verified the domain — dns, meta, file, or embed (set by the legacy Cookiebot-migration path); absent until verified.

verifiedAt

Epoch-ms of verification; absent until verified.

404 if the cbid doesn't exist, or belongs to another org.

const site = await fc.sites.get('acme-com-9f3k');

DELETE /v1/sites/:cbid

curl -X DELETE https://api.cookiemunch.net/v1/sites/acme-com-9f3k \
  -H "Authorization: Bearer fck_…" \
  -H "User-Agent: Mozilla/5.0"

204 on success, 404 if unknown/foreign. This is permanent and immediate — the site's config, consent log, and cookie declaration are deleted with it. There is no soft-delete or undo.

await fc.sites.delete('acme-com-9f3k');

POST /v1/sites/:cbid/verify

Checks domain ownership using the verifyToken from the site record, and marks the site verified on success.

Field

Type

Required

Description

method

dns | meta | file

yes

Which challenge to check.

curl -X POST https://api.cookiemunch.net/v1/sites/acme-com-9f3k/verify \
  -H "Authorization: Bearer fck_…" \
  -H "User-Agent: Mozilla/5.0" \
  -H "Content-Type: application/json" \
  -d '{ "method": "dns" }'
{ "verified": true, "method": "dns" }

On failure verified is false, with an optional reason — the response is still 200 either way (verification failure isn't a request error):

{ "verified": false, "reason": "TXT record not found" }

400 if method isn't one of dns/meta/file. 501 if domain verification isn't wired up on this deployment (self-host without the network/DNS deps injected).

const result = await fc.sites.verify('acme-com-9f3k', 'dns');

POST /v1/sites/:cbid/brand

"Match my site": best-effort fetches the site's homepage over HTTPS and extracts theme tokens for pre-filling a banner design. Returns an empty suggestion object (never an error) if the homepage can't be fetched or the fetched host doesn't match the site's domain.

curl -X POST https://api.cookiemunch.net/v1/sites/acme-com-9f3k/brand \
  -H "Authorization: Bearer fck_…" \
  -H "User-Agent: Mozilla/5.0"
{
  "suggestion": {
    "background": "#0b0f1a",
    "text": "#f5f5f5",
    "highlight": "#5b8def",
    "fontFamily": "Inter, sans-serif",
    "palette": ["#0b0f1a", "#5b8def", "#f5f5f5"]
  }
}

501 if brand extraction isn't configured on this deployment.

const { suggestion } = await fc.sites.brand('acme-com-9f3k');

GET /v1/sites/:cbid/snippet

Returns the exact <script> install tag for a site, so you can generate installation instructions programmatically instead of hardcoding the tag format.

Query param

Values

Description

blockingmode

auto | manual | checklist

Overrides the emitted data-blockingmode. Invalid/omitted values fall back to auto.

culture

BCP-47 tag, e.g. fr

Emits data-culture when it matches the pattern ^[a-zA-Z]{2,8}(-[a-zA-Z0-9]{1,8})*$; silently dropped otherwise.

curl "https://api.cookiemunch.net/v1/sites/acme-com-9f3k/snippet?blockingmode=auto" \
  -H "Authorization: Bearer fck_…" \
  -H "User-Agent: Mozilla/5.0"
{
  "snippet": "<script id=\"CookieMunch\"\n  src=\"https://cdn.cookiemunch.net/consent.js\"\n  data-cbid=\"acme-com-9f3k\"\n  data-blockingmode=\"auto\"></script>",
  "src": "https://cdn.cookiemunch.net/consent.js",
  "api": "https://api.cookiemunch.net",
  "cbid": "acme-com-9f3k",
  "blockingMode": "auto"
}

api is only meaningfully different from src's origin when consent.js is served from a separate CDN than the API (COOKIE_EMBED_ORIGIN vs COOKIE_API_BASE).

const install = await fc.sites.snippet('acme-com-9f3k', { blockingMode: 'auto' });

GET /v1/sites/:cbid/cookies

The latest categorized cookie declaration (from the most recent scan), as { updatedAt, cookies }.

curl https://api.cookiemunch.net/v1/sites/acme-com-9f3k/cookies \
  -H "Authorization: Bearer fck_…" \
  -H "User-Agent: Mozilla/5.0"
{
  "updatedAt": 1719858421000,
  "cookies": [
    { "name": "_ga", "category": "statistics", "domain": ".acme.com", "provider": "Google Analytics", "expiry": "2 years" }
  ]
}

updatedAt is 0 if no scan has ever run. 501 if the cookie-declaration feed isn't wired up. Trigger a fresh scan below.

const declaration = await fc.sites.cookies('acme-com-9f3k');

GET / POST /v1/sites/:cbid/scan

POST kicks off an async Playwright crawl of the site to discover and classify cookies; GET reads the current status.

# Start a scan
curl -X POST https://api.cookiemunch.net/v1/sites/acme-com-9f3k/scan \
  -H "Authorization: Bearer fck_…" \
  -H "User-Agent: Mozilla/5.0"

202 with { "status": "scanning" } when a scan starts; 409 with { "status": "already-scanning" } if one is already running for this cbid.

# Poll status
curl https://api.cookiemunch.net/v1/sites/acme-com-9f3k/scan \
  -H "Authorization: Bearer fck_…" \
  -H "User-Agent: Mozilla/5.0"
{ "status": "idle", "lastScannedAt": 1719858421000 }

lastScannedAt is null if no scan has ever completed. 501 on deployments without the scanner configured (it requires a Playwright Chromium install).

await fc.sites.scan('acme-com-9f3k');
const status = await fc.sites.scanStatus('acme-com-9f3k');

GET /v1/sites/:cbid/ab

Results for the site's active A/B banner experiment (configured via experiment in site config).

curl https://api.cookiemunch.net/v1/sites/acme-com-9f3k/ab \
  -H "Authorization: Bearer fck_…" \
  -H "User-Agent: Mozilla/5.0"
[
  { "variant": "A", "impressions": 5210, "optIns": 3012, "optInRate": 0.578 },
  { "variant": "B", "impressions": 5188, "optIns": 3401, "optInRate": 0.6556 }
]

501 if A/B reporting isn't wired up on this deployment.

const results = await fc.sites.ab('acme-com-9f3k');

Errors

All endpoints on this page follow the shared conventions: { "error": "…" } bodies, 404 for unknown-or-foreign cbid, 403 insufficient_scope for a scoped key missing sites:read/sites:write, and 501 for an unconfigured optional feature on a self-host. See conventions & errors for the full status code table.

Next: site config to configure the banner for one of these sites, or consent log, stats & export to read the decisions it produces.

Was this page helpful?