Public consent form
Orbit can host a public landing page where recipients enter their email or phone, choose channels, and opt in or out of receiving messages. Submissions write to the same consent surfaces as carrier-side STOP / START keywords —consent_records, channel_preferences, and suppression_list — so the platform’s outbound send gate immediately honours the new state.
The feature is off by default. Each tenant explicitly turns it on under Settings → Compliance → Public consent form. When disabled, the public URL returns 404.
When to use it
- The footer of email / SMS campaigns where you’d otherwise embed a vendor unsubscribe link.
- Sender bios (Instagram, LinkedIn) where recipients ask you to stop messaging.
- Operator-driven opt-in capture, e.g. when transcribing paper-form consent.
- Bulk re-permissioning campaigns after a privacy-policy change.
Enable the form
- Sign in as an owner or admin.
- Go to Settings → Compliance → Public consent form.
- Toggle Enable public consent form on.
- Copy the public URL (under the toggle) — it has the form
https://orbit.devotel.io/<locale>/consent/<tenantId>.
Optional configuration
All fields below are optional. Leave blank to use Orbit defaults. Branding- Business name — shown above the headline.
- Primary color — 3- or 6-digit hex (e.g.
#0ea5e9). Drives the submit button and success badge. - Logo URL — must be
https://(orhttp://). Rendered above the business name.
- Headline — replaces the default “Manage your preferences” (max 240 chars).
- Body — short explanatory paragraph (max 2000 chars).
- Footer — fine print, support contact, link to your privacy policy (max 1000 chars).
422 INVALID_CHANNEL. Leave all 11 channels selected to accept the platform default (email, fax, instagram, line, messenger, push, rcs, sms, viber, voice, whatsapp).
Pre-fill the recipient identifier
Append?contact=<email-or-phone> to the URL to pre-fill the form. The recipient can still edit the value before submitting.
Programmatic submissions
The form is a thin client over a public REST endpoint. Direct integrations (e.g. an embedded preference centre on your own marketing site) can POST against the same handler.Body
Errors
Read the tenant’s public config
For embedding teams that want to render their own UI against the same config the Orbit-hosted form uses:enabled: false and empty branding / copy / channels. Render a 404 — that matches how the Orbit-hosted page reacts.
What the form writes
Every submission writes to the same three surfaces the carrier-sidehandleOptIn / handleOptOut routes touch:
consent_records— one row per submitted channel withconsent_state = 'opted_in'/'opted_out'. The send-side gate at outbound time checks this column.contacts.channel_preferencesJSONB — per-channelopted_outflag flipped,global_opt_outflipped on opt-out, and an entry appended toconsent_historyfor audit continuity.suppression_list— opt-out inserts achannel='all'row that survives soft-delete. Opt-in setsrevoked_at = NOW()on every active row (audit-friendly, NOT a DELETE).
action: consent.public_opt_in / consent.public_opt_out).
Limits and abuse defence
- The POST + GET endpoints are rate-limited per source IP (
RATE_LIMIT_PUBLIC_UNAUTH— 10 requests per minute). - There is no Clerk session or API key on this route.
- Logs capture source IP, user-agent (truncated to 500 chars), and a contact-identifier kind classifier (
email/phone/whatsapp_id). - Suppression and consent state are authoritative in Postgres; the STOP-fence cache is a sub-RTT convenience that fails open.
Disabling the form
Toggle Enable public consent form off. The public URL returns404 from that moment, and the POST handler returns 422 INVALID_TENANT for that tenant — no in-flight submissions can land.
Stored consent records remain — disabling only stops new submissions. Re-enabling restores the previous configuration block (branding, copy, allowed channels) so an accidental toggle doesn’t lose the customisation.