Audit export & receipts: proving consent
- Written for
- + Written for
- Deprecated
- + Deprecated
- Applies to
- + Applies to
Audit export & receipts: proving consent
What it's for
The consent log is the ledger; audit export and receipts are the two ways you turn that ledger into something you can hand to someone else. They answer two different questions:
"Prove your whole site's consent history for this quarter." → bulk CSV export, for a DPO, auditor, or regulator.
"Prove what this one visitor agreed to." → a single, portable signed receipt, for a support ticket, a legal request, or a visitor who emails asking "what did I actually agree to?"
CSV export
Export a site's full consent history over a time range:
GET /api/v1/:cbid/export?from=&to=This returns Content-Type: text/csv with a consent-log.csv attachment — one row per consent record — ready to hand off without any conversion step. Unlike the paginated /consent/log endpoint (capped at 1000 rows per call), export walks the full range you ask for, which is what makes it the right tool for "give me everything from this audit period" rather than "show me recent activity."
Requirement: both /export and /consent/log require the site to be verified (domain ownership confirmed) before they'll return data. This stops a leaked or guessed cbid from being used to scrape another site's consent history — verification status is set when you register a property under Dashboard → Properties.
To pull an export yourself, issue an API key under Dashboard → Developers → API keys with the Consent read scope (consent:read), then call the endpoint with your site's cbid and date range. There's no bulk "download CSV" button in the dashboard UI today — this is a Developer API operation, which is why the API key screen exists as part of the same Privacy Ops workflow as DSAR and preferences.
Signed consent receipts
A receipt is a structured, ISO/IEC 27560-inspired proof-of-consent document for a single decision, built from its stamp (the same identifier you already use in the DSAR export/erase dialogs):
GET /api/v1/:cbid/receipt/:stampThe JSON receipt includes:
Field | Description |
|---|---|
| Receipt schema version ( |
| The site's |
| ISO-8601 timestamp of the decision |
| The consent |
| Visitor region at decision time |
| Per-purpose breakdown — category, human-readable purpose text, and whether it was granted |
| For any category or named purpose that isn't currently granted, whether it was actively |
| Optional linked privacy-policy URL + version, when configured |
Where your site config has a controller identity, jurisdiction, or withdrawal-mechanism set, the receipt includes those too, so the document is self-contained — a third party doesn't need to look anything up elsewhere to understand who collected the consent or how it can be withdrawn.
Signing
Every receipt ships as { receipt, signature }, HMAC-SHA256-signed over a canonical (stable key order) JSON serialization — so the pair can travel between systems and still be verified as untampered, with no shared database access required by the verifying party. If your deployment has asymmetric receipt keys configured, the JSON also carries an Ed25519 publicSignature + keyId, verifiable against the org's public keys at:
GET /api/v1/:cbid/receipt-keysThat endpoint is intentionally unauthenticated (it only exposes public keys) so any third party — a regulator, a visitor's lawyer, another system — can independently verify a receipt without ever touching your dashboard or API keys. Retired keys stay listed so older receipts keep verifying after a rotation.
Formats
The same receipt is available in three formats via content negotiation:
Request | Response |
|---|---|
default | Signed JSON ( |
| Self-contained HTML page — good for pasting into a support reply or printing |
| Downloadable PDF, sent as an attachment |
Note: Receipts require both a verified site domain and a configured signing secret on the server (
CONSENT_SIGNING_KEY/RECEIPT_SECRET). If receipts aren't configured, the endpoint returns501instead of silently failing.
Getting the stamp
Both tools key off a stamp. The most common way to get one in the dashboard is via Dashboard → Privacy → DSAR: when you open the Export or Erase dialog on a request, you're filling in exactly the cbid + stamp pair these endpoints need. If a visitor supplies you their own receipt ID (surfaced to them after they interact with the banner, if your integration exposes it), that's the same value.
Access via the Developer API
Issue an API key under Dashboard → Developers → API keys with:
Consent scope (
consent:read) for CSV export and log queries.Receipts scope (
receipt:read) for signed receipts.
Both are one-click checkboxes in the scope picker when creating or editing a key, so you can hand a narrowly-scoped key to, say, a compliance vendor who only needs receipt lookups, without giving them consent-log or DSAR access.
When to use which
CSV export — bulk reporting, a regulator's request covering many visitors, internal audit prep.
Signed receipt — one visitor asks "prove what I agreed to," or you need a portable, independently-verifiable artifact for a single decision (e.g. attached to a support ticket or legal file).
Compliance value
Together, export and receipts are what turn "we technically log consent" into "we can prove it, on demand, to anyone who asks — including someone with no access to our systems." That's the difference between a CMP that satisfies a checkbox and one that survives a real regulatory inquiry.
See also: Consent log · DSAR requests