Compliance send-gate error codes
When a send refuses before dispatch, Orbit answers with a machine-readable envelope — anerror.code plus HTTP status and
details — naming the exact gate that fired. This page is the single
routing surface for those codes: read the symptom table first to sort
the code by the gate family, then drop into the per-error entry for the
root cause, the tenant-owned control to change, a curl that re-checks
the posture, and the escalation path when a re-submit is owed.
Every control on this page is tenant-owned — you enable the gate,
register the sender, execute the BAA, or lift the override. The one
platform-owned control on this page (the US TCPA federal voice
window) is called out per code. Orbit enforces the gates; approvals
always come from the carrier or regulator reviewing your packet.
1. Symptom table — map the code to the gate
Sort the envelope’serror.code by family. The deep-dive link is the
per-error walkthrough below or the page that owns the topic.
2. Quiet hours
Quiet hours hold sends until the recipient-local window opens. Voice and SMS resolve the same recipient-local clock; the envelope carries an absolutenext_allowed_at UTC instant you schedule against directly.
QUIET_HOURS_BLOCKED / TCPA_QUIET_HOURS / TCPA_DIALING_WINDOW_BLOCKED — 422
Root cause. Your own quiet-hours posture window (Settings →
Timezone Policy) refuses the send; on voice the same gate emits the
TCPA_ spelling.
Tenant control. Widen, narrow, or disable the window under
Settings → Timezone Policy — this gate is opt-in per
Send Gates.
Re-check the posture. Preview the resolved window per destination
before a rollout:
next_allowed_at, or adjust
your own window. Open a ticket only if the returned next_allowed_at
contradicts the window you configured.
TCPA_FEDERAL_DIALING_WINDOW_BLOCKED — 422 (platform-owned)
Root cause. The sole platform-global guard: campaign and dialer
voice to US (+1) recipients outside 8 AM–9 PM recipient-local is
hard-blocked. No tenant toggle widens it — the statutory exposure is
not yours to waive.
Tenant control. None. Recovery is scheduling at next_allowed_at.
Escalate. A false timezone resolution is the only ticket class —
when the recipient’s number resolves to a region it is not in. The full
guard is on The TCPA federal voice guard.
TCPA_STATE_DIALING_WINDOW_BLOCKED — 422 (platform-owned)
Root cause. A stricter state overlay (Florida’s Sunday ban,
Mississippi’s early close, and the OK / LA / AL / AR / WV windows) sits
on top of the federal rail on a most-restrictive-wins rule.
Tenant control. None — schedule inside the state window. The
overlay map is on
US state calling windows.
Escalate. Same class as the federal guard — a recipient-local
mis-resolution with the payload’s resolved state named.
TCPA_TIMEZONE_UNKNOWN / QUIET_HOURS_TIMEZONE_UNKNOWN — 422
Root cause. The recipient’s timezone could not be resolved (neither
NANP area-code nor E.164 country prefix matched). Voice fails closed by
default to bound TCPA exposure; messaging defaults to fail open
(skip).
Tenant control. The org-level unknown_timezone_policy knob —
skip (allow) or deny (fail closed). Voice operators opting into
skip unblock unresolved recipients; messaging tenants opting into
deny start blocking them.
Re-check. The same
GET /compliance/quiet-hours/preview?destination=… shows whether a
destination resolves.
Escalate. If a real E.164 number fails to resolve, open a ticket
with the destination and the meta.request_id from the envelope.
3. Sender identity gates
These gates run before the message is accepted — nothing queues.SENDER_ID_NOT_REGISTERED / SENDER_ID_NOT_APPROVED — 422
Root cause. The from value is a custom alphanumeric sender ID
with no registration row on the account, or a row stuck at pending /
rejected / expired. E.164 numbers, the platform default sender, and
the shared pool never raise this — only named alphanumerics fire it.
Tenant control. Register the sender under Settings → Sender IDs,
and read the country’s registration field on
GET /api/v1/compliance/country-requirements
to know whether the destination demands it.
Re-check.
rejected row: read the reviewer notes, fix the cited
gap, and re-submit on the
pending number / Sender ID runbook.
NO_SENDER_CONFIGURED / SENDER_REQUIRED — 422
Root cause. NO_SENDER_CONFIGURED — the account has no usable
sender at all (no from, no default sender, no owned number, no trial
pool assignment). SENDER_REQUIRED — a direct API send simply did not
name any sender selector.
Tenant control. Claim a number (the dashboard CTA deep-links into
/numbers) or set a default sender; for SENDER_REQUIRED, send from
or one of the sender selectors.
Escalate. Never — both fix in your own settings.
4. Regional gates
These gates are opt-in per market — your organization enables them per country; tenants not operating in the region skip the probes entirely.MESSAGING_BR_SENDER_NOT_REGISTERED / …_SA_… / …_AE_… / …_SG_… — 422
Root cause. For an alphabetic sender, the destination country
(BR — Anatel, SA — CITC, AE — TDRA, SG — SGNIC) demands an
approved country-registration entry for that sender, and none exists.
Numeric senders skip this probe — carriers provision them at purchase
time.
Tenant control. Registrations are filed per-sender on
Sender-ID Registration; the
regulator’s approval is theirs to give.
Re-check.
MESSAGING_IN_DLT_TEMPLATE_REQUIRED / …_CONTENT_MISMATCH — 422
Root cause. The send to India carries no dlt_template_id
(REQUIRED), or carries one whose registered content template you now
mismatched — body drifted or sender ≠ registered header (MISMATCH,
enforced only when the template is locally registered as approved).
Tenant control. Always pass metadata.dlt_template_id (or
metadata.dlt.template_id) on IN sends; keep the body matching the
registered content and send from the registered header.
Escalate. Register the template in-country or lift the org-level
gate scope per the
Troubleshoot India DLT gate page —
that page owns the re-submit choreography.
MESSAGING_MX_NOM184_CONSENT_MISSING — 422
Root cause. A promotional A2P SMS to MX without an opt-in
consent_records row stamped nom184=true for the recipient phone.
Tenant control. Record NOM-184 consent on the contact (Contacts →
Consent), or send transactional traffic with
metadata.nom184_exempt=true — use that flag responsibly; the audit
trail records it.
Escalate. Never — the fix lives in your consent ledger.
5. DNC scrub
DNC_CONTACT / DNC_NUMBER — 422
Root cause. The recipient’s contact row carries dnc=true, or the
number sits in the scrubbed list. This is fail-closed only once you
opt in (dnc_sync_enabled) — otherwise the gate is not there.
Tenant control. The org opt-in dnc_sync_enabled; per-row list
sources on DNC Scrubbing.
Escalate. Never — either lift the recipient from the DNC list with
a documented reason, or don’t send.
DNC_SYNC_NOT_ENABLED — 403
Root cause. The pre-flight GET /dnc/check / POST /dnc/scrub
refuses because the org never enabled the scrub or the sync feed is
not yet synced.
Tenant control. Enable dnc_sync_enabled; a synced snapshot
retires the gate.
Escalate. If the feed stays synced: false past a re-enable, open
a ticket with the check response payload.
6. HIPAA BAA
HIPAA_BAA_REQUIRED — 422
Root cause. HIPAA mode is opted-in and the send’s audience or
content matched PHI — the workspace refuses PHI-bearing traffic until
your Business Associate Agreement is executed and in-term.
Tenant control. The BAA execution flow on
BAA — attest PHI scope, preview, e-sign by typing
the name.
Re-check.
executed means no current agreement, and HIPAA mode
itself stays off until then.
Escalate. For a workspace-role block on the BAA flow itself, the
403 path is on
Troubleshooting: HIPAA enable blocked.
HIPAA_BAA_GATE_DB_FAIL — 500
Root cause. The gate’s own read failed — a family the gate refuses
to guess, so it fails closed.
Tenant control. Retry with backoff; if it persists, this is a
platform issue — open a ticket with meta.request_id.
7. Policy scan
POLICY_VIOLATION — 422
Root cause. The pre-send scanner (TCPA / SHAFT / GDPR topic rules)
blocked the message body. Your org’s scan duty policy_scan_mode
decides: off logs only, warn surfaces the verdict, block refuses
the send.
Tenant control. The policy_scan_mode duty on the compliance
settings surface (API PATCH /settings/compliance/policy-scan-mode),
with warn as the default.
Re-check.
block plus a WARN-shaped verdict is the worked path: lift the
duty to warn and re-send.
Escalate. Never — the scanner names the legislation family in
details; honour it or fix the copy.
POLICY_SCAN_MODE_LOOKUP_FAILED — 503
Root cause. The mode resolver could not read your org’s current
duty and the cache is cold — it refuses to fall back to warn for a
block-duty tenant.
Tenant control. Retry with backoff; this is transient by design
and Retry-After friendly.
Worked flows
1. Brazil SMS blocked at send. Envelope:422 MESSAGING_BR_SENDER_NOT_REGISTERED. You opted into the BR gate
and your branded sender lacks an approved Anatel registration row.
File it on Sender-ID Registration;
re-check with GET /compliance/country-requirements. Until approval
lands, numeric senders keep sending.
2. India SMS rejected twice. First 422 MESSAGING_IN_DLT_TEMPLATE_REQUIRED (no dlt_template_id); after you
add one, 422 MESSAGING_IN_DLT_CONTENT_MISMATCH with
details.mismatch_type: body — the registered template is precise.
Match the body to the registered content exactly, or
walk the IN DLT resubmit.
3. HIPAA campaign refused. 422 HIPAA_BAA_REQUIRED — your campaign
audience is PHI-adjacent and the BAA reads pending. Execute the BAA
flow (BAA), re-read it with
GET /compliance/baa, then relaunch. A wizard-side PHI designation you
honestly never intended lifts to none; the
PHI deep dive owns both
paths.
4. Voice window blocked. 422 TCPA_DIALING_WINDOW_BLOCKED at
10 PM recipient-local. FEDERAL absent from the code → this is your
quiet-hours window, so either reschedule at next_allowed_at or widen
the window. Codes carrying FEDERAL are the one platform-owned control
— schedule; no toggle exists.
5. Scanner blocks on warn-shaped copy. 422 POLICY_VIOLATION
because duty was block. Read policy_scan_mode with the curl above,
decide, re-send.
When nothing fits
Any 5xx-class code (COMPLIANCE_CHECK_UNAVAILABLE,
HIPAA_BAA_GATE_DB_FAIL, POLICY_SCAN_MODE_LOOKUP_FAILED,
SENDER_ID_CHECK_UNAVAILABLE) is transient — retry with backoff before
touching posture. Any 4xx/409 class means a posture change is owed and
retrying the same request burns rate-limit budget without moving the
state.
If a 422 persists past the posture fix, open a ticket carrying the
code, the HTTP status, the meta.request_id from the envelope, the
referencing asset id (sender id / campaign id / profile id), and the
destination country — the same payload the
lifecycle-errors page
calls the full packet.
Cross-reference map
Each per-code topic here links out to the page that owns the deep choreography:- Send Gates — the canonical pre-send gate inventory.
- Sender-ID Registration and the country matrix — registration snippets and statuses.
- HIPAA and BAA — the BAA state machine, the e-sign flow, and the PHI vocabulary.
- DNC Scrubbing — sources, freshness, the check endpoint.
- TCPA Known-Litigator Gate — the consented-bypass companion to the window family.
- DLT-India Onboarding and IN DLT gates — Principal Entity, headers, content templates.
- RMD Filing Lifecycle — the FCC filing states the voice gates respect.
- Compliance profile lifecycle errors — the attach/mutate/delete 422/409 codes the send gates defer to.
- Pending numbers and Sender IDs — re-submission choreography for
rejectedregistrations.