Skip to main content

The Affirmative Opt-In Gate (consent_required)

consent_required is the tenant-owned affirmative opt-in gate. When you enable it, an outbound send on a gated channel requires a recorded, live opted_in consent row for the (contact, channel) pair, and a recipient who has never given consent is refused with 403 MESSAGING_CONSENT_REQUIRED. The gate’s own source header calls it the “positive-consent twin of the opt-OUT suppression path”: suppression blocks recipients who withdrew consent, this gate blocks recipients who never gave any. It ships off by default, and nothing on the platform side can enable it for you. This page walks through turning it on, scoping it, and operating it without blocking legitimate traffic.
This page covers the org-level gate. The per-contact consent ledger it reads (recording, lookup, expiry, receipts) is documented in Consent Management & Receipts.

What the gate is (and what it is not)

Three tenant knobs decide what a contact without a clean consent story receives, and they answer different questions: The two policies resolve the unknown tri-state (opted_in / opted_out / unknown): refuse or allow_with_logging, permit_on_missing or deny_on_missing answer on the contact’s behalf. consent_required resolves nothing. It demands a recorded grant: with the gate enabled, a non-exempt send to a contact with no opted_in row is blocked under every setting of the other two knobs. The gate is also not:
  • The TCPA known-litigator preflight, which blocks only US (+1) numbers on the litigator list.
  • The double-opt-in confirmation flow, which records consent after a send and does not gate the first send.
  • Opt-out suppression, which blocks recipients who withdrew.

A tenant-owned posture, off by default

The gate exists for operators whose regimes require affirmative opt-in before outbound contact:
  • GDPR Art. 6/7 (EU/EEA) — consent as the lawful basis for consumer marketing.
  • LGPD Art. 8 (Brazil) — the explicit-consent standard.
  • PDPA s. 14 (Singapore) — the consent-before-send obligation.
It is tenant-scoped and off by default. There is no platform or country-level switch that turns it on for you, and enabling it is a posture decision to take with counsel. Orbit enforces the posture you set and keeps the evidence trail; it never decides that a send is “compliant.”
The gate reads organizations.settings.consent_required:
Enable it by merging the object into your organization settings (owner role):
Two exemptions apply on top of the channel set, regardless of configuration:
  • The consent prompt itself. A double-opt-in confirmation message is how consent is gathered, so it is always allowed out.
  • Transactional traffic, while exempt_transactional is true (the default), per the table above.
For phone channels the gate matches recipients by their E.164 number; for the email channel it matches by the recipient’s address, so email opt-ins you record are honoured when you gate email.

How it composes with unknown_marketing_policy

The two knobs fire at different points and on different populations:
  1. This gate evaluates each directly addressed recipient at send time: does a live opted_in row exist for (contact, channel)?
  2. The marketing gate afterwards resolves contacts whose state is unknown through your unknown_marketing_policy.
In practice: with consent_required enabled on a channel, a contact with no ledger row is blocked here before the marketing policy is consulted, so on gated channels the gate is the stricter of the two for marketing traffic. unknown_marketing_policy keeps its role on channels you did not gate and for traffic this gate exempts, such as transactional sends under the default exemption. And nothing either knob permits overrides an explicit opted_out or a suppression entry: suppression drops the send before any policy is read. See Consent vs. Suppression. Enabling consent_required never changes your unknown-consent policies, and loosening those policies never weakens this gate.

Populate the ledger before you enable

Enabling the gate over an empty consent ledger blocks every non-exempt send on the gated channels with 403 MESSAGING_CONSENT_REQUIRED. Prepare the ledger first.
Record the grants you already hold before you flip enabled:
  1. Import historical opt-ins through the Consent API. POST /api/v1/compliance/consent writes the opted_in row the gate reads, including the channel and the grant’s metadata.
  2. Let double-opt-in confirmations land. A confirmed opt-in writes the same ledger row, so a contact mid-confirmation is covered the moment they confirm.
  3. Wire preference-center signups. Channel selections saved from your preference center should write an opted_in row per chosen channel.
A workable sequence: import what you can substantiate, enable with the narrow channel set (["sms"]), watch the block audit entries for one campaign cycle, then widen to ["sms", "mms"] and beyond. Also mind expiry. A grant stored with a valid_until window blocks again once the window lapses (details.consent_expired: true); the consent-management expiry surface lists grants that are about to lapse so you can re-confirm them before they do.

Failure shape, the settings cache, and rollback

A blocked send returns:
  • consent_expired: false — no opt-in was ever recorded; capture a first opt-in.
  • consent_expired: true — a grant existed but its valid_until lapsed; re-confirm the recipient.
  • The destination is redacted to its first five digits, both in the envelope and in the audit entry the gate writes for every blocked send, so a compliance review can rebuild the timeline without exposing numbers.
  • A blocked send is never charged: the gate runs before the billing hold.
  • If the consent lookup itself hits a backend error, the send fails closed with 503 SERVICE_UNAVAILABLE and is safe to retry with backoff.
The settings cache. Organization settings are held in an in-process cache of about 60 seconds. After a PATCH, allow up to a minute for the new posture to take effect on every API process; a send that lands inside the window may still see the previous posture. Rolling back safely. Set enabled: false and the gate returns to a no-op; the gated channels resume the prior single-opt-in behaviour within the cache window. Disabling deletes nothing: every ledger row you wrote stays in place for the next enablement. If enabling surfaced unexpected blocks, roll back in this order: disable first so traffic resumes, read the block audit entries to see exactly which recipients lacked a grant, record the missing opt-ins, then re-enable.