> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting: resolve dialing-window blocked voice calls

> Resolve 422 TCPA_DIALING_WINDOW_BLOCKED, TCPA_TIMEZONE_UNKNOWN, and TCPA_FEDERAL_DIALING_WINDOW_BLOCKED — map the error to the gate that fired, check recipient state resolution, and set the self-serve fix.

# Troubleshooting: resolve dialing-window blocked voice calls

A voice call held by a dialing window fails with a `422` before it ever
reaches the phone network — no SIP is dispatched, no carrier sees it,
and no trunk or codec change will clear it. Every block in this class
answers with four fields in the error details: `reason`, the resolved
`timezone`, `local_hour` at the recipient, and `next_allowed_at`. Those
four fields, plus which of the three error codes you received, tell you
which gate fired and what to change.

This page maps each code to its fix. For the concept behind the gates
(which states carry an overlay, why weekends matter), see
[US state calling windows](/compliance/state-calling-windows) — this
page works the errors, not the statutes.

## Symptom → cause index

Find your error code and reason first, then go to the section that works
it.

| Error code                            | `details.reason`                                                                                | Gate that fired                                                                                                                        | Go to                                                                                                           |
| ------------------------------------- | ----------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `TCPA_DIALING_WINDOW_BLOCKED`         | `outside_window`, `wrong_day`, or a stricter state overlay                                      | The **tenant opt-in gate** — your own voice quiet-hours setting is on and the recipient-local hour fell outside your window            | [The tenant opt-in gate fails open until you enable it](#the-tenant-opt-in-gate-fails-open-until-you-enable-it) |
| `TCPA_TIMEZONE_UNKNOWN`               | `unknown_timezone_deny`                                                                         | Either gate — a US (+1) recipient whose area code resolved no timezone, and the call **fails closed**                                  | [When the recipient's timezone can't resolve](#when-the-recipients-timezone-cant-resolve)                       |
| `TCPA_FEDERAL_DIALING_WINDOW_BLOCKED` | `outside_federal_window`, `outside_state_window`, `state_blocked_day`, or `timezone_unresolved` | The **campaign/dialer hard block** — automated voice outside the federal 8 AM–9 PM recipient-local window (or a tighter state overlay) | [The campaign/dialer hard block has no override](#the-campaigndialer-hard-block-has-no-override)                |

One distinction cuts most triage short: `TCPA_DIALING_WINDOW_BLOCKED`
comes from **a gate you turned on** — relax your own window or schedule
around it. `TCPA_FEDERAL_DIALING_WINDOW_BLOCKED` comes from the one gate
you cannot turn off — you can only schedule around it.

## "About to dial Florida on a Sunday?" — read the reason code back to its statute

You get `422 TCPA_DIALING_WINDOW_BLOCKED` — or
`TCPA_FEDERAL_DIALING_WINDOW_BLOCKED` from a campaign — and the error
details carry a `reason` and, for state-driven blocks, a `citation`.
Work the two worked dials from the
[state calling windows page](/compliance/state-calling-windows) as the
diagnostic pattern: same moment, two states, opposite outcomes.

Both dials are evaluated at **Sunday 8:30 PM recipient-local**:

**Miami, FL (area code 305)** → blocked. The area code resolves `305 → FL`,
and Florida's overlay (8 AM–8 PM, Sunday banned) intersects the federal
window to 8 AM–8 PM with no Sunday dialing. The 422 details read:

```json theme={null}
{
  "code": "TCPA_DIALING_WINDOW_BLOCKED",
  "details": {
    "reason": "state_blocked_day",
    "timezone": "America/New_York",
    "local_hour": 20,
    "next_allowed_at": "2026-08-31T12:00:00.000Z"
  }
}
```

**Dallas, TX (area code 214)** → allowed. `214 → TX`, Texas carries no
overlay, the federal 8 AM–9 PM window applies unchanged, and 8:30 PM is
still inside it. (An hour later it would come back
`outside_federal_window`.)

The reason codes map back to the statute, not to a platform quirk:

| `reason`                 | What it tells you                                                                                                                                                                                                                           | The fix                                                                                                                                                                          |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `state_blocked_day`      | The recipient's state bans dialing on this weekday at **any** hour — Florida, Mississippi, Louisiana, Alabama, Arkansas, and West Virginia ban Sunday (the state table is on [US state calling windows](/compliance/state-calling-windows)) | No hour survives a day ban. Reschedule to `next_allowed_at` (Monday 8 AM for the Florida example) — retrying the same day always re-blocks                                       |
| `outside_state_window`   | A state overlay tightened the end hour (8 PM in FL/OK/LA/AL; 7 PM in MS) and the recipient-local hour fell outside the intersected window                                                                                                   | Schedule to `next_allowed_at`. If the block surprises you — "federal says 9 PM" — the overlay is why; the overlap column of the state table shows the resulting window per state |
| `outside_federal_window` | The recipient is in a state with no overlay and the hour is outside the plain federal 8 AM–9 PM window                                                                                                                                      | Schedule to `next_allowed_at`                                                                                                                                                    |

For state-driven blocks, the error details also carry a `citation` —
see [Reading the citation in the error](#reading-the-citation-in-the-error)
below. For the full statutes behind each overlay, jump straight to the
[state calling windows page](/compliance/state-calling-windows); don't
try to re-derive them from the error.

## When the recipient's timezone can't resolve

`422 TCPA_TIMEZONE_UNKNOWN` (opt-in gate) or a
`TCPA_FEDERAL_DIALING_WINDOW_BLOCKED` with `reason: "timezone_unresolved"`
(campaign path) both mean the same thing: the recipient is a US (+1)
number whose area code mapped to no IANA timezone. There is no window
math behind this error — the resolver failed **before** any hour was
computed, and an unresolved timezone is never treated as "in window."

Where the two paths diverge is the failure posture:

* **Campaign and dialer voice fails closed — always.** A US recipient
  whose timezone can't be resolved is refused before the dial, no matter
  what your tenant settings say. The federal penalty exposure isn't
  yours to waive, so this posture isn't either.
* **Ad-hoc 1:1 voice is advisory by default.** With the voice gate off,
  the same call dispatches and the unresolved decision is only logged.
  When you **do** enable the voice gate, its posture for an unresolved
  timezone follows your `unknown_timezone_policy`:
  * `skip` (the platform default) — fail **open**: the call passes.
  * `deny` (the default the voice gate ships with for US recipients) —
    fail **closed**: `422 TCPA_TIMEZONE_UNKNOWN`.
  * `enforce_utc` — evaluate the window against UTC instead, a
    deterministic answer for every recipient.

The policies and where to set them are covered in
[Quiet hours configuration](/guides/quiet-hours-configuration). The
durable fix is data, not policy: map the failing number back to its area
code, and where the recipient's real timezone is better known than the
area code implies (a relocated number), pass a `timezone_override` on
the preview call so your scheduler plans around the true local time.

## What to check before a campaign: recipient → state resolution

Pre-flight a bulk list against the resolution chain instead of learning
it from blocked attempts. A US number resolves through this chain:

1. The E.164 number yields its NANP **area code**.
2. The area code maps to a **USPS state** — when the state is one of the
   seven overlay states, the intersected window applies.
3. The area code maps to a **timezone** (or fails to → the fail-closed
   case above).

Falls-through you should know about before the campaign launches:

* **Non-NANP recipients** (anything not +1) never hit the federal guard
  at all — TCPA jurisdiction is US-only. They play by your own channel
  gate, if you enabled one.
* **Canadian and Caribbean NANP area codes, and US area codes not yet
  mapped, fall through to the federal window only.** The 8 AM–9 PM
  recipient-local window still applies, but no state overlay can. A
  fall-through is **not** a failed lookup — it doesn't trip the
  fail-closed timezone posture.
* **States without an overlay** (TX, CA, NY, IL, most of the map) resolve
  and attach to the decision for your audit filtering, but the window
  stays the plain federal one.

Run the read-only preview against a sample of the list before you
launch:

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/compliance/quiet-hours/preview?phone=%2B13055550123&channel=voice" \
  -H "Authorization: Bearer $ORBIT_API_KEY"
```

```json theme={null}
{
  "allowed_now": false,
  "local_hour": 22,
  "local_timezone": "America/New_York",
  "window_start_local": "08:00",
  "window_end_local": "21:00",
  "next_allowed_at": "2026-08-27T12:00:00.000Z",
  "reason": "outside_window",
  "channel": "voice"
}
```

`allowed_now: false` with a `next_allowed_at` you can schedule against
is the whole pre-flight answer. Sample the list by area code — one
preview per distinct area code covers every recipient that shares its
resolution.

## Reading the citation in the error

When a **state** overlay drove the block, the error details name the
statute so you can trace the decision without reading platform code:

```json theme={null}
{
  "code": "TCPA_FEDERAL_DIALING_WINDOW_BLOCKED",
  "details": {
    "reason": "state_blocked_day",
    "timezone": "America/New_York",
    "local_hour": 20,
    "next_allowed_at": "2026-08-31T12:00:00.000Z",
    "citation": "Fla. Stat. § 501.059"
  }
}
```

A `citation` only appears on state-driven decisions — federal-only
blocks carry none. Use it as the audit trail: hand the citation and the
`reason` to counsel or a compliance reviewer and they can verify the
block against the statute text directly. The verification status and
the most-restrictive-wins composition rule behind the overlay table are
documented on [US state calling windows](/compliance/state-calling-windows).
The federal window itself cites 47 U.S.C. § 227(b)(1)(B) where it
appears in error messages.

## The tenant opt-in gate fails open until you enable it

Ad-hoc 1:1 dials from the dashboard or softphone are **advisory-only by
default**: outside any window, the call dispatches and the decision is
logged — no error at all. The gate that produces
`TCPA_DIALING_WINDOW_BLOCKED` on this path is `quiet_hours.voice.enabled`
in your organization settings, and it only ever exists because you set
it. Expectations to hold onto while you debug:

* **Gate off → fail open.** Calls dispatch in every window; the decision
  still lands in the log for visibility.
* **Gate on → fail open only where your policy says so.** An unresolved
  timezone passes under `unknown_timezone_policy: "skip"` and blocks
  under `"deny"` — the gate is exactly as strict as you configured.
* **Either way, the gate can only add restrictions.** Nothing on the
  tenant side relaxes the campaign/dialer hard block below it.

To stop holding ad-hoc calls, either disable the voice gate or widen
your own window — both are yours to change. To keep the gate but answer
unresolved timezones differently, switch the policy to `skip` (pass) or
`enforce_utc` (evaluate against UTC). All three knobs are walked in
[Quiet hours configuration](/guides/quiet-hours-configuration).

## The campaign/dialer hard block has no override

Campaign, dialer, and automated voice origination — predictive,
progressive, preview, and agentless modes, scheduled callbacks, and the
pre-dial gate — are **always hard-blocked outside the federal 8 AM–9 PM
recipient-local window, and always fail closed on an unresolved
timezone**. There is no tenant toggle, consent flag, support override,
or emergency carve-out for this path; the only lever is timing. If a
dial cannot go out right now, every fix is one of:

1. **Schedule to `next_allowed_at`.** Every 422 in this class carries
   it. Pass it straight to your scheduler — the dialer itself defers
   held contacts and re-attempts once the window opens, so a blocked
   attempt never burns the contact.
2. **Pre-flight with the preview endpoint** (above) so the campaign
   launches inside the window for every sampled area code.
3. **For `state_blocked_day`, reschedule the day, not the hour** —
   Florida's Sunday ban has no compliant hour on Sunday.

Don't try to work around the hard block by routing the campaign through
the ad-hoc path or by widening your own gate — the tenant gate only adds
restrictions on top, and the federal evaluation runs on the campaign
path regardless of what your gate says. The full carve-out is documented
on [Send gates](/compliance/send-gates).

## What to capture before escalating

Work the sections above first. If a block still misreads — the recipient
genuinely is in-window, the area code resolves wrong, or the
`next_allowed_at` looks off — open a ticket with:

1. **The full error body** — code, message, and the `details` object
   (`reason`, `timezone`, `local_hour`, `next_allowed_at`, `citation`).
2. **The recipient E.164 number** and its area code.
3. **The call path** — ad-hoc dashboard/softphone dial, or campaign /
   dialer origination, plus the campaign or dialer run ID for bulk work.
4. **Your organization ID** (Settings → Organization, or
   `organizationId` from `GET /api/v1/me`).
5. If the timezone resolution itself is in question, the
   **preview response** for the same number from
   `GET /api/v1/compliance/quiet-hours/preview`.

## What not to do

* **Do not retry the dial in a loop.** A window block re-fires on every
  attempt until the recipient-local hour changes. Read `next_allowed_at`
  and schedule there — retries before it only multiply 422s.
* **Do not reconfigure the trunk or restage the number.** The block
  fires before SIP; nothing on the carrier path is involved.
* **Do not flip the voice gate off to "fix" campaign blocks.** The
  tenant gate and the campaign hard block are different layers; disabling
  your gate changes nothing for automated voice and only loosens your
  own posture.
* **Do not treat a state fall-through as a resolver failure.** Canadian,
  Caribbean, and unmapped US area codes legitimately resolve to the
  federal window only — that's by design, not a gap to report.

## See also

* [US state calling windows](/compliance/state-calling-windows) — the
  overlay table, the resolution chain, and the statutes the `citation`
  field points back to.
* [Quiet hours configuration](/guides/quiet-hours-configuration) — the
  tenant opt-in gate, `unknown_timezone_policy`, and the campaign
  fallback window.
* [Send gates](/compliance/send-gates) — the preview endpoint and the
  campaign/dialer federal asymmetry.
* [Error codes](/reference/error-codes) — the full TCPA entry set this
  page works from.
* [Troubleshooting: voice call quality](/troubleshooting/voice-call-quality)
  — the next page once the call *does* dispatch and the audio is the
  complaint.
