/v1-consent records a visitor's per-purpose consent decisions (an audit trail) and reads back the latest one. It's the server-side source of truth behind the Web SDK's consent namespace, which POSTs here for you — but you can call it directly from any client.

Records consent — does not enforce it (yet)

/v1-consent records decisions to an audit trail; it does not yet block ingestion when a visitor denies. A recorded granted: false does not stop future events from being collected. The only consent enforced at ingestion today is the fingerprint-strip gate (context.fingerprint is dropped without an explicit grant — see Event ingestion). Server-side enforcement of analytics consent is planned; until then, gate tracking client-side — see Consent — DPDP & GDPR.

The path is /v1-consent (one segment)

The endpoint is <apiHost>/v1-consent — a single hyphenated segment, like /v1-batch. /v1/consent (two segments) is not a route and returns 404.

Authentication

/v1-consent uses method-aware key permissions:

MethodPurposeKey required
POSTRecord a decisionwrite or admin (uk_live_)
GETRead the latest decisionread or admin (uk_read_)

Any other method returns 405 Method not allowed. The endpoint is rate-limited to 60 requests per minute per (organization, client IP) — see Errors & rate limits.

Record a decision — POST /v1-consent

curl -X POST https://YOUR_PROJECT_REF.supabase.co/functions/v1/v1-consent \
  -H "Authorization: Bearer uk_live_YOUR_WRITE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "purpose": "analytics",
    "granted": true,
    "anonymousId": "anon_xyz789",
    "userId": "user_456"
  }'

Request body

FieldTypeRequiredNotes
purposestringyesThe consent purpose, e.g. analytics, fingerprinting. Max 64 characters.
grantedbooleanyestrue = consent given, false = denied.
anonymousIdstringyesThe subject's anonymous ID. Max 128 characters.
userIdstringnoThe known user ID, once identified. Max 128 characters.

The decision is stored against a canonical id — your userId when present, otherwise the anonymousId — so a decision recorded while anonymous still applies after the visitor is identified. The server also records the request IP, user-agent, and a source of sdk.

Response

{ "success": true, "purpose": "analytics", "granted": true }

Validation failures return 400 with the reason in error (e.g. purpose is required (non-empty string), purpose exceeds 64 chars, granted is required (boolean), anonymousId exceeds 128 chars). A storage failure returns 500 Failed to record consent decision.

curl "https://YOUR_PROJECT_REF.supabase.co/functions/v1/v1-consent?purpose=analytics&anonymousId=anon_xyz789" \
  -H "Authorization: Bearer uk_read_YOUR_READ_KEY"

Query parameters

ParameterRequiredNotes
purposeyesThe purpose to look up. Missing → 400.
anonymousIdyesThe subject's anonymous ID. Missing → 400.
userIdnoIf present, used as the canonical id for the lookup (matching how the decision was recorded).

Response

When a decision exists, the most recent one is returned:

{ "purpose": "analytics", "granted": true, "recorded": true, "created_at": "2026-06-10T10:00:00.000Z" }

When none exists:

{ "purpose": "analytics", "granted": null, "recorded": false }

Next

Last updated 2026-06-10

We use cookies for analytics — to understand how visitors use UMAP360 and improve the product. Essential cookies (session, forms) always run; analytics cookies wait for your call. See cookie policy.