Sinch Voice API: Choosing between v1 and v2
For all new projects, please use Voice API v2. This is especially important for projects involving:
- AI capabilities like Streams and Voice Relay
- Voice campaigns like Batch calling
You should only use the older Voice API v1 if one of the following is a strict requirement:
- The project must be in General Availability (GA).
- The project requires In-App voice or Conferencing (until these features are available in v2).
SVAML (Sinch Voice API Markup Language) v2 is a powerful command language for controlling call flows. It consists of a list of commands sent to the API to manage calls, either as part of call setup or dynamically during a call.
- SVAML commands are sent as a JSON array of objects, each representing an action to be performed on the call.
- Each command has a type (e.g.,
dial,message, etc.) and may include parameters specific to it as well as related event handlers. - Commands can be nested or chained, allowing for complex call flows (e.g., gather input, then play audio, then dial out).
- Commands can be sent as part of the initial call setup or in response to events (e.g., call answered).
A SVAML command has the following basic structure:
{
"command": "command_type",
"parameter1": "command_specific_parameter_value",
"parameter2": "command_specific_parameter_value",
"events": [
{
"on_event_name": [
{
"command": "another_command_type",
"parameter": "another_value"
}
]
}
]
}- Endpoint which enables consuming the Voice API globally - Redirected by Sinch to the closest region.https://voice.api.sinch.com/v2/projects/{projectId}/calls
- North America 1 - Easthttps://us1.voice.api.sinch.com/v2/projects/{projectId}/calls
- South America 1 - Easthttps://br1.voice.api.sinch.com/v2/projects/{projectId}/calls
- Europe 1 - Centralhttps://eu1.voice.api.sinch.com/v2/projects/{projectId}/calls
- Asia Pacific 1 - Southeasthttps://sg1.voice.api.sinch.com/v2/projects/{projectId}/calls
- https://au1.voice.api.sinch.comhttps://au1.voice.api.sinch.com/v2/projects/{projectId}/calls
{ "commands": [ { … } ] }
Command to run Answering Machine Detection on the call
SVAML commands to execute based on the answering machine detection result. These events define different call flows depending on whether a human, machine, beep, or unknown entity answers the call, or whether a machine answered without a beep being detected.
Accept an incoming call.
{ "command": "answer" }
Schema:
Answer call
Initiate outbound calls to phone numbers, SIP endpoints, streams, or conferences.
{ "command": "dial", "callName": "destination", "from": { "type": "PHONE", "phone": { "number": "+15551234567" } }, "to": { "type": "PHONE", "phone": { "number": "+15559876543" } }, "dialTimeoutDurationSeconds": 30, "maxCallDurationSeconds": 3600, "events": { "onAnswer": [ { … } ] } }
Schema:
Command to initiate a new call
Identifier for this call leg within the session. Must be unique across all active call legs in the session.
Other commands (e.g., hangup) can reference this name to target this specific leg.
Maximum time in seconds to wait for the call to be answered. If the timeout expires without an answer, the onTimeout event is triggered.
Maximum duration of the call in seconds. The call is terminated automatically when this limit is reached.
Webhook to handle call events, used when callBehaviors are set to WEBHOOK
Perform Answering Machine Detection on answered calls.
{ "command": "amd", "events": { "onHuman": [ { … }, { … } ], "onBeep": [ { … } ] } }
Schema:
Command to run Answering Machine Detection on the call
SVAML commands to execute based on the answering machine detection result. These events define different call flows depending on whether a human, machine, beep, or unknown entity answers the call, or whether a machine answered without a beep being detected.
Play audio or text-to-speech messages to participants.
{ "command": "messages", "messagesName": "greeting-sequence", "messages": [ { "type": "SAY", "say": { … } }, { "type": "PLAY", "play": { … } }, { "type": "SAY", "say": { … } } ] }
Schema:
Command to play a message on the channel
Name of the message for identification and reference within the call session.
This name is used to uniquely identify the message and must be unique within the current call session. This name can be referenced in other commands (e.g., stopMessages) to control this specific message.
Ordered list of messages to play.
SVAML commands to execute based on message playback outcomes.
Stop any ongoing message playback.
{ "command": "stopMessages", "messagesName": "my-messages" }
Schema:
Command to stop playing messages
Name of the message sequence to stop, as set by messagesName in the messages command.
Temporarily halt call commands or media playback.
{ "command": "pause", "durationMilliseconds": 1500 }
Schema:
Pause execution.
Duration of the pause in milliseconds.
End a call or disconnect a participant.
{ "command": "hangup", "callName": "origin" }
Schema:
Hangup call
Name of the call leg to end, as set by callName in the dial command.
If omitted, the current call leg is ended.
Execute a webhook to your backend for dynamic call control, expecting SVAML commands in response.
{ "command": "webhook", "webhookName": "my.custom.event", "url": "https://example.com/webhook", "fallbackUrl": "https://example.com/fallback" }
Schema:
Command to trigger a mid-call webhook
Name for this webhook event. When triggered, the webhook request's event property will contain this name prepended with call.webhook..
For example, if webhookName is set to "my.custom.event", the event will be delivered as "call.webhook.my.custom.event".
URL of the webhook endpoint to send the mid-call event to.
Fallback webhook URL used when the primary webhook URL fails.
A failed request is re-sent to this URL immediately. After repeated consecutive failures of the primary URL, requests are sent only here until the primary URL recovers.
See Timeouts and failover in the Webhooks section for the authoritative algorithm.
Starts a recording of the call channel.
{ "command": "startRecording", "recordingName": "customer-support-recording", "recordingOptions": { "format": "MP3", "recordingType": "COMBINED", "destination": "AWS", "destinationUrl": "s3://voice-recordings-prod/calls", "credentials": "accessKeyId:secretAccessKey:eu-central-1", "transcriptionOptions": { "isEnabled": true, "locale": "en-US" } }, "events": { "onFinish": [ { … } ], "onFailure": [ { … } ] } }
Schema:
Command to start recording on the channel
Identifier for this recording within the session. Must be unique across active recordings in the session.
Other commands (e.g., stopRecording) reference this name to target a specific recording.
Setting the recording name is useful for stopping the recording using the stopRecording command. If name is not set, recording can only be stopped when the call is disconnected.
Recording options for this recording.
SVAML commands to execute based on recording lifecycle outcomes.
Stops recording.
{ "command": "stopRecording", "recordingName": "my-recording" }
Schema:
Command to stop recording on the channel
Name of the recording to stop, as set by recordingName in the startRecording command.
Bridges two calls.
{ "command": "bridgeCall", "bridgeName": "my_bridge" }
Schema:
Command to add the call to a bridge
Name of the bridge to join. If no bridge with this name exists in the session, a new one is created automatically.
Define IVR menus.
{ "command": "menu", "startMenu": "main", "menus": { "main": { "prompt": { … }, "repeatPrompt": { … }, "inputTimeoutDurationSeconds": 5, "repeatCount": 2, "minimumInputLength": 1, "maximumInputLength": 1, "inputMethods": [ … ], "matches": { … }, "onFailure": [ … ] } } }
Schema:
Executes menu-based input collection using the configured menu definitions.
Name of the menu to execute first. Must match a key in menus.
Map of menu definitions keyed by menu name.
Navigate IVR Menus
{ "command": "gotoMenu", "menuName": "string" }
Schema:
Switch execution to another menu within the current menu context.
Name of the target menu to execute next. Must match a key in menus.
See the API reference for a full list of supported commands and their parameters.
This example illustrates a complete call flow defined in a single SVAML payload:
- The call begins with a
dialcommand. - When the call is answered, the
on_answerevent triggers a sequence of other commands:- AMD Detection: Performs Answering Machine Detection.
- Pause: Introduces a brief delay.
- Message Playback: Plays a message to the callee.
- If AMD detects a machine or a beep, nested event handlers execute additional commands:
- Stop Messages: Stops any ongoing message playback.
- Play Alternate Messages: Delivers an alternate message based on the event.
- Hang Up: Ends the call.
All actions are handled within the SVAML payload, eliminating the need for webhook round-trips.
{
"commands": [
{
"command": "dial",
"name": "outbound_call",
"from": {
"type": "PHONE",
"phone": {
"number": "+46701234567"
}
},
"to": {
"type": "PHONE",
"phone": {
"number": "+46701234568"
}
},
"events": [
{
"on_answer": [
{
"command": "amd",
"events": [
{
"on_machine": [
{
"command": "pause",
"duration": "1500ms"
},
{
"command": "messages",
"name": "da-other-messages",
"messages": [
{
"type": "say",
"say": "Detected machine, alternate message played.",
"format": "text"
}
]
},
{
"command": "hangup"
}
]
},
{
"on_beep": [
{
"command": "stop-messages",
"name": "da-messages"
},
{
"command": "messages",
"name": "da-other-messages",
"messages": [
{
"type": "say",
"say": "Beep detected, stopping previous messages and playing new one.",
"format": "text"
}
]
},
{
"command": "hangup"
}
]
}
]
},
{
"command": "pause",
"duration": "1500ms"
},
{
"command": "messages",
"name": "da-messages",
"messages": [
{
"type": "say",
"say": "Hello, this is a test message",
"format": "text"
}
]
}
]
}
]
}
]
}


