Integrations
API keys, webhooks and the integration catalogue.
/v1/api-keysAPI keys for this workspace
Needs: 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". |
/v1/api-keysCreate an API key
The 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. |
/v1/api-keys/{id}Revoke a key
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 | — |
/v1/integrationsIntegrations, with whether each is connected and working
Needs: 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. |
/v1/integrations/{key}Disconnect an integration
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 | — |
/v1/integrations/{key}Connect / configure an integration
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 |
/v1/integrations/{key}/verifyRe-verify an integration
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 |
|---|---|---|
| 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 |
/v1/webhooksStop sending consent decisions anywhere
Needs: A signed-in panel session, sent as Authorization: Bearer <access token>.
| Status | Body | When |
|---|---|---|
| 204 | — |
/v1/webhooksThe consent webhook for this workspace, if there is one
Needs: 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. |
/v1/webhooksPoint the consent webhook somewhere
The 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. |
/v1/webhooks/rotateIssue a new signing secret; the old one stops immediately
Needs: 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. |
Next groupMembers