Skip to main content
The widget fetches your tenant’s active consent template, renders the purposes as toggles alongside the legal clauses, collects the subject’s identifier, and records their decision. It is anonymous and scoped to your portal UUID — no API key, no bearer token, no CAPTCHA.
This is the public consent surface: the subject asserts their own identifier and the server records their decision. Managing consent state for an already-authenticated user is a different API — contact support if that is what you need.

Quickstart

That is the whole integration for the common case. The built-in form handles the toggles, the identifier field, and the three actions: Accept all, Save preferences, and Reject all. The server localizes purpose and clause text from Accept-Language. The SDK owns only the chrome copy — buttons and badges — in en, es, and pt.

How decisions are recorded

When the subject submits, the SDK serializes their per-purpose choices into the shape the server stores. Two rules are enforced before anything is sent:
  • Mandatory purposes are always recorded as granted. A purpose marked mandatory is coerced to accepted regardless of the toggle, and its toggle renders locked on.
  • Every purpose in the template is included — the SDK iterates the template’s purposes, not only the ones the user touched.
“Save preferences” is hidden when the template has no optional purposes.

createConsent(options)

ConsentController

Server types

Decision and result

Headless usage

Bring your own UI, or a preset identifier from your session, and drive the submit directly. The widget still fetches the template so submit knows the purpose keys and can coerce the mandatory ones.
submit() rejects if the template has not loaded yet. Wait for state() to reach ready, or for the ready event.

Errors

Privacy notes

  • The subject asserts their own identifier. This is an anonymous surface, so the identifier is a claim, not a proof — never treat a recorded decision as authentication.
  • The endpoint is write-only. The widget records a decision and cannot read existing ones back.
  • Clause content is rendered with textContent, never as HTML, so server-supplied copy cannot inject markup into your page. Line breaks are preserved.
  • Responses are enumeration-safe. A templateId that does not exist, or belongs to another tenant, returns the same generic error as any other failure — probing for valid IDs yields nothing.

Embedding

No camera, no engine, no secure-context requirement. See Embedding requirements.