Consent API reference

Embed
Preview of the card
<a href="https://forumulate.com/guides/cookies-consent-api"><img src="https://forumulate.com/guides/_api/public/orgs/046a9bc0-d530-43ae-9bae-af7945008cda/spaces/36aa4df0-1e95-4cef-8ae9-795169441345/pages/6c7deb75-1449-4e3e-a021-3bf1c4a24fc1/social-card.svg?v=3e7ae33eec8b" alt="Consent API reference" width="600" height="315"></a>

Everything in the console is available over the API. All routes require a session or token with org.manage_settings (space overrides require space.update), except the inbound webhook, which is authenticated by its signature.

The generated, always-current endpoint schemas also live in the API reference.

Read the org config

GET /orgs/:orgId/consent

Returns the stored config with the secret stripped, plus two derived fields:

{
  "provider": "cookiemunch",
  "preset": { "cbid": "your-site-id" },
  "webhookConfigured": true,
  "webhookUrl": "https://your-site/api/hooks/consent/<org-id>"
}

webhookConfigured tells you whether a signing secret is set; the secret itself is never returned.

Write the org config

PUT /orgs/:orgId/consent

Body is the full config object. Unknown keys are rejected (strict validation) — this is attacker-influenced tenant input, so there's no free-text HTML anywhere.

{
  "provider": "custom",
  "custom": {
    "mode": "loader",
    "loaderUrl": "https://cdn.acme.com/cmp.js",
    "verifiedHosts": ["cdn.acme.com"]
  },
  "policyVersion": "2026-09",
  "webhookSecret": "whsec_optional_write_only"
}

The response is the same stripped view GET returns — the secret is never echoed back. Omit webhookSecret to keep the stored one.

Fields

Field

Type

Notes

provider

enum

One of the providers. Required.

preset

object

Publishable vendor id — cbid, dataDomainScript, customerId, or websiteUuid.

custom

object

For provider: "custom" — loader or adapterApi mode. See Custom CMP.

hosted

object

For provider: "hosted" — categories, copy, links, theme.

policyVersion

string

Your own version label for the active policy.

webhookSecret

string

Write-only. The webhook signing secret. Never returned.

Rotate the webhook secret

POST /orgs/:orgId/consent/webhook-secret
→ 201 { "secret": "whsec_…", "webhookUrl": "https://…/api/hooks/consent/…" }

Generates and stores a fresh secret, returned once. The previous secret stops verifying immediately.

Per-space override

GET /orgs/:orgId/spaces/:spaceId/consent
PUT /orgs/:orgId/spaces/:spaceId/consent

The body is either { "mode": "inherit" } or a full config with "mode": "override" (every org-level field, plus mode). Reads and writes strip the secret just like the org routes.

Inbound webhook

POST /api/hooks/consent/:orgId

Authenticated by an HMAC-SHA256 signature over the raw body, keyed with that org's secret — see Consent & DSAR webhook. Returns 200 on a verified delivery, 401 on a bad signature, 404 when the org has no secret configured.

The Forumulate teamUpdated