> ## 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.

# The voice-broadcast model — one-to-many voice calls over the campaigns backbone

> Where broadcast sits next to dialer and multi-step campaigns — the wizard creates a standard voice-channel campaign, the three audio sources it can carry, the TCPA / quiet-hours / approvals gating chain, and how settled cost and ROAS attribution land afterward.

# The voice-broadcast model

A voice broadcast is the one-shot "call these contacts, play a message" use case. This page names where that use case sits in the outbound model — beside the dialer that connects answered calls to live agents and the multi-step campaign engine — and ties together the runway a broadcast travels: the campaigns backbone it rides, the three audio sources it can carry, the gating chain it must clear, and how settled cost and ROAS attribution land afterward. Read this once and every page of broadcast documentation points at the same model.

## The taxonomy — broadcast vs dialer vs multi-step campaign

Orbit's outbound voice surface has three distinct modes. Picking between them is a one-time architectural read, not a per-campaign decision:

| Mode                        | What it owns                                                                                                                 | Canonical surface                                                                        |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| **Broadcast**               | One blast campaign on the `voice` channel: call the audience, play the message, hang up. No agent, no steps.                 | The **Outbound → Voice Broadcasts** wizard, or `POST /campaigns` with `channel: "voice"` |
| **Predictive/power dialer** | Outbound dialing that hands answered calls to live agents — claim modes, pacing, dispositions, and the abandon-rate ceiling. | **Outbound → Dialer**, backed by the `dialer` endpoints                                  |
| **Multi-step campaign**     | Ordered steps or an event-driven graph, each step on its own channel with condition gates and exit goals.                    | The full campaign wizard (`blast`/`drip`/`journey` modes)                                |

Broadcast owns exactly one thing — the voice-channel blast. The dialer owns agent-handoff dialing (preview, progressive, predictive, and `agentless` mode, where the scheduler dials and routes to a recorded broadcast or an AI voice agent). The multi-step campaign owns sequencing across channels. A broadcast is never a dialer campaign: it creates no dispositions, consumes no agent presence, and its `agentless` analog is just the recorded-broadcast route inside the dialer model.

## The campaigns backbone

Everything the **Outbound → Voice Broadcasts** wizard saves is an ordinary campaign record — one `POST /campaigns` call with `channel: "voice"` and `type: "blast"`. There is no separate broadcast object:

* **Same endpoints.** Create, read back, launch, pause, resume, and cancel through the campaigns API; audience preview runs `POST /campaigns/audience/preview` with `channel: "voice"` so suppression and do-not-call exclusions show before you spend anything on audio.
* **Same status lifecycle.** The broadcast moves through `draft → scheduled → sending → running → completed` exactly as [campaign lifecycle](/concepts/campaign-lifecycle) defines; `paused`, `aborting`, and the terminal statuses mean the same things.
* **Same voice metadata.** The wizard packs the TTS voice id, language, business-hours flag, and caller-id override into the campaign's `variables` bag, which the dispatch provider reads when it picks up the call stream.

Because there is only one object, none of the broadcast UI's behavior is special-cased — a paused broadcast, a reverted approval, or a `voice-cost-rollup` read all exercise the campaigns spine.

## The authoring lane — three payload sources

The broadcast composer offers three audio sources, and the choice rides the campaign record in two forms:

* **Pre-recorded audio upload.** The clip (MP3, WAV, or M4A up to 25 MB) uploads to the voice asset store first (`POST /voice/assets`); the returned `audio:asset:<file_id>` handle becomes the campaign's `message_template`, so the dispatch resolves the asset at send time even if the signed preview URL has expired.
* **TTS text.** The script body lands directly in `message_template`; `metadata.voice_id` and `input.language` in `variables` pick the stock or cloned voice and its language. Contact tokens (`{{first_name}}`, `{{last_name}}`, custom fields) resolve per recipient at render time.
* **Voice clone.** A clone created under **Voice → Voice Clones** (with signed consent and a sample script) is just another entry in the TTS voice picker — the campaign stores the clone id in `voice_id` and lives the TTS-text path from then on.

The A/B lane is the same record plus `ab_test_enabled: true`; each variant carries its own script body, and the winner-selection rules (30 answered calls per variant, 24-hour evaluation window, 10% lead or confidence) score the variants afterward.

