Consent inspector
Consent touches every channel — SMS, voice, email, push, WhatsApp, MMS, fax — and it’s one thing Orbit owns end to end. The Consent inspector (Audience → Consent) shows, for a single contact, the complete consent ledger plus the exact allow/block verdict the platform would compute if a destination tried to deliver to them today. It’s the surface you open before you queue a send, and the surface you open when a send was suppressed and you need to know why. Before this page existed, the only way to read a contact’s consent ledger or preview the destination verdict was a raw API call. The inspector closes that gap — the same two endpoints the compliance team hits with curl, wrapped in a form.What the inspector shows
Type acontact_id (cnt_… — the identifier shown on the contact’s record page, or the id returned by the Contacts API) into Look up a contact and the page splits into two cards.
Consent records — one row per consent ledger entry, newest first:
Verdict simulator — pick a channel (and optionally a policy template) and press Run consent check. You get back the same structured verdict the destination dispatch path computes at delivery time — Allowed or Blocked, with the machine-readable reason and human label.
The verdict reasons and what to do with each:
When to open it
- Preflight a single contact before you queue them into a campaign, add them to a destination, or hand them to an agent. The verdict simulator runs the identical decision the destination dispatch path runs at delivery time, so a
Blockedanswer now is a send that would be suppressed later — catch it in the inspector, not in the delivery log. - Debug a suppressed send. When a message was suppressed on a consent gate, paste the contact id and rerun the check against the channel that was suppressed. The reason code tells you which gate fired (
opted_out,revoked,expired,policy_mismatch, or the refuse-on-unknown defaults). - Compliance audit. For GDPR Art 30 burden-of-proof purposes, the records card exposes the lawful basis, policy template, and captured-at timestamp of every grant and revoke in the ledger — the same evidence the export endpoints can hand to a DPA.
How the verdict is computed
The verdict folds three stores, per the consent and suppression model:consent_records— the append-only ledger. Every opt-in or opt-out flip inserts a new row; the decision reads the newest active row (revoked_at IS NULL). A partial unique index guarantees at most one active row per (contact, channel), so the verdict is deterministic.channel_preferences— the contact profile’s per-channel preference flags, consulted only when the ledger is empty: an explicit profile opt-in or opt-out is surfaced so the inspector doesn’t lie “no records on file” about a positive opt-in captured via import, merge, flows, or CRM sync. A top-levelglobal_opt_outflag suppresses every channel and returnsopted_out.- Suppression list — the opt-out suppression mirror that the send gate consults for hard blocks.
deny_on_missing or permit_on_missing — see Consent default policy) can invert only the two “no record / unknown state” branches. Four gates are always enforced regardless of tenant posture, because they’re universal-legal: a positive opt-out, a revoked grant, a policy-template mismatch, and an expired validity window.
Fixing a verdict from the surface
The inspector is a read surface — the grant/revoke writes stay on the surfaces that own them. From aBlocked verdict:
- To consent the contact — open the contact’s profile in the audience workspace and set the channel opt-in; the write lands in the ledger. Rerun the verdict and the reason moves to
allowed. - To revoke — use the same contact-level opt-out control. The revocation inserts a new ledger row (the ledger is append-only), stamps
revoked_at, and the verdict flips to Blocked withrevoked. - To restore (re-consent after a revocation) — set the opt-in again from the contact profile. The new row supersedes the revoked one and the verdict returns to Allowed.
API walkthrough
Two endpoints back the inspector. Both are restricted to owner / admin / developer roles, tenant-scoped, and rate-limited (60 reads/min for the ledger endpoint, 600 verdicts/min for the check endpoint — the check is the dispatch-path hot path).Read the full ledger for a contact
Run a single destination verdict
policy_template is optional; omit it to skip the template gate):
cdp_consent_check) with the inputs and verdict — that’s the forensic trail you can tail instead of an audit row per call.
Grant / revoke from the API
The targeted grant or revoke goes to the compliance consent endpoint. An opt-out also mirrors the channel into the suppression list so the send gate sees it within the same call:201 with the new ledger consent_record_ids. You can pass a phone/email identifier instead of contact_id — the endpoint resolves it the same way the lookup does.
Worked example: verify a verdict and restore consent
- Open Audience → Consent inspector.
- Paste the contact you were about to send to — say
Cnt_4f3a9b1c2d(casing is normalized), press Inspect. The page confirms the profile identity inline so you’re not working against the wrong hash. - In the Verdict simulator, pick
smsand press Run consent check. Suppose it comes back Blocked — contact opted out of this channel. - The records card explains why: the newest sms row has state
opted_outand aRevokedtimestamp. - Check with the contact, then open their profile page and set the sms opt-in back on.
- Re-run the check. It now returns Allowed — active grant on record, with the new
consent_record_idandgranted_at. You’re clear to send.
See also
- Consent and suppression model — the full three-store model concept page
- Consent default policy — the
deny_on_missingvspermit_on_missingtenant posture - Consent management — the ledger-management operations page
- Consent suppression export — exporting the ledger for a DPA
- Contacts API — where a
contact_idcomes from