Docs

Recording & reading consent

POST /v1/consent, batch, idempotency, and reading state & history.

Record

POST /v1/consent
Authorization: Bearer sk_live_…
Idempotency-Key: 4b0f…

{
  "subject": "email:user@example.com",
  "purpose": "marketing_email",
  "state": "GRANTED",
  "channel": "banner",
  "locale": "en",
  "pageUrl": "https://acme.com/signup"
}

The subject can be an internal id, <type>:<value>, or an object { "identifiers": [{ "type", "value" }] } to create the subject if it does not exist. state can only be GRANTED, DENIED or WITHDRAWN.

201 response: { id, subjectId, subjectCreated, purpose, state, purposeVersion, collectedAt, receiptId }.

Batch

POST /v1/consent/batch with { "records": [ … ] } (max 100). Issues one receipt per subject covering all of that subject’s records in the batch.

Read the state

GET /v1/subjects/email:user@example.com/consent?purpose=marketing_email
→ { "subjectId": "…", "purposes": {
     "marketing_email": { "state": "GRANTED", "purposeVersion": 3,
       "needsReconsent": false, "latestPurposeVersion": 3 } } }

Published purposes with no record for the subject appear with their defaultState. needsReconsent is true if the stored version lags a later version published as RECONSENT_REQUIRED, or if the record has expired.

History

GET /v1/subjects/{ref}/consent/history (sk_ only) returns up to 500 append-only rows, each with its proof and the supersedesId chain.