Turn phone calls on for a number
Adds voice to one of the numbers you hold, or gives you a new one. Send number for a number that is already yours (see GET /v3/channels); leave it out to be given a new US number, optionally in a particular area_code. Sending both is refused. Nothing registers, so the number can carry calls as soon as this returns.
What happens on a call is decided by your callback_url: when a call arrives on the number, or a caller presses a key on a menu, Sent POSTs a signed question there and follows the answer. The response carries the callback_secret the questions are signed with, the one time it is shown without rotating; verify a question the way you verify a webhook. POST /v3/channels/voice/{number}/test sends a test question and reports the verdict.
Send agent_id instead of callback_url, or with it, to have one of your voice agents (GET /v3/voice/agents) answer calls to the number. The agent wins over the callback URL for calls to the number; calls your app places from it still follow your app. routes_to in the response says which answers, and reads agent_pending while the number is still being moved to the agent. Calls follow the move within about an hour, as the provider applies it on its own clock. While numbers cannot be bound to agents, a request with agent_id is refused with 502 before any number is obtained or anything is written; send callback_url instead.
Your first voice number becomes the line app-originated calls are placed from when a voice token names no number; send default_for_app_calls: true to give that role to another number. A number you turned off earlier is turned back on, and the same number with a different callback_url has its URL replaced and keeps its secret.
Read the number's settings with GET /v3/channels/voice and change them with PATCH /v3/channels/voice/{number}.
With sandbox: true the request is validated and a simulated number reported with 202; nothing is written and no number is bought.
Idempotency-Key?stringUnique key to ensure idempotent request processing. Must be 1-255 alphanumeric characters, hyphens, or underscores. Responses are cached for 24 hours per key per customer.
^[a-zA-Z0-9_-]+$length <= 255x-profile-id?stringProfile UUID to scope the request to a child profile. Only organization API keys can use this header. The profile must belong to the calling organization.
uuidapplication/json- body
Turns phone calls on for a number: one you already hold, or a new one.
Voice is per number the way SMS is per market: each number you hold can carry calls on its own, and each has its own callback URL, where Sent asks what to do with every call on it, or a voice agent that answers calls to it. The first number you turn voice on for becomes the line app-originated calls are placed from when a voice token names no number.
Send number to add calls to a number you already hold, or leave it out to be given a new US number — optionally in a particular area_code. The two are alternatives, not a pair.
sandbox?booleanSandbox flag - when true, the operation is simulated without side effects Useful for testing integrations without actual execution
number?|One of your phone numbers, in E.164 format. Leave the field out entirely to be given a new one instead; sending it empty is a refused request rather than a request for a new number.
area_code?|The US area code a new number should be in, as 212. Only for a request that leaves number out — sending both says two different things about which number to use, and is refused. Omit it too and the number comes from anywhere in the country.
callback_url?|Where Sent asks what to do with each call on this number: an absolute HTTP or HTTPS URL on a public host. A signed question is POSTed here when a call arrives or a caller presses a key, and the answer decides the call. Every question is signed with the callback_secret the response returns, the same way your webhooks are signed. Turning the number on again with a different URL replaces it and keeps the secret. Required unless agent_id is sent.
agent_id?|One of your voice agents (GET /v3/voice/agents), such as agent_9f2ab000-0000-4000-8000-000000000001, to answer calls to this number. It wins over callback_url for calls to the number, and both may be sent; calls your app places from the number still follow your app. Send it instead of callback_url for a number only an agent answers.
default_for_app_calls?|Make this the line app-originated calls are placed from when a voice token names no number. Omit it and your first voice number takes that role; a later one leaves it where it is.
Voice is on for the number; store callback_secret now
application/json- response
Standard API response envelope for all v3 endpoints
success?booleanIndicates whether the request was successful
data?|nullThe response data (null if error)
error?|nullError details (null if successful)
meta?Metadata about the request and response
curl -X POST 'https://api.sent.dm/v3/channels/voice' \ -H 'Idempotency-Key: req_abc123_retry1' \ -H 'Content-Type: application/json' \ -d '{ "number": "+12125550100", "callback_url": "https://example.com/voice", "default_for_app_calls": false, "sandbox": false}'{ "success": true, "data": { "callback_secret": "whsec_MWYyZDFlMmU2N2RmNmI3YThmNTZhODFiYzJlNGQzYjI=", "number": "+12125550100", "status": "ACTIVE", "default_for_app_calls": true, "callback_url": "https://example.com/voice", "agent_id": null, "routes_to": "callback", "created_at": "2026-07-22T12:00:00+00:00", "updated_at": "2026-07-22T12:00:00+00:00" }, "error": null, "meta": { "request_id": "req_7X9zKp2jDw", "timestamp": "2026-11-12T15:32:26.8029207+00:00", "version": "v3" }}Voice agent protocol
Reference for the frames a voice agent exchanges with Sent over the sent.voice.v1 WebSocket subprotocol: connection, session, text, audio, tool, heartbeat and resume frames, the tool and error codes, close codes, limits, and a worked text session.
List your voice numbers GET
Every number you turned phone calls on for, active or inactive, oldest first. Each entry carries the number's status, whether it is the default line for calls placed from your app, and its callback URL. The signing secret is never on a read; it is shown when voice is turned on and by `POST /v3/channels/voice/{number}/rotate-secret`. The same entries `GET /v3/channels` reports under `voice`, and the same shape `GET /v3/channels/voice/{number}` returns for one of them. Change a number with `PATCH /v3/channels/voice/{number}`.