Skip to main content

Voice pre-send gate chain

An outbound voice call passes a chain of pre-send checks before any SIP leaves the platform. This page is the single map of that chain: the order the gates evaluate in, which ones you can turn off, and how to read a rejection back to the exact gate that fired. It is a routing page — it maps gates to their deep pages rather than re-explaining them. The chain runs on the outbound-dial path itself. A campaign launch, a dialer send, an ad-hoc dashboard dial, and a customer-trunk origination all take the same checks in the same order.

1. The canonical chain — order of evaluation

The gates fire in this order on every outbound voice call:
  1. Emergency short-code reject — platform-global, no toggle. If the destination resolves to an emergency short code (911 / 112 / 999 / 000), the call is refused first, before any other gate runs. → 422 EMERGENCY_CALLING_NOT_SUPPORTED. Deep page: Troubleshooting: voice destination blocks → Emergency short codes, code in the error codes reference.
  2. TCPA federal dialing window for campaign/dialer US (+1) voice, and the tenant opt-in quiet-hours gate for ad-hoc dials. The federal 8 AM–9 PM recipient-local window is the one compliance control the platform owns outright: no opt-out, fail-closed. → 422 TCPA_FEDERAL_DIALING_WINDOW_BLOCKED (federal), TCPA_DIALING_WINDOW_BLOCKED (your opt-in gate), TCPA_STATE_DIALING_WINDOW_BLOCKED (state overlay). Deep pages: TCPA federal voice guard, US state calling windows, send gates → quiet hours.
  3. FCC AI-voice written-consent gate — runs after the federal window and before any billing hold or media step. If the call is classified synthetic or cloned and no prior express written consent is on record, the call blocks. Human-voice calls short-circuit as no-ops. → 422 FCC_AI_VOICE_WRITTEN_CONSENT_REQUIRED. Deep page: FCC 24-17 — written consent for AI voices.
  4. Fraud-velocity guard, then the DNO caller-id reject. The fraud-velocity guard blocks premium-rate destination prefixes and enforces per-tenant rate and daily-spend caps. The DNO guard runs after the caller-id (from) is resolved and rejects a calling-party number that matches a Do-Not-Originate entry. → VOICE_BLOCKED_DESTINATION / VOICE_DAILY_SPEND_CAP / VOICE_RATE_LIMITED (fraud guard), 422 VOICE_DNO_BLOCKED (DNO). Deep page: Troubleshooting: voice destination blocks → DNO.
  5. Trunk caller-id reject — on a customer SIP trunk INVITE, the presented caller-id must be in the trunk’s allow-list or the org’s DID list. → VOICE_CALLER_ID_REJECTED (403 on the trunk path). Deep page: Troubleshooting: voice destination blocks → Trunk caller-id.
  6. Per-country rate window — a per-destination-country sliding-window cap. → 429 VOICE_COUNTRY_RATE_LIMITED. Deep page: Troubleshooting: voice destination blocks → Per-country rate window.
  7. STIR/SHAKEN attestation assignmentnot a gate. The A/B/C attestation level is resolved at the same moment as the pre-send checks and stamped onto the call record for reporting. It never blocks or reroutes a call. Deep page: STIR/SHAKEN attestation posture.
Order matters for triage: a call refused at step 1 never reached step 7. When you read a rejection, the gate nearest step 1 that fired is the one to fix first — later gates never got a chance to run.

2. Precedence table — gate, trigger, code, can you turn it off

3. Which gate fired — read the 422 body and the audit log

Every gate writes its own distinct error code onto the rejection, so disambiguation is mechanical, not interpretive. Read the response body. The error.code field in the JSON body names the gate that fired. Match the code against the precedence table above. A refusal at step 2 returns a TCPA code; a refusal at step 6 returns 429 VOICE_COUNTRY_RATE_LIMITED; the two never overlap. Codes with FEDERAL in the name belong to the platform’s hard guard; codes without it belong to your own tenant-side configuration. For the FCC gate specifically, the 422 payload also carries a reason (no_written_consent_on_record, tenant_consent_schema_missing, or consent_lookup_error) and a hint describing the consent-row shape to add. Cross-check in the audit log. Each gate also writes an audit entry at the moment it blocks, so you can correlate a user’s report against the recorded event. Filter your audit log (Settings → Audit log) by:
  • The recipient number (redacted) and the call path (campaign, ad-hoc dial, trunk origination) to isolate the attempt.
  • The machine event code — e.g. voice.fcc_ai_consent_blocked for the AI-consent gate — so you can separate one gate’s blocks from another even when two gates fired on the same recipient in one session.
  • The error code — every block event carries the same code the API returned, so the audit entry and the 422 body agree on which gate fired.
The audit log is append-only, so the record survives whatever happens to the request upstream — a blocked call still leaves its gate’s audit row even when the caller retries or abandons. When the result looks wrong, capture the full error body (code + details), the destination and presented caller-id in E.164, the call path, and your organization id before escalating — Troubleshooting: voice destination blocks ends with that capture checklist. The FCC AI-voice written-consent gate sits after the federal TCPA dialing-window guard and before the billing hold — internal order, fixed by the platform:
  1. After the federal window. The federal 8 AM–9 PM recipient-local hard guard always runs first; the FCC gate layers on top of it and never relaxes its outputs.
  2. Before any billing hold, media room, or dispatch. A blocked AI / cloned-voice call never burns a billing hold, never opens a media path, and never touches the disposition lock.
Within the same step, the classifier resolves human, synthetic, or cloned from the call’s request metadata (voice_content_typevoice_cloned_model_idvoice_agent_id / agent_idtts_text / tts_body); a human verdict short-circuits the consent lookup entirely. The precedence table and worked examples live on the gate’s own page: FCC 24-17 — written consent for AI voices.

5. Fail-open vs fail-closed — per gate

The failure posture of each gate (what happens when the gate itself cannot resolve its input) is deliberate and asymmetric: The asymmetry rule is consistent: controls the platform owns at a statutory floor (federal window, FCC consent, BAA) fail closed, because a false pass is the expensive error. Controls you own (your quiet-hours gate, your DNO override) fail open, because a false refusal is the expensive error. The same split is the reason the federal window carries no skip toggle while your own quiet-hours gate ships with one.

See also