IVR Flows
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, thesession.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
moneyvalue is read as an amount, adateas a day and month,digitsone 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: truein the webhook.
Push a lead
1. Find the flow and its fields
2. Send the lead
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 aclient_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:
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 aRetry-Afterheader) 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 normalsession.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.