{"templateId":"openapi_docs","sharedDataIds":{"openAPIDocsStore":"oas-docs/voice-2.0/api-reference/voice.yaml","sidebar":"sidebar-docs/voice-2.0/sidebars.yaml"},"props":{"definitionId":"docs/voice-2.0/api-reference/voice.yaml","dynamicMarkdocComponents":[],"baseSlug":"/docs/voice-2.0/api-reference/voice","seo":{"title":"Voice API v2","siteUrl":"https://developers.sinch.com","llmstxt":{"title":"Sinch Developer Documentation","description":"LLMs.txt containing a map of all the documentation files for Sinch.","sections":[{"title":"Numbers API","description":"The Numbers API enables you to search for, view, and activate numbers. It's considered a precursor to other APIs in the Sinch product family. The numbers API can be used in tandem with any of our APIs that perform messaging or calling.","includeFiles":["docs/numbers/**/*.md","docs/numbers/**/*.yaml"],"excludeFiles":["docs/numbers/index.md"]},{"title":"Conversation API","description":"Send and receive messages globally on many popular channels with ease and confidence when using Sinch's Conversation API. Conversation API is the preferred API for sending mobile messages on SMS and other social channels with Sinch. It is a simple API with unified error messages, consistent request payloads, and common webhook payloads that are channel-agnostic.","includeFiles":["docs/conversation/**/*.md","docs/conversation/**/*.yaml"],"excludeFiles":["docs/conversation/index.md"]},{"title":"Voice API","description":"The Voice API works as a big telephony switch. The Voice API handles incoming phone calls (also known as incoming call “legs”), sets up outgoing phone calls (or outgoing call “legs”), and bridges the two. The incoming call leg may come in over a data connection (from a smartphone or web application using the Sinch SDKs) or through a local phone number (from the PSTN network). Similarly, the outgoing call leg can be over data (to another smartphone or web application using the Sinch SDKs) or the PSTN network.","includeFiles":["docs/voice/**/*.md","docs/voice/**/*.yaml"],"excludeFiles":["docs/voice/index.md"]},{"title":"Voice API v2","description":"The Voice API works as a big telephony switch. The Voice API handles incoming phone calls (also known as incoming call “legs”), sets up outgoing phone calls (or outgoing call “legs”), and bridges the two. The incoming call leg may come in over a data connection (from a smartphone or web application using the Sinch SDKs) or through a local phone number (from the PSTN network). Similarly, the outgoing call leg can be over data (to another smartphone or web application using the Sinch SDKs) or the PSTN network.","includeFiles":["docs/voice-2.0/**/*.md","docs/voice-2.0/**/*.yaml"],"excludeFiles":["docs/voice-2.0/index.md"]},{"title":"Verification API","description":"The Verification API is a platform for phone number verification. It consists of the API and different software development kits (the Sinch SDKs) that you integrate with your smartphone or web application and cloud based back-end services. Together they enable SMS, Flashcall, Phone Call and Data verification in your application.","includeFiles":["docs/verification/**/*.md","docs/verification/**/*.yaml"],"excludeFiles":["docs/verification/index.md"]},{"title":"Provisioning API","description":"Provisioning API allows you to programmatically set up your senders, accounts and templates on your favorite messaging platforms on the Conversation API. For now, you can create your first WhatsApp channel through Meta's Embedded sign up, you can configure your first SMS App and configure your webhooks. As development continues, we will be adding the most commonly used channels.","includeFiles":["docs/provisioning-api/**/*.md","docs/provisioning-api/**/*.json"],"excludeFiles":["docs/provisioning-api/index.md"]},{"title":"Elastic SIP Trunking API","description":"With Elastic SIP Trunking you can create and manage your SIP trunks and phone numbers programmatically.","includeFiles":["docs/est/**/*.md","docs/est/**/*.yaml"],"excludeFiles":["docs/est/index.md"]},{"title":"Fax API","description":"Send and receive HIPAA compliant faxes on our modern fax platform using our developer-friendly API.","includeFiles":["docs/fax/**/*.md","docs/fax/**/*.yaml"],"excludeFiles":["docs/fax/index.md"]},{"title":"In-app Voice and Video SDK","description":"The In-app Voice and Video SDK enables you to add voice and video calling capabilities directly into your mobile or web application using the Sinch SDKs.","includeFiles":["docs/in-app-calling/**/*.md"],"excludeFiles":["docs/in-app-calling/index.md"]},{"title":"Number Lookup API","description":"The Number Lookup API is designed to provide in-depth information about phone numbers, helping enterprises enhance their communication strategies and prevent fraud. By identifying the type of phone line (for example, mobile, landline, VoIP) and the associated carrier, the API allows businesses to optimize routing, reduce unnecessary costs, and improve customer engagement.","includeFiles":["docs/number-lookup-api-v2/**/*.md","docs/number-lookup-api-v2/**/*.yaml"],"excludeFiles":["docs/number-lookup-api-v2/index.md"]},{"title":"Functions","description":"Serverless compute for voice and messaging. Deploy your code and Sinch routes live calls and messages to it — no infrastructure to run.","includeFiles":["docs/functions/functions/**/*.md","docs/functions/concepts/**/*.md","docs/functions/reference/**/*.md"],"excludeFiles":["docs/functions/functions/index.md"]},{"title":"CLI","description":"One command line for every Sinch API and the full Functions lifecycle — scaffold, run locally, deploy, and manage.","includeFiles":["docs/functions/cli/**/*.md"],"excludeFiles":["docs/functions/cli/index.md"]}]}},"itemId":"","disableAutoScroll":true,"metadata":{"type":"openapi","title":"Voice API v2","description":"# Core Concepts\n\nThe Voice API enables embedding voice calling into applications for virtually limitless use cases. From **number masking** for privacy, automated **appointment reminders**, and **outreach campaigns** with answering machine detection, to **bridging calls** between PSTN and SIP endpoints, the API offers the flexibility and control needed for modern communications.\n\n## Call Model\n\n{% table %}\n\n- Concept\n- Description\n\n---\n\n- **Session**\n- A session initiates as soon as the first call is created. It serves as a container for all related calls and their connections, maintaining context and state throughout the interaction. The session persists until all associated calls are terminated.\n\n---\n\n- **Call**\n- A single participant's connection in a session (e.g., caller or callee).\n- **Inbound Call:** A call initiated from an external source (PSTN, SIP, etc.) into the service.\n- **Outbound Call:** A call initiated by the service to an external destination.\n\n---\n\n- **Bridge**\n- A mechanism to connect one or more calls, so that participants can communicate with each other.\n![session bridge chart](/images/voicev2/voicev2-session-chart.png)\n\n{% /table %}\n\n### Initiating Calls\n\nThere are a few ways to create a call:\n\n1. **Inbound Calls:** Triggered by incoming traffic from PSTN, SIP, or other sources.\n2. **Outbound Calls (via Dial):** Initiated from within an existing call session using the `dial` command.\n3. **Outbound Calls (via API):** Created directly by sending an API request to the Voice API.\n4. **Call Queuing:** Calls can be queued and processed based on parameters such as priority, time, or custom logic.\n\n### Call Pacing (Batch)\n\nThe new Voice API v2 supports Call pacing via batch calling to efficiently manage high volumes of outbound calls. This is especially useful for scenarios like appointment reminders, notifications, or campaigns where customers need to reach multiple recipients in a controlled and scalable way.\n\n#### How To Initiate Batch Calls\n\nTo initiate several calls in a batch, send a POST request to the `/v2/projects/{projectId}/calls` endpoint. The request body contains a SVAML payload describing the call flow and a list of parameters for each call in the batch. The API queues and triggers calls according to the provided configuration, such as maximum calls per second (`maxCps`) and time-to-live (`ttlSeconds`).\n\n```json\n{\n  \"commands\": [\n    {\n      \"command\": \"dial\",\n      \"callName\": \"batch-notification\",\n      \"from\": { \n        \"type\": \"PHONE\",\n        \"phone\": { \"number\": \"@from\" } \n      },\n      \"to\": { \n        \"type\": \"PHONE\",\n        \"phone\": { \"number\": \"@to\" } \n      },\n      \"events\": {\n        \"onAnswer\": [\n          {\n            \"command\": \"messages\",\n            \"messages\": [\n              {\n                \"type\": \"SAY\",\n                \"say\": {\n                  \"text\": \"Hello @name, you have an appointment tomorrow at 10 AM.\",\n                  \"voiceName\": \"Emma\"\n                }\n              }\n            ]\n          }\n        ]\n      }\n    }\n  ],\n  \"parameters\": [\n    { \"from\": \"+46712345678\", \"to\": \"+46787654321\", \"name\": \"Alice\" },\n    { \"from\": \"+46712345678\", \"to\": \"+46781234567\", \"name\": \"Bob\" }\n  ],\n  \"batchOptions\": {\n    \"maxCps\": 10,\n    \"ttlSeconds\": 60\n  }\n}\n```\n\n- **commands:** SVAML commands describing the call flow for each call in the batch. Parameter placeholders start with `@` and can be used as variables for each call. They can be used alone as in `@from` or in combination with text in a say message (e.g., `Hello @name, your appointment is at @time`).\n- **parameters:** An array of objects, each specifying the values for the placeholders in the commands. Each object represents a call to be queued and triggered.\n- **batchOptions:** Controls how the batch is processed:\n  - `maxCps`: Maximum number of calls per second to be initiated.\n  - `ttlSeconds`: Time-to-live for the batch in seconds; calls not initiated within this time window will be skipped.\n\nThe API responds with metadata for the queued calls:\n\n- **sessionIds:** Each call in the batch is assigned a unique sessionId, which can be used to track the state and progress of individual calls.\n- **batchId:** The batchId identifies the entire batch operation, allowing batch state and summaries to be queried, or the batch to be managed as a whole (e.g., cancel unprocessed calls).\n- **Other properties:** The response may also include other Ids, timestamps, and state related information.\n\n\n#### How Calls Are Triggered\n\nWhen a batch request is submitted:\n1. The API validates the SVAML commands and parameters.\n2. Calls are queued and triggered according to `maxCps` and `ttlSeconds` settings.\n3. Each call is processed independently, using the provided parameters to personalize the call flow.\n4. The API tracks the state of each call (e.g., `QUEUED`, `INITIATED`, `IN_PROGRESS`, `COMPLETED`).\n5. Batch progress can be monitored and summaries can be retrieved via the [GET] `/v2/projects/{projectId}/batches/{batchId}` endpoint.\n\n## Call Lifecycle\n\nA call progresses through several states from creation to completion.\n\n**Call States**\n\n{% table %}\n\n- State\n- Description\n\n---\n\n- `QUEUED` \n- Call is waiting to be processed.\n\n---\n\n- `INITIATED`\n- Call setup is in progress (ringing).\n\n---\n\n- `IN_PROGRESS`\n- Call is answered and active.\n\n---\n\n- `COMPLETED`\n- Call ended normally.\n\n---\n\n- `REJECTED`\n- Recipient rejected the call.\n\n---\n\n- `NO_ANSWER`\n- Recipient did not answer.\n\n---\n\n- `CANCEL`\n- Call was cancelled before being answered.\n\n---\n\n- `BUSY`\n- Recipient was busy.\n\n---\n\n- `FAILED`\n- Call could not be set up.\n\n{% /table %}\n\n**Call Transitions**\n\n![transition states flowchart](/images/voicev2/voicev2-transition-states.png)\n\nThis diagram shows how a call moves between states. Typically, most calls start at `QUEUED`, progress to `INITIATED`, and either get answered (`IN_PROGRESS`) or end in a final state (`COMPLETED`, `NO_ANSWER`, etc.).\n\n## Handling Events with Webhooks\n\nWhen a specific event occurs (for example, a call is answered), the Voice API v2 sends an HTTP request (usually POST) to the webhook URL configured in service settings. The request contains details about the event, such as call identifiers and timestamps. The application can then respond with [SVAML commands](/docs/voice/api-reference/svaml) to control the ongoing call or perform other actions.\n\n### Typical Request-Response Cycle\n\n1. An event (e.g., call.answered) occurs in the Voice API.\n2. The API sends a POST request to the configured webhook endpoint with event details.\n3. The server processes the event and responds with SVAML commands (e.g., play a message, gather input).\n4. The API executes the commands and updates the call state.\n\n```mermaid\nsequenceDiagram\n  participant VoiceAPI as Voice API\n  participant Backend as Application Backend\n  VoiceAPI ->> Backend: POST webhook (event details)\n  Backend ->> VoiceAPI: SVAML commands (response)\n  VoiceAPI ->> Backend: Further webhooks (if needed)\n  Backend ->> VoiceAPI: Additional SVAML commands\n```\n\nWebhook endpoints must respond within 5 seconds. If the endpoint fails or times out and a `fallbackUrl` is configured, the request is re-sent to the fallback URL. See *Timeouts and failover* in the **Webhooks** section for the algorithm and its effect on delivery guarantees.\n\n### Webhooks vs. Events\n\n- **Webhooks:** External HTTP notifications sent to the application when specific events occur.\n- **Events:** Internal API notifications about call state changes; can be exposed via webhooks for external handling or internally by predefining event handlers in SVAML commands.\n\n### Event Naming Convention\n\nEvents are named using the pattern `resource.command.event`.\n\nFor example:\n- `call.answered`: Indicates that a call was answered.\n- `call.amd.machine`: Indicates that the Answering Machine Detection (AMD) on a call detected a machine.\n\nThis convention helps clearly identify the resource, the command involved, and the specific event that occurred.\n\n#### Common Webhook Events\n\n- `call.incoming`: Triggered when a call is received from PSTN, SIP, etc.\n- `call.answered`: Triggered when a call is answered.\n- `call.hangup`: Triggered when a call is hung up.\n\n### Precedence Rules\n\nWhen handling events in call flows, the Voice API applies the following precedence rules to determine which SVAML commands are executed:\n\n- **Command-Level Event Handlers:**  \n  If an event handler (e.g., `on_answer`, `on_machine`) is defined directly within a SVAML command, the commands specified in that handler are executed first for that event.\n\n- **Service Configuration Fallback:**  \n  If the event handler is not defined in the SVAML command, the API falls back to the event handler defined in the service configuration. This allows default behaviors for events to be set at the service level.\n\n- **Execution Order:**  \n  - Command-level event handlers always take priority over service-level handlers.\n  - If neither is defined, the event is ignored and no commands are executed for that event.\n\n**Best Practice:**  \nDefine event handlers in SVAML commands for custom, per-call logic. Use service configuration event handlers for default or global behaviors across all calls.\n\n\n### Webhook Request Example\n\nWhen a call is answered, the API sends a POST request to the configured webhook endpoint that includes the event type and the current call details.\n\nThe webhook endpoint should return a valid SVAML payload specifying which commands to execute on the call. For example, the response below synthesizes a welcome message and then ends the call.\n\n```json\n{\n  \"commands\": [\n    {\n      \"command\": \"messages\",\n      \"messages\": [\n        {\n          \"type\": \"SAY\",\n          \"say\": {\n            \"text\": \"Welcome to our service!\",\n            \"voiceName\": \"Emma\"\n          }\n        }\n      ]\n    },\n    {\n      \"command\": \"hangup\"\n    }\n  ]\n}\n```\n\n### Regions\n\nThe following table displays the servers available for each region.\n\n| Region | Server |\n| ------ | ------ |\n| Global endpoint - Redirected by Sinch to the closest region. | `https://voice.api.sinch.com` |\n| North America 1 - East | `https://us1.voice.api.sinch.com` |\n| South America 1 - East | `https://br1.voice.api.sinch.com` |\n| Europe 1 - Central | `https://eu1.voice.api.sinch.com` |\n| Asia Pacific 1 - Southeast | `https://sg1.voice.api.sinch.com` |\n| Australia & Oceania 1 - Southeast | `https://au1.voice.api.sinch.com` |\n\n### Best Practices\n\n- **Respond Quickly:** Webhook requests should be processed and responded to as quickly as possible to avoid call delays.\n- **Idempotency:** A failed request is re-sent to the fallback URL, so the same event can arrive more than once. Make the handler idempotent and deduplicate on the `ce-id` and `ce-source` headers — see *Timeouts and failover* in the **Webhooks** section.\n- **Logging:** Log incoming webhook requests and responses for troubleshooting and auditing.\n- **Validation:** Validate incoming requests to ensure they are from the Voice API (see Security below).\n\n### Security\n\nTo safeguard a webhook endpoint, verify that incoming requests are genuinely sent by the Voice API and have not been altered in transit. This prevents unauthorized access and mitigates risks such as man-in-the-middle attacks.\n\n1. Each service has an access key and secret.\n2. When a webhook arrives, use the key and secret to compute a hash of the payload.\n3. Compare the computed hash to the signature in the request authorization header.\n4. Only process the webhook if the hashes match.\n\nAccess to the webhook endpoint may also be restricted by IP address, and HTTPS can be used to encrypt traffic.\n","summary":"Make and receive voice calls with Sinch's RESTful Voice API interface."},"compilationErrors":[],"markdown":{"partials":{},"variables":{"rbac":{"teams":["anonymous"]},"user":{},"remoteAddr":{"hostname":"developers.sinch.com","port":4000,"ipAddress":"216.73.217.7"},"lang":"default_locale","env":{"PUBLIC_REDOCLY_BRANCH_NAME":"main"}}},"pagePropGetterError":{"message":"","name":""}},"slug":"/docs/voice-2.0/api-reference/voice","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}