Number timezone and state resolution
Every quiet-hours and calling-window verdict starts with the same question: where is the recipient? TCPA windows are recipient-local, so before Orbit can decide whether a call or message is inside the allowed window it has to derive a timezone — and, for US numbers, a state — from the phone number itself. This page is the resolver atlas: what the lookup tables contain, how they chain together, where the edge cases (overlays, split NPAs, Canadian codes) resolve, how the coverage-drift test keeps the inventory honest, and what verdict you get when a recipient’s timezone cannot be resolved. This is an internal-lookup explainer, not endpoint documentation — it describes how the resolution layer underneath quiet hours, state calling windows, and the recording-consent gate derives its inputs. Nothing here is a control you configure; the tenant-owned controls sit on those pages. The resolution layer just answers “what timezone and state does this number imply” identically for all of them, so a blocked or released verdict is traceable to one lookup chain rather than per-feature guesswork.1. Resolver precedence graph
Quiet-hours evaluation resolves the recipient’s timezone through a fixed precedence — the first path that produces an answer wins, and every later path is skipped:- Explicit timezone hint — a per-recipient or per-request hint always wins over every lookup. Pass it whenever you know the recipient’s actual local time; number portability means a 305 (Miami) subscriber can live in Oregon, and the hint is the only source that overrides portability.
- NANP area-code inventory — for +1 numbers, the three digits after
the
+1index the inventory described in section 2, and the resolved zone drives the state projection in section 3. - Country-code fallback — for non-+1 numbers, a country-prefix table
supplies a best-available zone (e.g. +44 →
Europe/London). - Unresolved — the verdict splits by surface; see the fail posture in section 4.
2. NANP area-code inventory and the drift test
The lookup chain’s NANP branch indexes a single source of truth: one hand-maintained map of IANA timezone → assigned area codes, sourced from the NANPA Active Codes report (the North American Numbering Plan Administrator’s monthly assignment list). Its coverage:- US — all 50 states + DC, including the IANA sub-zones that matter
for quiet-hours math (Indiana and Michigan each resolve to their own
zone, Arizona resolves to the no-DST
America/Phoenix). - US territories — Puerto Rico, US Virgin Islands, Guam, American Samoa, Northern Mariana Islands.
- Canada — all 10 provinces + 3 territories.
- The inventory test pins the map as the canonical NANP coverage set. It asserts total coverage stays above 300 assigned NPAs (the live count after the US + territories + Canada sweep), spot-checks a known-good sample per region (212 in New York, 415 in Los Angeles, 416 in Toronto, 787 in Puerto Rico, 671 in Guam), and asserts no NPA appears under two timezones at once — a duplicated key is exactly the drift the test catches.
- The state-resolver test pins the USPS map’s own invariant: each NPA in the map maps to exactly one state, every two-party-consent state’s principal NPA is present, and the map stays above 150 entries — the union floor that the recording-consent and calling-window gates together need.
- Adding a new NPA means appending it to its zone’s inventory in one
place; every projection re-derives automatically, and both tests go
green again. How to run the drift check: execute the compliance
test suite (
vitest rununder the compliance package) — the inventory and state-resolver suites are part of it and refuse to let a diverged map merge.
3. US state resolution and the split-NPA cases
For US +1 numbers there is a second projection: area code → USPS state code, roughly 170 single-state assignments built from the same NANPA data. It exists because two gates need a state, not a timezone: the seven mini-TCPA overlays (FL, OK, MS, LA, AL, AR, WV) and the two-party-consent recording gate. The map single-source-of-truth is described in section 2 — this section is about the edge cases that surprise operators. The state map previously lived as two divergent tables — one biased toward overlay states, one toward recording-consent states — so the same recipient could resolve to a state in one gate and to nothing in the other. The current map is the union of both, which is why its coverage is wider than either gate strictly needs: a TX or NY recipient resolves to a state even though neither state changes the federal window. The resolved state is still attached to the decision for telemetry and audit filtering, and the map gains coverage over time without any gate needing to change. The state-resolver test pins exactly that invariant (the “covers BOTH former maps’ states on the same lookup” case), so a regression that quietly drops one side of the union fails in CI. Splits and overlays. NANP assignments routinely split an NPA across two states (a boundary split) or create a new overlay code over an existing region. Three canonical patterns show how the resolver treats them:- A timezone-only assignment with no US state — Canadian NPAs resolve
to a timezone but project a
nullstate by design.+1 306 ...(Saskatchewan) resolves toAmerica/Reginaon the timezone branch and tonullon the state branch, because the USPS projection only maps US states. The overlay and consent gates treatnullas “no overlay — federal-only path,” so a Canadian recipient never gets a false US state. - A multi-state region resolved to its dominant share — assignments
stay single-state, and where an NPA straddles a boundary the resolver
returns the state with the dominant share of the footprint.
+1 385 ...and+1 801 ...both cover Utah and resolve toAmerica/Denver; the state projection resolves toUTonly if/when the contributor has added it — until that contributor lands, anullstate is the honest answer, not a fabricated one. - A state not yet assigned in the map — some NPAs that are valid on
the NANP timezone branch still yield no USPS state. The Kansas/Missouri
corridor (
913,816,417,660,620,785,316) resolves toAmerica/Chicagoon the timezone branch, but none of those NPAs has a KS/MO assignment in the state map yet — both states have no overlay and no two-party-consent gate, so the union never needed them. The resolver deliberately returnsnullrather than guess, and the audit record shows “no state assigned” rather than a fabricated KS/MO answer. That discipline — union of the two former maps, never a guess — is what the median-split pattern teaches.
null state is never fatal,
and an explicit timezone hint would only ever override the timezone branch
— the state branch stays honestly null until the contributor updates the
map.
4. Fail posture and worked verdict examples
The unresolvable case splits by surface, and each surface documents its posture explicitly:- Quiet-hours evaluation and the standalone TCPA window check fail
open. An unmapped +1 area code resolves to
unknown_timezoneand the send is allowed, with the reason recorded for audit. The alternative — blocking every legitimate call to a newly assigned area code — over-blocks real traffic. - The campaign/dialer voice path under the federal guard fails closed.
Because the penalty exposure of an unlawful call outweighs a missed send,
an unresolvable recipient timezone on that path returns
timezone_unresolvedand the call is held. The state calling windows page details that asymmetry; the fix is to pass an explicit timezone hint. - State resolution failing is never fatal. A
nullstate means “no overlay applies — federal window unchanged,” for both the NANP and the non-NANP shapes above. It does not block, and it does not trip the timezone fail-closed posture on the voice path.
The table rows are exactly the four edge-cases above (clean hit,
timezone-on-the-NANP-branch, timezone-not-on-the-state-branch,
unresolvable-on-either-branch, country fallback, hint) — an operator
debugging a blocked or released verdict can pattern-match against these
six shapes before touching the preview endpoint.
Overlays. When a city gains an overlay area code, the new NPA resolves
to the same timezone and state as the code it overlays as soon as it is
added to the inventory. Until then it is an unmapped area code with the
fail posture above.
Timezone ≠ residency. An area code reflects where a number was
assigned, not where the subscriber lives now. Number portability means a
Miami 305 number can belong to someone in Oregon. When you know a
recipient’s actual local timezone, pass it as the explicit
timezone hint — the hint always outranks the area-code lookup.
5. Where the resolution feeds
The same lookup chain is consumed by:- TCPA quiet-hours decisions — the boolean allowed/denied evaluation behind the send gates and the quiet-hours preview endpoint. The preview returns the resolved timezone and local hour alongside the verdict, which is what makes a blocked decision debuggable: you can see the exact timezone the gate resolved and compare it against your recipient’s actual location.
- Voice-guard timezone resolution — the campaign/dialer pre-dial gate resolves the recipient timezone before any window math; an explicit hint is honored first, then the area-code inventory.
- State calling windows — the state overlay intersection, as on US calling windows.
- Recording-consent gating — the per-state consent gate, as on recording consent.
Related
- Quiet hours preview — read a verdict without sending
- US calling windows — the federal + state overlay intersection
- Recording consent — the per-state consent gate
- TCPA quiet hours and windows — the tenant-owned setup workflow