Voice Guard: the Federal Dialing-Window Decision Check
Outbound voice dispatch in Devotel Orbit passes one recipient-level decision check before the call is placed: is this recipient reachable under the US federal TCPA window — 8 AM to 9 PM recipient-local time — at this moment? This page documents that check: the gates it runs at, how the verdict is computed, the error surface a blocked dial returns, and what distinguishes this guard from your tenant-owned quiet-hours settings. The worked example at the end walks a flagged +1 recipient through the correction path.1. Where the voice firewall is deployed
The guard is wired at the dispatch decision point, not the campaign definition. Every outbound voice dispatch channel consults it before placing the call:- The public voice-dispatch API — every
POST /voice/calls-class dispatch request. - Dialer pacing workers — predictive, progressive, preview, and agentless campaign dials.
- Callback dispatch workers — virtual-hold and scheduled callbacks.
- The voice gateway pre-dial gate — the final hop before the carrier egress.
2. How the gate evaluates
The decision is a short, deterministic chain. Non-+1 recipients and non-NANP numbers skip the federal window entirely; everything else is evaluated against recipient-local time.- Recipient check — the guard reads the E.164 destination. A
non-US, non-NANP recipient is allowed immediately (reason
non_us_recipient); tenant quiet-hours or state overlays may still apply downstream, but the federal wire is skipped. - Timezone resolution — for a +1 recipient the guard resolves the
timezone from the NANP area-code map. If no map entry resolves, the
check fails closed: because TCPA jurisdiction cannot be disproved,
the dial is denied rather than guessed (reason
timezone_unresolved). - Local-hour evaluation — the resolved timezone converts the evaluation instant into a recipient-local hour. An unresolvable hour fails closed the same way.
- Window comparison — 8 AM to 9 PM recipient-local is allowed
(reason
inside_federal_window); anything else is denied, and the result carries the UTC instant the window next opens (next_allowed_at), computed with DST-safe hour arithmetic.
3. What a hard block means
A blocked evaluation in enforce mode returns HTTP422 with the error
code TCPA_FEDERAL_DIALING_WINDOW_BLOCKED. That code is intentionally
distinct from TCPA_DIALING_WINDOW_BLOCKED (your tenant quiet-hours
gate), so audit filtering can separate federal-window denials from
org-configured window denials.
The error body carries a structured detail object so your retry logic
never has to parse message text:
The
reason enum:
4. How this differs from your tenant-owned controls
Every other compliance gate — tenant quiet-hours, DNC/consent, country blocks, the orgunknown_timezone_policy (skip / enforce_utc /
deny) — is something you own: it is configurable per tenant, defaults
open, and fails open when resolution is impossible.
This guard is the one exception. It accepts no tenant toggle and no
per-tenant opt-out, and its timezone-unresolved path always fails
closed regardless of your org policy setting. The federal
1,500-per-call penalty (47 U.S.C. § 227(b)(1)(B)) is the reason
that asymmetry exists: the guard checks one input (the recipient’s NANP
timezone) and owns one window (8 AM–9 PM), independent of anything you
configure. Any override posture — for example a tenant state-list
exception — belongs in the tenant quiet-hours layer, never here; this
gate has no exemption knobs.
State overlays still matter, but they intersect downstream: the
state calling windows overlay can
only narrow within the federal window (e.g. Florida’s 8 PM close); it
never reopens a federally closed hour. The relationship is spelled out
on quiet-hours preview.
5. Worked example: a +1 recipient gets flagged
A campaign dial targets+1 305 555 0101 at 22:40 recipient-local
(11:40 PM at the evaluation instant — before the dialer’s batch spins
up): the area-code map resolves America/New_York, local hour 22 is
outside 8–21, and the enforce-mode dispatch receives:
reason first:
outside_federal_window— schedule the dial tonext_allowed_at. Queue workers re-poll on that instant; a campaign launch holds to the smallestnext_allowed_atacross recipients.timezone_unresolved— the recipient’s area code resolved to no timezone entry (common on Canadian or Caribbean +1 numbers). Fix the contact record’s timezone, then re-dispatch; without the correction every retry fails closed identically.non_us_recipient/inside_federal_window— no action; the verdict is advisory for downstream gates only.
next_allowed_at is UTC ISO and DST-safe, schedule against
that field and never re-derive the opening hour in your own scheduler.
See also
- Quiet-hours preview — the read-only “would this dispatch now” endpoint across channels
- US state calling windows — the mini-TCPA overlays that narrow the federal window
- TCPA posture across SMS and voice — the tenant-owned control map
- Troubleshooting compliance error codes —
the full error-code index including both
TCPA_FEDERAL_DIALING_WINDOW_BLOCKEDandTCPA_DIALING_WINDOW_BLOCKED