01API keys for this workspace
/v1/api-keysNeeds: A signed-in panel session, sent as Authorization: Bearer <access token>.
| Status | Body | When |
|---|---|---|
| 200 | ApiKeyDto[] |
| Field | Type | What it is |
|---|---|---|
| id required | string | |
| name required | string | |
| prefix required | string | The first few characters, to tell keys apart. |
| createdAt required | string | |
| lastUsedAt | string | null | |
| revokedAt | string | null | Revoked keys stop working instantly but stay listed — a key that read consent records is part of the answer to "who saw this". |
02Create an API key
/v1/api-keysThe key is returned here and is unrecoverable afterwards.
Needs: A signed-in panel session, sent as Authorization: Bearer <access token>.
| Field | Type | What it is |
|---|---|---|
| name required | string | Example: "Data warehouse sync" |
| Status | Body | When |
|---|---|---|
| 200 | CreatedApiKeyDto |
| Field | Type | What it is |
|---|---|---|
| id required | string | |
| name required | string | |
| prefix required | string | The first few characters, to tell keys apart. |
| createdAt required | string | |
| lastUsedAt | string | null | |
| revokedAt | string | null | Revoked keys stop working instantly but stay listed — a key that read consent records is part of the answer to "who saw this". |
| key required | string | The key. Shown once and unrecoverable afterwards. |
03Revoke a key
/v1/api-keys/{id}Revoked, not deleted: a key that was used to read consent records is part of the answer to "who saw this".
Needs: A signed-in panel session, sent as Authorization: Bearer <access token>.
| Name | Where | Type | What it is |
|---|---|---|---|
| id required | path | string |
| Status | Body | When |
|---|---|---|
| 204 | — |
04Integrations, with whether each is connected and working
/v1/integrationsNeeds: A signed-in panel session, sent as Authorization: Bearer <access token>.
| Name | Where | Type | What it is |
|---|---|---|---|
| category | query | "Install" | "Tag Management" | "Analytics" | "Advertising" | "Data / Tagging" | "Developer / API" | |
| status | query | "ok" | "warn" | "off" | |
| kind | query | "signal" | "gated" | "platform" | "api" | |
| q | query | string |
| Status | Body | When |
|---|---|---|
| 200 | IntegrationsListDto |
| Field | Type | What it is |
|---|---|---|
| connected required | number | Connected AND live — a card that does nothing is never counted as connected. |
| warnings required | number | |
| total required | number | |
| items required | IntegrationStateDto[] | |
| items[].key required | string | |
| items[].name required | string | |
| items[].category required | string | |
| items[].kind required | "platform" | "api" | "signal" | "gated" | How this vendor is handled — signal (we speak its consent API), gated (its script is blocked until consent), platform (an install route) or api (one of our own outbound surfaces). The panel groups by this, because a Connect button means something different in each case. |
| items[].availability required | "live" | "planned" | live when code acts on it today; planned when nothing does yet. |
| items[].summary required | string | One line saying what actually happens. |
| items[].connectable required | boolean | False for anything that cannot be connected — every platform and planned. |
| items[].enabled required | boolean | |
| items[].status required | string | off | ok | warn |
| items[].mode required | string | null | |
| items[].config required | object | |
| items[].connectedAt required | string | null | |
| gatedVendors required | GatedVendorDto[] | Vendors covered by tag gating rather than by a card. Listed so the page can say "these are handled, here is how" instead of showing fifteen dead Connect buttons. |
| gatedVendors[].name required | string | |
| gatedVendors[].category required | "marketing" | "preferences" | "analytics" | The consent category its script belongs to. |
| gatedVendors[].match required | string | A substring of its script URL, offered as a starting blocking pattern. |
05Disconnect an integration
/v1/integrations/{key}Needs: A signed-in panel session, sent as Authorization: Bearer <access token>.
| Name | Where | Type | What it is |
|---|---|---|---|
| key required | path | string |
| Status | Body | When |
|---|---|---|
| 204 | — |
06Connect / configure an integration
/v1/integrations/{key}Needs: A signed-in panel session, sent as Authorization: Bearer <access token>.
| Name | Where | Type | What it is |
|---|---|---|---|
| key required | path | string |
| Field | Type | What it is |
|---|---|---|
| enabled | boolean | |
| mode | string | |
| config | object |
| Status | Body | When |
|---|---|---|
| 200 | IntegrationStateDto |
| Field | Type | What it is |
|---|---|---|
| key required | string | |
| name required | string | |
| category required | string | |
| kind required | "platform" | "api" | "signal" | "gated" | How this vendor is handled — signal (we speak its consent API), gated (its script is blocked until consent), platform (an install route) or api (one of our own outbound surfaces). The panel groups by this, because a Connect button means something different in each case. |
| availability required | "live" | "planned" | live when code acts on it today; planned when nothing does yet. |
| summary required | string | One line saying what actually happens. |
| connectable required | boolean | False for anything that cannot be connected — every platform and planned. |
| enabled required | boolean | |
| status required | string | off | ok | warn |
| mode required | string | null | |
| config required | object | |
| connectedAt required | string | null |
07Re-verify an integration
/v1/integrations/{key}/verifyNeeds: A signed-in panel session, sent as Authorization: Bearer <access token>.
| Name | Where | Type | What it is |
|---|---|---|---|
| key required | path | string |
| Status | Body | When |
|---|---|---|
| 200 | IntegrationStateDto |
| Field | Type | What it is |
|---|---|---|
| key required | string | |
| name required | string | |
| category required | string | |
| kind required | "platform" | "api" | "signal" | "gated" | How this vendor is handled — signal (we speak its consent API), gated (its script is blocked until consent), platform (an install route) or api (one of our own outbound surfaces). The panel groups by this, because a Connect button means something different in each case. |
| availability required | "live" | "planned" | live when code acts on it today; planned when nothing does yet. |
| summary required | string | One line saying what actually happens. |
| connectable required | boolean | False for anything that cannot be connected — every platform and planned. |
| enabled required | boolean | |
| status required | string | off | ok | warn |
| mode required | string | null | |
| config required | object | |
| connectedAt required | string | null |
08Stop sending consent decisions anywhere
/v1/webhooksNeeds: A signed-in panel session, sent as Authorization: Bearer <access token>.
| Status | Body | When |
|---|---|---|
| 204 | — |
09The consent webhook for this workspace, if there is one
/v1/webhooksNeeds: A signed-in panel session, sent as Authorization: Bearer <access token>.
| Status | Body | When |
|---|---|---|
| 200 | WebhookDto |
| Field | Type | What it is |
|---|---|---|
| url required | string | |
| mode required | "all" | "granted-only" | "revoked-only" | |
| enabled required | boolean | |
| lastStatus | number | null | |
| lastError | string | null | |
| lastAttemptAt | string | null | |
| lastSuccessAt | string | null | |
| failures required | number | Consecutive failures. Delivery stops once it hits the cap. |
| stopped required | boolean | True when delivery has given up and needs attention. |
10Point the consent webhook somewhere
/v1/webhooksThe signing secret comes back on the FIRST save only, and never again. HTTPS-only, and private addresses are refused — this value makes the server issue an outbound request to wherever it points.
Needs: A signed-in panel session, sent as Authorization: Bearer <access token>.
| Field | Type | What it is |
|---|---|---|
| url required | string | Example: "https://example.com/hooks/cmpstack" |
| mode | "all" | "granted-only" | "revoked-only" | Which decisions are worth sending. granted-only and revoked-only exist so a customer syncing a suppression list is not woken by decisions that do not change it. |
| enabled | boolean |
| Status | Body | When |
|---|---|---|
| 200 | WebhookSecretDto |
| Field | Type | What it is |
|---|---|---|
| url required | string | |
| mode required | "all" | "granted-only" | "revoked-only" | |
| enabled required | boolean | |
| lastStatus | number | null | |
| lastError | string | null | |
| lastAttemptAt | string | null | |
| lastSuccessAt | string | null | |
| failures required | number | Consecutive failures. Delivery stops once it hits the cap. |
| stopped required | boolean | True when delivery has given up and needs attention. |
| secret required | string | The HMAC signing key. Shown once and never returned again — store it now. |
11Issue a new signing secret; the old one stops immediately
/v1/webhooks/rotateNeeds: A signed-in panel session, sent as Authorization: Bearer <access token>.
| Status | Body | When |
|---|---|---|
| 200 | WebhookSecretDto |
| Field | Type | What it is |
|---|---|---|
| url required | string | |
| mode required | "all" | "granted-only" | "revoked-only" | |
| enabled required | boolean | |
| lastStatus | number | null | |
| lastError | string | null | |
| lastAttemptAt | string | null | |
| lastSuccessAt | string | null | |
| failures required | number | Consecutive failures. Delivery stops once it hits the cap. |
| stopped required | boolean | True when delivery has given up and needs attention. |
| secret required | string | The HMAC signing key. Shown once and never returned again — store it now. |