Developers
Programmable Voice API
Use XML response verbs to program real-time call behavior for inbound and outbound voice workflows. This guide follows the official API model with clearer language and examples.
How It Works
Your application initiates or modifies a call through REST API endpoints and provides either a URL to an XML response document or an inline XML payload. NextGenSwitch executes each XML verb in order.
Example XML response:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>Hello, world!</Say>
</Response> PHP helper example:
<?php
require_once './vendor/autoload.php';
use NextGenSwitch\VoiceResponse;
$response = new VoiceResponse();
$response->say('Hello World!');
echo $response->xml(); Available XML Verbs
- <SAY> - Convert text to speech.
- <PLAY> - Play audio media.
- <GATHER> - Collect DTMF and/or speech input.
- <DIAL> - Connect to another party or channel.
- <RECORD> - Capture caller audio.
- <STREAM> - Start bidirectional WebSocket audio streaming.
- <HANGUP> - End the active call.
- <PAUSE> - Pause flow for a configured duration.
- <REDIRECT> - Load another XML instruction document.
- <BRIDGE> - Bridge to another in-progress call.
- <LEAVE> - Exit queue/waiting context but keep call alive.
Create or Modify Calls via API
Use a REST request from your application to trigger or modify call behavior.
Create Call (POST)
Required request parameters:
| Parameter | Description |
|---|---|
to | Destination number for the call. |
from | Caller number or client identifier. |
statusCallback (optional) | Webhook URL for live states such as dialing, ringing, established, and disconnected. |
response | URL to XML instruction document (omit if using responseXml). |
responseXml | Inline XML instruction body (omit if using response URL). |
curl --header "X-Authorization: Your_authorizaton_code" \
--header "X-Authorization-Secret: Your_authorizaton_secret" \
--request POST \
--data 'to=23123&from=2323&statusCallback=http://your_status_callback_url&response=http://your_xml_response_document_url' \
http://nextgenswitch_url/api/v1/call Modify Ongoing Call (PUT)
Send a PUT request with call_id and responseXml to change the active call flow.
Endpoint:
PUT http://nextgenswitch_url/api/v1/call/{call_id} Required parameters:
| Parameter | Description |
|---|---|
call_id | Unique ID of the active call to modify. |
responseXml | Inline XML containing updated flow instructions. |
curl --header "X-Authorization: Your_authorizaton_code" \
--header "X-Authorization-Secret: Your_authorizaton_secret" \
--request PUT \
--data '"responseXml": "<Response>\n <Pause length=\"2\"/>\n <Say loop=\"1\">call has been modified</Say>\n <Dial>1000</Dial>\n</Response>"' \
http://nextgenswitch_url/api/v1/call/{call_id} <Say> Verb
Converts text to speech for playback during the call.
| Attribute | Description |
|---|---|
loop | Number of repetitions. A value of 0 can be treated as continuous looping by implementation. |
<Response>
<Say loop="2">This message will be repeated twice.</Say>
</Response> <Play> Verb
Plays an audio file from URL or supported media source.
| Attribute | Description |
|---|---|
loop | Number of repetitions. Values less than or equal to 0 may be treated as extended looping. |
<Response>
<Play loop="3">https://example.com/audio/connecting.mp3</Play>
</Response> <Gather> Verb
Collects user input by DTMF, speech recognition, or both.
| Attribute | Description |
|---|---|
action | Webhook URL for collected input. |
method | HTTP method for action URL (`POST`/`GET`). |
timeout | Wait time for input in seconds. |
speechTimeout | Speech input wait time in seconds. |
numDigits | Expected DTMF length; `0` waits for timeout or finish key. |
finishOnKey | DTMF key that finalizes input. |
actionOnEmptyResult | Whether to call action URL with empty input. |
transcript | Enable speech transcription. |
beep | Play beep before capture starts. |
speechProfile | Custom speech-recognition profile. |
input | Input mode: `dtmf`, `speech`, or `dtmf speech`. |
<Gather action="https://example.com/process_input" method="POST" numDigits="4" timeout="10">
<Say>Please enter your 4-digit PIN.</Say>
</Gather> Action callback variables
When gathering finishes, NextGenSwitch sends the result to the action URL. A
POST callback uses application/x-www-form-urlencoded; a GET
callback sends the same fields as query parameters.
| Variable | Description |
|---|---|
call_id | ID of the call executing the gather. |
digits | DTMF digits collected before numDigits, finishOnKey, or timeout ended the gather. The finish key is not included. |
speech_result | Transcribed speech text when speech input and transcription are enabled. Omitted when no transcription is available. |
confidence | Speech recognition confidence returned by the configured transcription service. Omitted when unavailable. |
voice | Path of the captured gather audio file when voice input was recorded. Omitted for DTMF-only gathers. |
rec_path | Internal captured-audio path. Usually empty for DTMF-only gathers. |
event_from | Caller ID of the original call. |
event_to | Destination of the original call. |
event_call_id | ID of the original call. This normally matches call_id. |
Example DTMF callback:
call_id=CALL-123
digits=1234
rec_path=
event_from=1001
event_to=2001
event_call_id=CALL-123
The action endpoint should return a valid XML <Response>. NextGenSwitch parses that
response and continues the call with its verbs. Return an empty <Response /> when no
additional action is required.
In the current switch implementation, the action callback is sent only when at least one digit or a voice recording is available. A timeout with no input does not invoke the action URL.
<Dial> Verb
Connects the current call to a phone number, queue, or external SIP/VoIP destination.
| Attribute | Description |
|---|---|
to | Target phone number, SIP endpoint, or queue name. |
action | Webhook URL called after dial completes. |
method | HTTP method for action webhook. |
callerId | Caller ID for outbound leg. |
answerOnBridge | Bridge audio immediately after answer. |
ringTone | Enable/disable ringback tone to caller. |
timeLimit | Maximum connected call duration in seconds. |
hangupOnStar | Allow caller to hang up by pressing `*`. |
record | Recording mode (`record-from-answer` / `record-from-ringing`). |
recordingStatusCallback | Recording event webhook URL. |
statusCallback | Call status event webhook URL. |
channel | Advanced channel selector. |
channel_id | Advanced numeric channel identifier. |
<Response>
<Dial to="+1234567890" answerOnBridge="true" record="record-from-answer">
<Play>https://example.com/audio/connecting.mp3</Play>
</Dial>
</Response> Action callback variables
After the dialed leg finishes or the dial attempt fails, NextGenSwitch sends the result to the
action URL. A POST callback is form-encoded; a GET callback uses
query parameters.
| Variable | Description |
|---|---|
call_id | ID of the parent call that executed <Dial>. |
bridge_call_id | ID of the outbound/dialed call leg. It can be empty when the leg could not be created. |
dial_status | Numeric result: 1 means the dialed leg was established; 0 means the dial failed or was not established. |
duration | Connected talk time in seconds. It is 0 when the call was not established. |
waiting_duration | Seconds from starting the dial until the outbound leg was established. For an unanswered attempt, this is the total time spent waiting before completion. |
record_file | Path of the generated recording when dial recording was enabled and started. Omitted when no recording was produced. |
event_from | Caller ID of the parent call. |
event_to | Destination of the parent call. |
event_call_id | ID of the parent call. This normally matches call_id. |
Example successful dial callback:
call_id=CALL-123
bridge_call_id=CALL-456
dial_status=1
duration=84
waiting_duration=6
record_file=records/CALL-123/dial/example.mp3
event_from=1001
event_to=2001
event_call_id=CALL-123
As with <Gather>, the dial action endpoint should return Voice XML. Use the returned
fields to select the next flow, such as retrying another destination when dial_status=0
or ending the call after a successful connection.
<Record> Verb
Records caller audio with optional timeout, key-based stop, beep, and transcription support.
| Attribute | Description |
|---|---|
action | Webhook URL receiving recording metadata and file reference. |
method | HTTP method for action URL. |
timeout | Seconds of silence before auto-stop. |
finishOnKey | Key to end recording (set 0 to disable key stop). |
transcribe | Enable transcription output. |
trim | Trim leading/trailing silence. |
beep | Play beep before recording starts. |
<Response>
<Record
action="https://example.com/handle_recording"
method="POST"
timeout="5"
finishOnKey="#"
beep="true" />
</Response> <STREAM> Verb
Creates a live, bidirectional audio stream over WebSocket for AI agents or custom real-time services.
<?xml version="1.0"?>
<response>
<connect>
<stream name="stream" url="ws://127.0.0.1:8766/ws">
<parameter name="param1" value="param1_value" />
<parameter name="param2" value="param2_value" />
</stream>
</connect>
</response> <Hangup> Verb
Immediately disconnects the active call.
<Response>
<Say>We are now going to hang up.</Say>
<Hangup />
</Response> <Pause> Verb
Temporarily pauses call execution for the defined duration.
<Response>
<Pause length="3" />
<Say>Your call is very important to us.</Say>
</Response> <Redirect> Verb
Stops current execution and loads a new XML instruction document from the specified URL.
<Response>
<Say>You will now be redirected to a different set of instructions.</Say>
<Redirect method="GET">https://example.com/new_instructions.xml</Redirect>
</Response> <Bridge> Verb
Bridges the active call with another in-progress call using a bridge call ID.
| Attribute | Description |
|---|---|
bridgeAfterEstablish |
Boolean flag controlling bridge timing: false attempts immediate bridge,
true waits until secondary call is fully established.
|
<Response>
<Say>We are bridging your call now.</Say>
<Bridge bridgeAfterEstablish="true">ABC123</Bridge>
</Response> <Leave> Verb
Removes the caller from queue/conference context while continuing the call flow.
<Response>
<Say>You will now leave the queue, but remain on the call.</Say>
<Leave />
<Say>Welcome back! You have left the queue.</Say>
</Response>