Skip to main content

Quiet hours: org-wide channel gates vs. the campaign fallback window

Orbit’s quiet-hours gate is tenant-owned: everything on this page is a control you configure (or choose to leave off). The only exception is the TCPA federal voice window for US recipients, covered in its own section below. Opting into quiet hours is your call — nothing here is required by CAN-SPAM or GDPR. This page is the operator runbook for that gate. Three surfaces compose your posture:
  1. The org-wide channel gate — per-channel toggles in organization settings (settings → quiet_hours.<channel>.enabled), written through PUT /api/v1/settings/general and mirrored in the dashboard org settings (see also Compliance posture).
  2. The campaign fallback window — a single org-wide start/end pair for drip and journey sends whose campaign row carries no explicit window. In the dashboard: Settings → Campaign limits → Default quiet hours; over the API: GET/PUT /api/v1/campaigns/quiet-hours/settings.
  3. The preview endpointGET /api/v1/compliance/quiet-hours/preview, a read-only check that answers “would this send to this recipient go through right now?” Run it before every rollout; it’s worked through in the runbook below.

The two windows

The campaign fallback is exactly what its name says — a fallback, not a second gate. Resolution order for a campaign send: the campaign row’s own window, then the org fallback, then the platform default 21:00 → 09:00 (quiet hours run 9 PM to 9 AM recipient-local). The two knobs can disagree. A campaign-dispatched send evaluates the campaign path’s window as one layer; the org channel gate — when you’ve enabled that channel — is a separate layer evaluated at the send site. Treat the org gate as the posture for 1:1 traffic and the campaign fallback as the default regime for bulk traffic. A blocked send reports next_allowed_at — schedule around the window rather than retrying. The fallbacks you can set at either layer can only ever narrow the envelope; they never widen a channel gate you’ve enabled.

Org-wide per-channel gate

The channel gate is opt-in per channel. Each per-channel entry supports: Org-level keys (apply to all channels together):

Default posture per channel

Until you enable a channel, nothing is held. When you flip a channel on without specifying hours, the platform hours kick in: The full channel set accepted by the gate: sms, mms, whatsapp, rcs, viber, telegram, voice, email, instagram, messenger, line, apple_messages, fax, push, web_chat.

Two carve-outs that keep essential traffic flowing

  • Prior express consent — with consent_overrides_quiet_hours true (the default), a recipient with an explicit-consent record passes through on any non-voice channel. Voice never takes this carve-out.
  • Transactional traffic lane — sends the caller tags as transactional (OTPs, alerts, account notifications) are exempt from the gate even on an enabled channel. Voice never takes this carve-out either.
Set consent_overrides_quiet_hours to false only if you want stopped sends with no consent exceptions.

Campaign fallback window

Any authenticated caller reads it; only owner/admin writes it. Read the current fallback window:
platform_default_start / platform_default_end echo the hours drip and journey sends use while the override is off — inherit them or replace them, your choice. In the dashboard this form is Settings → Campaign limits → Default quiet hours. Set your own window (both hours are required when enabled is true):
Clear back to the platform default:
Overnight windows (e.g. start 22, end 7) are accepted at both layers — a start > end pair wraps around midnight.

Recipient timezone resolution

The gate works in recipient-local time. Timezone resolution follows this chain:
  1. An explicit recipientTimezone hint from the caller, when supplied.
  2. US area code → IANA timezone, for +1 numbers.
  3. E.164 country code → a representative IANA timezone (Europe, Asia, the Americas, and common operator markets).
  4. For email recipients, the organization’s default timezone.
  5. When none of the above resolves — the org’s unknown_timezone_policy (also configurable in the dashboard at Settings → Voice):
If the recipient does resolve to a timezone, an ordinary enabled-channel block returns 422 QUIET_HOURS_BLOCKED (voice: TCPA_DIALING_WINDOW_BLOCKED) with the window and next_allowed_at in the error details.

TCPA federal voice carve-out

Campaign and dialer voice to US recipients is hard-blocked outside the 8 AM–9 PM recipient-local federal window — no org gate, fallback window, or consent flag relaxes it, and a US recipient whose timezone can’t be resolved is blocked fail-closed. This is the one knob the platform owns; it applies to campaign and dialer voice only, not to 1:1 ad-hoc calls or any messaging channel. Non-US recipients play by the ordinary gate: the fail-open skip policy applies to recipients outside US jurisdiction, and your own voice channel gate (if enabled) layers on top. You can always tighten past the federal window — e.g. a voice gate of 09:00–20:00 recipient-local — but you can never widen it. Ad-hoc 1:1 voice from the dashboard outside the federal window dials through with an advisory log unless you’ve enabled the voice channel on the org gate, which makes it a hard hold (422 TCPA_DIALING_WINDOW_BLOCKED). With consent_overrides_quiet_hours: true (the default), a recipient you hold explicit-consent for passes the gate on non-voice channels — the TCPA “prior express consent” carve-out. A permitted recipient stays reachable inside your closed hours; a contact without a consent record is held until the window opens. Set it to false when consent must never relax your window. The gate ignores the flag entirely on the voice channel — voice hinges on the federal window and state overlays, not the consent carve-out.

