TCPA Posture Across SMS and Voice
This page assembles the TCPA-relevant controls into one ordered reference you can hand to counsel. The TCPA pieces on the live docs are spread across a voice-statute table, a quiet-hours operator guide, a content scanner, and a litigator screen — the goal here is the one posture a single reading covers.1. The federal window across channels
The federal TCPA dialing window is 8 AM–9 PM recipient-local (47 U.S.C. § 227(b)(1)(B), 47 CFR § 64.1200(c)(1)). How strictly it bites depends on the channel and the send path, so read this section per lane. Campaign and dialer voice (US recipients): always hard-blocked outside the federal window. Predictive, progressive, preview, and agentless dialer modes, scheduled callbacks, and the pre-dial gate are refused with422 TCPA_FEDERAL_DIALING_WINDOW_BLOCKED outside the
federal window regardless of your tenant settings — this is the one
platform-owned, fail-closed control in the quiet-hours stack. There is
no tenant toggle that relaxes it. The read-only check behind it is the
same one the send path runs — you can preview it before launch with
GET /api/v1/compliance/quiet-hours/preview?phone=<E.164>&channel=voice.
A blocked result carries a DST-safe next_allowed_at ISO timestamp;
schedule to it instead of retrying.
Ad-hoc 1:1 voice: advisory until you opt in. Dashboard and
softphone dials dispatch outside the window with a decision logged —
until you enable the voice channel on your org quiet-hours gate,
which turns the same evaluation into a hard hold
(422 TCPA_DIALING_WINDOW_BLOCKED).
SMS and other messaging: your org gate, plus the content scanner.
The org gate’s enabled-channel default for sms, mms, rcs,
viber, telegram, and voice is 08:00–21:00 recipient-local
(09:00–21:00 for WhatsApp and Meta channels). On top of that, the
pre-send policy scanner checks TCPA quiet hours on the SMS and
WhatsApp marketing lane for US +1 recipients and returns an advisory
finding in the default warn mode — while your org runs strict
mode, the same finding rejects the send with 422 POLICY_VIOLATION.
Transactional traffic (OTPs, alerts, account notifications) is exempt
from both layers.
Resolution order for a campaign send: the campaign row’s own window,
then the org fallback window, then the platform default 21:00 → 09:00.
Fallbacks can only narrow an enabled channel gate, never widen it.
Full mechanism on
Quiet hours configuration and
Pre-send policy scanner.
2. State mini-TCPA overlays
Seven US states layer a stricter mini-TCPA statute on top of the federal hours. Federal law expressly permits stricter state rules (47 U.S.C. § 227(e)), so the binding window for a US recipient is the most-restrictive-wins intersection: the earlier end hour, the union of all banned weekdays. The overlay can tighten; it never widens.
Mississippi’s statutory 7:30 PM cutoff is rounded conservatively to
the 7 PM hour boundary. The recipient’s state is resolved from the
NANP area code; a state-driven block returns
reason
outside_state_window or state_blocked_day with the statute
citation (e.g. Fla. Stat. § 501.059) in the error details so
counsel can trace the decision without reading platform code. The
full derivation, resolution chain, and per-row statute citations live
on US state calling windows.
3. Timezone, DST, and fail-safe behavior
The gate works in recipient-local time, and the fail posture when the recipient’s timezone can’t be resolved is deliberately different per path:- Campaign and dialer voice: fail-closed, always. A US recipient whose timezone resolves nowhere (no area-code mapping, no hint) is refused before any window math — an unresolved timezone is never treated as “in window”.
- Ad-hoc and messaging sends: your
unknown_timezone_policy.skippasses (fail open),denyblocks with422 QUIET_HOURS_TIMEZONE_UNKNOWN, andenforce_utcevaluates against UTC for a deterministic window. The voice channel ships withdenyas its default for US recipients; every other channel default isskip.
timezone_override hint to the
preview call when your CRM knows better than the area code implies
(relocated numbers). Blocked timestamps are DST-safe — next_allowed_at
is a UTC ISO instant you can hand straight to your scheduler, so clock
transitions reopen a window in wall-clock hours, never split seconds.
Both failure postures are worked end-to-end in
Troubleshooting: resolve dialing-window blocked
calls and Troubleshooting:
state mini-TCPA blocked voice
calls.
4. Content and copy gates
Quiet hours are time-of-day; the content side of the TCPA is what the copy itself must carry. The pre-send policy scanner runs on every outbound message before dispatch and collapses its rules into apass / warn / block verdict:
- Missing opt-out — a message that reads as promotional but carries no opt-out phrase (STOP keyword coverage across 14 locales).
- TCPA quiet hours on SMS/WhatsApp — marketing sends outside
08:00–21:00 recipient-local, advisory in
warnmode and enforceable instrictmode. - SHAFT, spam score, and sender-registration gates — adjacent carrier-contract rules in the same scan.
block
verdict: warn (default) records the finding on the message and in
the X-Policy-Violations response header; strict rejects the send
with POLICY_VIOLATION; off skips the scan entirely. Lint a draft
before launch with POST /api/v1/messages/lint — same scanner, same
verdict, nothing sent. Full rule table and mode semantics on
Pre-send policy scanner.
5. Consent: the prior-express-written-consent taxonomy
The TCPA distinguishes transactional messages (requires prior express consent) from marketing messages (requires prior express written consent — a signed or recorded agreement naming the disclosure the recipient agreed to). Orbit’s consent ledger records the distinction on every grant:consent_type—marketing,transactional, or your own purpose category.lawful_basis— the GDPR Art 6 basis, mirrored so one ledger answers both regimes.consent_text_versionandconsent_proof_url— which disclosure the recipient agreed to and where your proof of it lives.
POST /api/v1/compliance/consent per (contact, channel) pair; read
a pre-send gate from /lookup; and answer a discovery request with
the tenant-wide /export (CSV or JSON, owner/admin keys). Where your
evidence tier needs a recorded recipient reply — the form TCPA
written consent usually takes — drive the managed double opt-in
handshake instead of a bare record. Time-bounded consent
(valid_until / expires_in_days) carries an expired flag on
lookups so an old grant stops relaxing gates by itself. Mechanics on
Consent management and
Double opt-in.
Two places consent surfaces move gates directly: with your
consent_overrides_quiet_hours flag true (the default), a recipient
you hold a consent record for passes your org quiet-hours gate on
non-voice channels; and a consented recipient flows past the
known-litigator gate under a bypass audit trail (next section). Neither
carve-out applies to voice — voice gates on window math alone.
6. Known-litigator screening
A single non-consented A2P SMS to a professional TCPA plaintiff costs 1,500 per message. The known-litigator gate flags recipients on the platform’s litigator list (contact pre-flag, cache, live lookup, seed — cheapest first) before billing and blocks the send with403 TCPA_KNOWN_LITIGATOR_BLOCKED. The gate is scoped to US +1 SMS
and MMS traffic and is off by default — you opt in per
organization with tcpa_check_enabled in general settings. A
recipient with an opted_in consent record for the channel passes
through under a consented_bypass audit entry instead of a block,
so your own permitted lists keep working. The check fails open on a
lookup outage. Voice is deliberately out of scope — the
troubleshooting levers there are the dialing windows above.
Mechanics on TCPA known-litigator
gate.
7. Opt-out and suppression under the TCPA
The TCPA requires honoring revocation on every channel. A contact who replies STOP (or opts out through the Preference Center or the Consent API) lands on the suppression list with scopeall — the
voice and dialer gates read that same list, so an SMS opt-out also
stops calls to the number. Bulk-import a legacy list with
POST /api/v1/compliance/suppression-list/import (phone rows also
mirror onto the DNC list and flag the matching contacts) and export
the ledger back out for an audit. Suppression is a hard gate at every
send site — campaign, contact import, or API send alike, dropped
before dispatch. Mechanics on Opt-out & suppression
lists.
Assemble the checklist
One page, end to end, in the order your lanes run:- Federal voice window — campaign/dialer hard block, ad-hoc opt-in gate; the layer nothing relaxes.
- State overlays — the seven mini-TCPA states above; your own gate can narrow them further, never widen.
- Fail-safe posture — unresolved timezone behavior per path;
DST-safe
next_allowed_aton every hold. - Content gates — scan mode (
warn/strict), missing-opt-out, and the quiet-hours SMS rule; lint before launch. - Consent taxonomy — marketing vs transactional records with
consent_text_version+ proof; double opt-in for the written tier. - Litigator screening —
tcpa_check_enabledon US SMS/MMS with the consented-bypass audit trail. - Suppression — STOP keywords, Preference Center, Consent API, and
CSV imports converge on one scope-
alllist.
See also
- Quiet hours configuration —
the org gate, campaign fallback, and
unknown_timezone_policyknobs. - US state calling windows — the
overlay table and the statutes each
citationpoints back to. - Troubleshooting: resolve dialing-window blocked calls — the triage hub for the 422 family.
- Troubleshooting: state mini-TCPA blocked voice calls — the per-state overlay variant end-to-end.
- Pre-send policy scanner — scan modes, the TCPA SMS rule, and the compose-time linter.
- Consent management — the ledger the consent taxonomy records.
- TCPA known-litigator gate — the opt-in screen and its bypass audit trail.
- Opt-out & suppression lists — the hard gate every opt-out path converges on.
- Send gates — the full gate stack (DNC, RND, emergency stop) the window layers share.