## The gating chain — TCPA, quiet hours, approvals

A voice broadcast must clear every gate the voice channel declares, evaluated in this fixed order:

1. **TCPA federal voice guard** — the hard 8 AM–9 PM recipient-local window. A scheduled broadcast that lands outside it fails the launch with `422 TCPA_FEDERAL_DIALING_WINDOW_BLOCKED`; the window is not configurable. See [TCPA federal voice guard](/concepts/tcpa-federal-voice-guard).
2. **Quiet hours** — the workspace-level per-recipient dialing window (`business_hours_only` on the wizard). The composer flag forwards through `variables.business_hours_only`, and the dispatch defers per recipient against the tenant-owned quiet window rather than reverting to a global clock. See [send gating and quiet hours](/concepts/send-gating-and-quiet-hours).
3. **Action approvals** — when the org's trust tier requires supervisor sign-off, the launch returns `pending_approval` and parks in **Outbound → Approvals** instead of dispatching. See [action approvals model](/concepts/action-approvals-model).

All three are tenant-owned controls: TCPA is federally fixed, quiet hours are workspace-defined, approvals are trust-tier-defined. Recording-consent acknowledgement (`recording_consent_acknowledged: true`) is a fourth, unconditional gate on every voice campaign create — the wizard affirms it on your behalf.

## Preflight cost preview and approvals flow

Before the first recipient dials, the wizard reads the same server-side aggregate the campaign page uses (`GET /campaigns/:id/voice-cost-rollup`) and renders the projected per-minute pricing for the draft. Check the returned sufficiency fields against the wallet before launch — a broadcast that clears the gates but overdraws the wallet returns `402` at the create call. The approvals queue then treats the identically-shaped record the same way it treats any campaign: approvers clear the queue and the launch proceeds.

## Settlement and attribution

Voice billing settles by the minute after the call stream drains; a broadcast's settled cost surfaces through the campaigns spine:

* **One-minute billing increments** — the rollup charges in one-minute ticks per answered call; short messages price small, long ones price linearly with duration. Per-call minimums apply where the carrier contract declares them; the rollup surfaces either shape in the settled fields.
* **ROAS attribution** — post-settlement, `GET /campaigns/:id/roas` joins the settled spend against conversion events to produce attributed revenue with last-touch and multi-touch funnels (plus holdout-incremental revenue when you ran a holdout cohort). A/B scoring reports against the same settled answer rates.

Settlement is terminal — after the campaign completes, cost and ROAS reads return the actual roll-up, not projections.

## One worked example

The wizard creates exactly this campaign record when you press **Create broadcast**:

```json theme={null}
{
  "id": "cmp_ab12cd34ef56",
  "name": "Acme Dental — Thursday cleaning reminders",
  "type": "blast",
  "channel": "voice",
  "status": "scheduled",
  "audience_type": "list",
  "audience_id": "list_cd8eb31fdc",
  "from": "+15550123",
  "message_template": "Hi {{first_name}}, this is a reminder from Acme Dental...",
  "recording_consent_acknowledged": true,
  "scheduled_at": "2026-10-05T13:00:00Z",
  "ab_test_enabled": true,
  "variables": {
    "business_hours_only": true,
    "voice_id": "elevenlabs-rachel",
    "language": "en-US",
    "from": "+15550123"
  }
}
```

Post-settlement, the same `id` answers `GET /campaigns/cmp_ab12cd34ef56` with `status: "completed"`, the rollup returns settled totals instead of projections, and the ROAS attribution endpoint carries revenue against the settled spend — none of which requires a second object. The broadcast is one campaign record end to end.

## See also

* [Campaign lifecycle](/concepts/campaign-lifecycle) — the shared status machine a broadcast rides
* [Dialer pacing model](/concepts/dialer-pacing-model) — agent-connected dialing modes, the broadcast's neighbor
* [Voice call lifecycle](/concepts/voice-call-lifecycle) — call states the individual broadcast dials move through
* [Run a voice broadcast end to end](/guides/voice-broadcasts) — the operator walkthrough of this model
* [Outbound dialer campaign guide](/guides/outbound-dialer-campaign) — the full guided-dialog dialer path