State mini-TCPA overlays

Some US states layer a stricter calling window or day-of-week ban on top of the federal hours (Florida’s Sunday ban, Oklahoma/Mississippi windows, and others). Overlays compose as most-restrictive-wins: a send must clear the federal window and every applicable state overlay; the overlay can tighten but never widen. Voice blocks trace back with these failure reasons:
  • outside_state_window — a state overlay tightened the window and this hour fell outside it.
  • state_blocked_day — the overlay bans dialing on this weekday entirely.
The full state-by-state table and which recipient states resolve into each overlay live in US state calling windows.

Operational runbook

Rollout checklist. Before you flip a channel on or push a broad list:
  1. Preview a sample of recipients with GET /api/v1/compliance/quiet-hours/preview?phone=<E.164>&channel=<channel>, adding timezone_override=<IANA> only when your CRM carries a better hint than the number resolves to.
  2. Confirm the org gate block: GET /api/v1/settings/general and read the quiet_hours tree before PUT — writes merge at the top level, but the quiet_hours key itself is replaced wholesale (see the write section below).
  3. For bulk rollouts, watch GET /api/v1/settings/compliance-health — its warnings rank the worst offender (most-held sender, error clusters) so you fix the noisiest lane first.
Holds are per-recipient, not per-tenant. One contact held at 21:05 recipient-local blocks only that contact’s sends; the rest of your batch keeps admitting in parallel. A held 1:1 send throws 422 QUIET_HOURS_BLOCKED with next_allowed_at in the error details — schedule at that timestamp instead of retrying in a loop. A held send never consumes a quota or slot reservation, so retries re-admit cleanly once the window opens. Writes take up to about a minute to reach every send site — org settings are cached briefly in the send path. Reads are immediate; verify the merged posture back with a GET before rolling out.

Worked examples

Bulk rollout at 21:05 — hold-queue behaviour

You push a 1,000-recipient list through the API at a moment when a slice of your list sits outside your 08:00–21:00 org gate recipient-local. Each recipient resolves independently against your enabled sms gate:
  • In-window recipients admit immediately.
  • Held recipients get a 422 with next_allowed_at; your worker parks them and continues the batch. The batch itself isn’t paused — holds are per-recipient.
  • When each recipient’s window reopens, re-submit the parked row; no slot was burned while held.
Double-check a specific recipient without burning the attempt:
next_allowed_at is a DST-safe ISO timestamp — pass it straight to your scheduler.

Timezone-unresolved US voice recipient — fail-closed

A campaign voice dial to +15551234567 where the area code resolves no timezone runs into the federal guard’s fail-closed posture: the dial is refused with 422 TCPA_TIMEZONE_UNKNOWN before any window math. Fix the data — set the contact’s timezone on the record or pass recipientTimezone — then requeue. The same unresolved input on the sms channel with unknown_timezone_policy: "deny" ends in 422 QUIET_HOURS_TIMEZONE_UNKNOWN; with the default skip policy it passes fail-open. The deny policy is only the default for US-recipient voice, per the federal carve-out above. Two contacts, sms gate enabled, 22:30 recipient-local (outside your window):
With consent_overrides_quiet_hours: false, both hold until 08:00 recipient-local. On voice, the flag doesn’t apply at all — every voice attempt is gated on window math alone.

Enable a channel via the organization settings API

There is no dedicated quiet-hours write endpoint for the channel gate; it lives inside the organization settings store, and every send reads it. Update it through PUT /api/v1/settings/general (owner/admin):
Read the current posture back with GET /api/v1/settings/general and look at the quiet_hours block in the returned settings.
Merge-then-verify. PUT /settings/general merges settings at the top level, so a write that contains only quiet_hours keeps your other settings intact — but a write at whose root you place a full quiet_hours object REPLACES that key. If you mean to keep existing entries (for example a default window or the campaign fallback’s stored leaf keys), read the current block first and merge before writing.
Writes take up to about a minute to reach every send site — org settings are cached briefly in the send path.

Choose a posture

  1. Leave everything off (default) if you operate outside quiet-hours jurisdictions, or you handle limits elsewhere. One caveat: US campaign and dialer voice stays hard-blocked — that one can’t be turned off.
  2. US marketing operator — enable sms (and voice if you dial ad-hoc) on the org gate; platform hours 08:00–21:00 recipient-local apply immediately. The consent carve-out keeps permitted recipients reachable.
  3. EU/APAC operator with drip campaigns — set the campaign fallback to your local window (e.g. 22:00 → 07:00) in Settings → Campaign limits so every drip and journey that lacks its own window sends inside your regime. Add the org gate per channel if you also want 1:1 traffic held.

See also