Consent receipts
CSV + JSON read APIs for every persisted consent decision.
Overview
Every consent decision is signed and stored append-only. The dashboard exposes two read APIs scoped to your workspace: a paginated JSON list for the UI, and a CSV export for downloads and SIEM pipelines. Both require a dashboard session token (the same Supabase JWT the dashboard uses) and the x-cookielint-tenant header to pin the workspace.
New receipts are signed with Ed25519 once the environment keypair is configured (see Verify a consent receipt). Older rows retain their HMAC-SHA256 signature and remain internally verifiable.
CSV export
The CSV export is the canonical retrieval path. It includes the full hashed subject identity, the hashed IP and user-agent, the regime, the decisions, and the receipt signature. Viewers and editors can read paginated receipts; admins and owners can export.
curl "https://api.cookielint.com/admin/v1/tenants/$TENANT_ID/consent-receipts.csv" \
-H "Authorization: Bearer $JWT" \
-H "x-cookielint-tenant: $TENANT_ID" \
-G \
--data-urlencode "siteId=$SITE_ID" \
--data-urlencode "from=2026-04-01T00:00:00Z" \
--data-urlencode "to=2026-05-01T00:00:00Z"Filters: siteId, subjectHash, source (BANNER_ACCEPT_ALL, BANNER_REJECT_ALL, BANNER_SAVE_PREFS, PREFS_MODAL, API_TOGGLE, GPC, REVOKE, IMPORTED), regime, countryCode, from, to. Each export itself writes a CONSENT_RECEIPTS_EXPORTED entry to the audit log, so legal can prove who pulled what and when.
JSON read API
For a JSON view, use /admin/v1/tenants/:tenantId/consent-receipts (without the .csv suffix) and paginate via the returned cursor. Each receipt looks like this:
{
"id": "4f9a...",
"siteId": "...",
"bannerConfigVersion": 7,
"regime": "GDPR",
"locale": "en-GB",
"decisions": [
{ "category": "NECESSARY", "status": "GRANTED" },
{ "category": "ANALYTICS", "status": "DENIED" }
],
"subjectHash": "7c3a...e21f",
"countryCode": "DE",
"source": "BANNER_REJECT_ALL",
"signature": "...",
"capturedAt": "2026-04-15T12:04:09.000Z",
"receivedAt": "2026-04-15T12:04:09.421Z"
}The IP and user-agent are HMAC-peppered before storage and never returned in the read API. Subject identity is a SHA-256 of a per-visitor random ID; we never store raw identifiers.

