Build voice apps with Sinch Voice REST API. Use for phone calls, text-to-speech (TTS), IVR menus, DTMF input, conference calling, call recording, call forwarding, answering machine detection (AMD), SIP routing, WebSocket audio streaming, and SVAML call control.
Scanned 5/27/2026
Install via CLI
openskills install sinch/skills---
name: sinch-voice-api
description: Build voice apps with Sinch Voice REST API. Use for phone calls, text-to-speech (TTS), IVR menus, DTMF input, conference calling, call recording, call forwarding, answering machine detection (AMD), SIP routing, WebSocket audio streaming, and SVAML call control.
metadata:
author: Sinch
version: 1.1.2
category: Voice
tags: voice, calls, tts, ivr, dtmf, conference, recording, svaml, sip, amd, webrtc
uses:
- sinch-authentication
- sinch-sdks
---
# Sinch Voice API
## Overview
The Sinch Voice API lets you make, receive, and control voice calls programmatically via REST. It uses **SVAML** (Sinch Voice Application Markup Language) to define call flows through callback events.
## Agent Instructions
Before generating code, you MUST ask the user:
1. **Approach** — SDK or direct API calls (curl/fetch/requests)?
- [Node.js SDK Reference](https://developers.sinch.com/docs/voice/sdk/node/syntax-reference.md)
- [Python SDK Reference](https://developers.sinch.com/docs/voice/sdk/py/syntax-reference.md)
- [Java SDK Reference](https://developers.sinch.com/docs/voice/sdk/java/syntax-reference.md)
- [.NET SDK Reference](https://developers.sinch.com/docs/voice/sdk/dotnet/syntax-reference.md)
2. **Language** — Node.js, Python, Java, .NET, curl?
When generating SDK code, fetch the corresponding SDK reference page for accurate method signatures, or use the bundled examples:
- [Node.js examples](references/examples/nodejs.md) | [Python examples](references/examples/python.md) | [Java examples](references/examples/java.md) | [.NET examples](references/examples/dotnet.md)
When generating direct API calls, use the [Voice API Reference (Markdown)](https://developers.sinch.com/docs/voice/api-reference/voice.md) for request/response schemas.
## Getting Started
### Authentication
See the [sinch-authentication](../sinch-authentication/SKILL.md) skill. The Voice API uses **Application Key + Application Secret** (not project-level OAuth2).
- **Basic Auth**: `Authorization: Basic base64(APPLICATION_KEY:APPLICATION_SECRET)`
- **Signed Requests** (production): HMAC-SHA256 signing. See [Authentication Guide](https://developers.sinch.com/docs/voice/api-reference/authentication.md).
### Base URLs
| Region | Base URL |
|--------|----------|
| Global (default) | `https://calling.api.sinch.com` |
| North America | `https://calling-use1.api.sinch.com` |
| Europe | `https://calling-euc1.api.sinch.com` |
| Southeast Asia 1 | `https://calling-apse1.api.sinch.com` |
| Southeast Asia 2 | `https://calling-apse2.api.sinch.com` |
| South America | `https://calling-sae1.api.sinch.com` |
Configuration endpoints (numbers, callbacks) use: `https://callingapi.sinch.com`
### SDK Installation
See [sinch-sdks](../sinch-sdks/SKILL.md) for installation and client initialization across all languages.
### First API Call: TTS Callout
```bash
curl -X POST \
"https://calling.api.sinch.com/calling/v1/callouts" \
-u "{APPLICATION_KEY}:{APPLICATION_SECRET}" \
-H "Content-Type: application/json" \
-d '{
"method": "ttsCallout",
"ttsCallout": {
"destination": { "type": "number", "endpoint": "+14045005000" },
"cli": "+14045001000",
"locale": "en-US",
"text": "Hello! This is a test call from Sinch."
}
}'
```
**Node.js SDK:**
```javascript
import { SinchClient } from "@sinch/sdk-core";
const sinch = new SinchClient({
applicationKey: "{APPLICATION_KEY}",
applicationSecret: "{APPLICATION_SECRET}",
});
const response = await sinch.voice.callouts.tts({
ttsCalloutRequestBody: {
destination: { type: "number", endpoint: "+14045005000" },
cli: "+14045001000",
locale: "en-US",
text: "Hello! This is a test call from Sinch.",
},
});
console.log("Call ID:", response.callId);
```
For more examples, see [Callouts Reference](https://developers.sinch.com/docs/voice/api-reference/voice/callouts/callouts.md) or [bundled examples](references/examples/).
## Key Concepts
### SVAML (Sinch Voice Application Markup Language)
SVAML controls call flow. Every SVAML response has:
- **instructions** (array): Multiple tasks — play audio, record, set cookies
- **action** (object): Exactly ONE routing/control action
Full reference: [SVAML Actions](https://developers.sinch.com/docs/voice/api-reference/svaml.md#actions) | [SVAML Instructions](https://developers.sinch.com/docs/voice/api-reference/svaml.md#instructions) | [Bundled SVAML Reference](references/svaml.md)
### Actions (one per response)
| Action | Description |
|--------|-------------|
| `hangup` | Terminate the call |
| `continue` | Continue call setup (ACE response to proceed without rerouting) |
| `connectPstn` | Connect to PSTN number. Supports `amd` for Answering Machine Detection |
| `connectMxp` | Connect to Sinch SDK (in-app) endpoint |
| `connectConf` | Connect to conference room by `conferenceId` |
| `connectSip` | Connect to SIP endpoint |
| `connectStream` | Connect to a WebSocket server for real-time audio streaming (**closed beta** — contact Sinch to enable) |
| `runMenu` | IVR menu with DTMF collection (supports `enableVoice` for speech input) |
| `park` | Park (hold) the call with looping prompt |
### Instructions (multiple per response)
| Instruction | Description |
|-------------|-------------|
| `playFiles` | Play audio files, TTS via `#tts[]`, SSML via `#ssml[]` |
| `say` | Synthesize and play text-to-speech |
| `sendDtmf` | Send DTMF tones |
| `setCookie` | Persist key-value state across callback events in the session |
| `answer` | Answer the call (sends a SIP 200 OK to the INVITE, which starts billing). Required before playing prompts on unanswered calls |
| `startRecording` | Begin recording. Supports `transcriptionOptions` for auto-transcription |
| `stopRecording` | Stop an active recording |
### Callback Events
| Event | Trigger | SVAML Response |
|-------|---------|----------------|
| **ICE** | Call received by Sinch platform | Yes |
| **ACE** | Call answered by callee | Yes |
| **DiCE** | Call disconnected | No (fire-and-forget, logging only) |
| **PIE** | DTMF/voice input from `runMenu` | Yes |
| **Notify** | Notification (e.g., recording finished) | No |
See [Callbacks Reference](https://developers.sinch.com/docs/voice/api-reference/voice/callbacks/ice.md) for event schemas, or [bundled callbacks reference](references/callbacks.md) for full field tables and JSON examples.
### Callout Types
| Method | Use Case |
|--------|----------|
| `ttsCallout` | Call and play synthesized speech. Supports `text` or advanced `prompts` (`#tts[]`, `#ssml[]`, `#href[]`) |
| `conferenceCallout` | Call and connect to a conference room |
| `customCallout` | Full SVAML control with inline ICE/ACE/PIE |
Callout flags: `enableAce` (default `false`), `enableDice` (default `false`), `enablePie` (default `false`) control which callbacks fire.
### REST Endpoints
Paths starting with `/calling/v1/` use the **regional base URL** from the table above. Paths starting with `/v1/configuration/` use `https://callingapi.sinch.com`.
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/calling/v1/callouts` | Place a callout (TTS, conference, or custom) |
| PATCH | `/calling/v1/calls/id/{callId}` | Update in-progress call with SVAML (PSTN/SIP only) |
| GET | `/calling/v1/calls/id/{callId}` | Get call info |
| PATCH | `/calling/v1/calls/id/{callId}/leg/{callLeg}` | Manage a call leg (PlayFiles/Say only) |
| GET | `/calling/v1/conferences/id/{conferenceId}` | Get conference info |
| DELETE | `/calling/v1/conferences/id/{conferenceId}` | Kick all participants |
| PATCH | `/calling/v1/conferences/id/{conferenceId}/{callId}` | Mute/unmute/hold participant |
| DELETE | `/calling/v1/conferences/id/{conferenceId}/{callId}` | Kick specific participant |
| GET | `/v1/configuration/numbers` | List numbers and capabilities |
| POST | `/v1/configuration/numbers` | Assign numbers to an application |
| DELETE | `/v1/configuration/numbers` | Un-assign a number |
| GET/POST | `/v1/configuration/callbacks/applications/{applicationkey}` | Get/update callback URLs |
## Common Patterns
### IVR Menu (SVAML)
```json
{
"instructions": [
{ "name": "setCookie", "key": "step", "value": "ivr" }
],
"action": {
"name": "runMenu",
"mainMenu": "main",
"menus": [{
"id": "main",
"mainPrompt": "#tts[Press 1 for sales or 2 for support.]",
"options": [
{ "dtmf": 1, "action": "return(sales)" },
{ "dtmf": 2, "action": "return(support)" }
]
}]
}
}
```
### Conference with Recording
```json
{
"instructions": [
{ "name": "startRecording", "options": { "notificationEvents": true } }
],
"action": {
"name": "connectConf",
"conferenceId": "myRoom",
"moh": "ring"
}
}
```
### PSTN Forward with AMD
```json
{
"action": {
"name": "connectPstn",
"number": "+14045009000",
"cli": "+14045001000",
"maxDuration": 3600,
"amd": { "enabled": true }
}
}
```
## Executable Scripts
Bundled Node.js scripts (no external dependencies, uses Basic Auth):
```bash
export SINCH_APPLICATION_KEY="{APPLICATION_KEY}"
export SINCH_APPLICATION_SECRET="{APPLICATION_SECRET}"
export SINCH_VOICE_REGION="global" # optional
```
| Script | Description | Example |
|--------|-------------|--------|
| `make_tts_call.cjs` | TTS callout | `node scripts/make_tts_call.cjs --to +14045005000 --text "Hello"` |
| `make_conference_call.cjs` | Conference callout | `node scripts/make_conference_call.cjs --to +14045005000 --conference-id myRoom` |
| `get_call_info.cjs` | Get call details | `node scripts/get_call_info.cjs --call-id CALL_ID` |
| `list_numbers.cjs` | List voice numbers | `node scripts/list_numbers.cjs` |
## Gotchas and Best Practices
1. **Callback URL must be publicly accessible.** Use ngrok for local dev. Configure in Dashboard under Voice app settings.
2. **ONE action per SVAML response.** Multiple instructions are fine. Chain callbacks for sequential actions (ICE → ACE → PIE).
3. **ACE not sent for in-app destinations.** ACE is not issued when destination type is `username`, only for PSTN/SIP. Setting `enableAce: true` has no effect for in-app destinations.
4. **DiCE is fire-and-forget.** Informational only. No SVAML response expected. Use for logging/cleanup.
5. **Regional endpoints matter.** Wrong region increases latency. Conference rooms have regional scope — force all participants to the same region for cross-region conferences.
6. **Instruction ordering matters.** Array order = execution order. Place `answer` before `playFiles`; place `startRecording` before the connecting action.
7. **Max call duration: 14400 seconds (4 hours).** Set `maxDuration` on `connectPstn`/`connectSip` for shorter limits.
8. **Validate callback signatures in production.** HMAC-SHA256 signature in `Authorization` header. See [Callback Signing](https://developers.sinch.com/docs/voice/api-reference/authentication/callback-signed-request.md).
9. **`setCookie` for state.** Carries key-value pairs across ICE, ACE, PIE, DiCE within a call session.
10. **`connectMxp` does not support recording.** `startRecording`/`stopRecording` instructions are ignored with `connectMxp`.
11. **`runMenu` defaults.** `barge`: `true` (input accepted during prompt). `timeoutMills`: `5000` ms.
12. **AMD on `connectPstn`.** `amd: { enabled: true, async: true/false }` for answering machine detection.
13. **`startRecording` transcription.** `transcriptionOptions: { enabled: true, locale: "en-US" }` for auto-transcription.
14. **Conference DTMF options.** `conferenceDtmfOptions` on `conferenceCallout`/`connectConf` with modes: `ignore` (default), `forward`, `detect` (sends PIE).
15. **`cli` is required for TTS callouts to connect.** The API accepts a TTS callout without a `cli` parameter and returns a call ID, but the call will never reach the destination. The `cli` is the number displayed as the incoming caller — use your verified number or your Dashboard-assigned number, in E.164 format (e.g., `"+14151112223333"`). To test, register on the [Sinch Dashboard](https://dashboard.sinch.com) and use the free number assigned to your app. See [Assign your number](https://developers.sinch.com/docs/voice/getting-started.md#2-assign-your-number-and-get-your-credentials).
## Links
- [Voice API Reference (Markdown)](https://developers.sinch.com/docs/voice/api-reference/voice.md)
- [Voice API OpenAPI Spec (YAML)](https://developers.sinch.com/_bundle/docs/voice/api-reference/voice.yaml?download)
- [SVAML Actions](https://developers.sinch.com/docs/voice/api-reference/svaml.md#actions) | [SVAML Instructions](https://developers.sinch.com/docs/voice/api-reference/svaml.md#instructions)
- [Callbacks](https://developers.sinch.com/docs/voice/api-reference/voice/callbacks/ice.md) | [Callouts](https://developers.sinch.com/docs/voice/api-reference/voice/callouts/callouts.md)
- [Authentication](https://developers.sinch.com/docs/voice/api-reference/authentication.md) | [Callback Signing](https://developers.sinch.com/docs/voice/api-reference/authentication/callback-signed-request.md)
- [Node.js SDK Reference](https://developers.sinch.com/docs/voice/sdk/node/syntax-reference.md)
- [Python SDK Reference](https://developers.sinch.com/docs/voice/sdk/py/syntax-reference.md)
- [Java SDK Reference](https://developers.sinch.com/docs/voice/sdk/java/syntax-reference.md)
- [.NET SDK Reference](https://developers.sinch.com/docs/voice/sdk/dotnet/syntax-reference.md)
- [Voice Tutorials](https://developers.sinch.com/docs/voice/tutorials.md)
- [LLMs.txt (full docs index)](https://developers.sinch.com/llms.txt)
No comments yet. Be the first to comment!