Skip to main content

IVR Flows

New to IVR flows, or not a developer? Start with IVR Flows: a simple guide.
An IVR flow is a scripted phone call driven by the keypad. You draw it once in the dashboard: what to say, which keys the caller can press and where each key leads, and which of your APIs to call along the way. Then you push leads to it over the API, one call per lead. When a call ends, the session.completed webhook tells you which path the caller took, every key they pressed and the outcome the call reached. For every field of the flow JSON, see IVR Flow JSON Reference.
IVR Flows is enabled per account. Until it is, every endpoint below returns 403 IVR_FLOWS_DISABLED. Contact Vocobase to turn it on; your IVR prices are set at the same time, one per voice model (Standard and Premium).

Build the flow

Flows are built and published in the dashboard under IVR Flows. A flow is a graph of blocks joined by exits: Each flow speaks with one of two voice models, Standard or Premium, chosen in the dashboard when you build it. The model sets the per-pulse price of the flow’s calls, and the API returns it as voice_model: the model of the flow’s published version, which is what calls speak with and are billed at. A draft you are still editing may use a different model; it takes effect when you publish it. Flows on the previous Premium voices were moved to Standard when Premium moved to its new voices, so voice_model reads standard for them. They keep the same voice and are billed at your Standard price, which is your previous Premium price unless your account already had a Standard price. A few rules worth knowing before you design:
  • Lead field types decide how each value is spoken. A money value is read as an amount, a date as a day and month, digits one digit at a time.
  • Fetch URLs must be https:// with a fixed host. Placeholders are allowed only in the path and query string, never in the scheme, host or port.
  • Pre-dial Fetch. Fetch blocks that follow Start directly run before the number is dialed. If one fails, the number is never dialed and the call ends as failed (see Read the result), so a caller never hears a half-filled script.
  • Publishing freezes the current draft as a new numbered version. Pushed calls always run the latest published version; editing the draft does not affect them until you publish again.
  • Use Test call in the editor to ring your own phone on the unpublished draft. Test calls are billed like any IVR call and are marked is_test: true in the webhook.

Push a lead

1. Find the flow and its fields

Only flows with a published version are listed. Read one flow to see the lead fields its published version expects:

2. Send the lead

A 202 means the call was accepted and queued, not that it was answered. Track it with call.status.updated or GET /calls/{call_id}.

Request fields

IVR calls are placed on your VoiceLink connection.

How to send each field type

A required field that is absent, null or "" is missing. Keys the flow does not declare are refused, so a typo never silently drops a value. Every problem is listed at once:
problem is one of missing, wrong_type or unknown. The lead values you sent are echoed back as variables on session.completed.

Retries and idempotency

Send a client_reference_id with every lead and reuse it when you retry. If the key was used before, the API returns 200 with the original call and idempotent_replay: true, and places no new call:
The key space is shared with POST /calls/start on the same account. If the key belongs to a call that was not placed on this flow, flow_id is null. To call the same lead again on purpose, use a new key.

Limits and billing

  • Pushes share the per-minute call quota of POST /calls/start (429 RATE_LIMITED, with a Retry-After header) and the account’s concurrent call limit (429 LIMIT_REACHED). Back off and retry both.
  • IVR calls are billed per pulse of answered time at your account’s price for the voice model of the flow’s published version (Standard or Premium). Unanswered calls and pre-dial failures cost nothing. To start, a call needs enough balance for one minute at that price; otherwise it returns 403 FORBIDDEN.

Read the result

Every IVR call ends with the normal session.completed webhook, with one extra ivr block:
Pre-dial failures. When a pre-dial Fetch fails, the call ends without dialing: call.status is failed, call.end_call_reason is NOT_CONNECTED, duration_seconds and credits_used are 0, and ivr.failure is prefetch_failed. ivr.fetches shows which Fetch failed and why. agent_id and agent_name on an IVR call’s webhook identify an internal agent that backs the flow. Key your integration on ivr.flow_id instead. Full field reference: Webhook payloads → IVR Flows calls.

Error codes