Skip to content

IVR Flows

IVR (Interactive Voice Response) flows drive incoming WhatsApp voice calls. A flow is stored per WhatsApp account as a v2 flow graph in the menu field: { version: 2, nodes, edges, entry_node }. When a call connects, the calling engine walks the graph starting from entry_node, playing greetings, collecting DTMF digits, making HTTP callbacks, and routing callers to agent teams.

The menu object is a directed graph:

FieldTypeDescription
versionintegerMust be 2
nodesarrayFlow nodes (see below)
edgesarrayConnections between nodes, each { from, to, condition }
entry_nodestringID of the node where execution begins (required when nodes is non-empty)

Each node has the shape:

{
"id": "node-1",
"type": "greeting",
"label": "Welcome",
"position": { "x": 100, "y": 100 },
"config": { "greeting_text": "Welcome to Acme support" }
}

Node types:

TypePurpose
greetingPlay an audio prompt or text-to-speech greeting
menuPlay a prompt and collect a single DTMF digit to branch on
gatherCollect a sequence of DTMF digits (e.g. an account number)
http_callbackMake an HTTP request and branch on the response
transferRoute the call to an agent team
goto_flowJump to another IVR flow (terminal)
timingBranch on business hours
hangupEnd the call (terminal)

Edge conditions select which outgoing edge is followed: default, digit:N (e.g. digit:1), timeout, max_retries, http:2xx, http:non2xx, in_hours, out_of_hours. Terminal nodes (goto_flow, hangup) must not have outgoing edges.

Retrieve IVR flows for your organization, most recent first. Paginated.

Terminal window
GET /api/ivr-flows
ParameterTypeDescription
accountstringFilter by WhatsApp account name
pageintegerPage number
limitintegerResults per page
{
"status": "success",
"data": {
"ivr_flows": [
{
"id": "uuid",
"organization_id": "uuid",
"whatsapp_account": "Main Business",
"name": "Support IVR",
"description": "Main support menu",
"is_active": true,
"is_call_start": true,
"is_outgoing_end": false,
"menu": {
"version": 2,
"entry_node": "node-1",
"nodes": [],
"edges": []
},
"welcome_audio_url": "",
"created_by_id": "uuid",
"updated_by_id": "uuid",
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
}
],
"total": 3,
"page": 1,
"limit": 20
}
}

Retrieve a single IVR flow with its full graph.

Terminal window
GET /api/ivr-flows/{id}

Returns a single IVR flow object (same shape as the list items above), with created_by and updated_by user objects preloaded.

Create a new IVR flow. The graph is validated and, if TTS is available, greeting audio is generated.

Terminal window
POST /api/ivr-flows
{
"whatsapp_account": "Main Business",
"name": "Support IVR",
"description": "Main support menu",
"is_active": true,
"is_call_start": true,
"is_outgoing_end": false,
"welcome_audio_url": "",
"menu": {
"version": 2,
"entry_node": "node-1",
"nodes": [
{
"id": "node-1",
"type": "greeting",
"label": "Welcome",
"config": { "greeting_text": "Welcome to Acme support" }
}
],
"edges": []
}
}
FieldTypeRequiredDescription
namestringYesFlow name
whatsapp_accountstringYesName of the WhatsApp account the flow belongs to
descriptionstringNoFlow description
is_activebooleanNoWhether the flow is enabled
is_call_startbooleanNoUse this flow as the entry point for incoming calls on the account. Setting it unsets any other call-start flow for the same account
is_outgoing_endbooleanNoRun this flow at the end of outgoing calls on the account. Setting it unsets any other on the same account
menuobjectNoThe v2 flow graph. Validated for structural correctness
welcome_audio_urlstringNoOptional welcome audio URL

Returns the created IVR flow object.

Update an existing IVR flow. Supports partial updates — empty fields are not applied, so you can toggle is_active without resending the whole menu.

Terminal window
PUT /api/ivr-flows/{id}

Accepts the same fields as Create IVR Flow. The boolean toggles (is_active, is_call_start, is_outgoing_end) are always applied; name, description, menu, welcome_audio_url, and whatsapp_account are applied only when non-empty.

Returns the updated IVR flow object.

Soft-delete an IVR flow.

Terminal window
DELETE /api/ivr-flows/{id}
{
"status": "success",
"data": {
"message": "IVR flow deleted"
}
}

Upload an audio file for use as an IVR greeting or prompt. The file is transcoded to OGG/Opus (48kHz mono) for WebRTC compatibility. Send as multipart/form-data with the file under the file field.

Terminal window
POST /api/ivr-flows/audio
{
"status": "success",
"data": {
"filename": "a1b2c3d4-....ogg",
"mime_type": "audio/mpeg",
"size": 204800
}
}

Use the returned filename as the audio_file value in a node's config.

Serve a previously uploaded IVR audio file. Returns the raw audio bytes with the appropriate Content-Type.

Terminal window
GET /api/ivr-flows/audio/{filename}

The audio file body (not a JSON envelope).

  • Calling - WhatsApp voice calling, the IVR flow builder, transfers, and recording