API reference
Revox API
Revox places AI phone calls. You describe the conversation in an assistant (prompt, voice, first sentence, what to extract after the call), then ask Revox to call a phone number with it, one call at a time or in campaigns of thousands of contacts. After the call you get the outcome, the transcript, the recording and the data the assistant extracted.
These docs are written for developers and for AI agents: every page also exists in Markdown.
At a glance
- Base URL
- https://www.getrevox.com/api
- Auth header
- Authorization: Bearer $REVOX_API_KEY
- Content type
- application/json
- MCP server
- https://www.getrevox.com/api/mcp-servers/generic/mcp
Authentication
Every request carries an API key as a Bearer token: Authorization: Bearer YOUR_API_KEY. Create keys in the dashboard, under API keys. A key belongs to one organization: everything you create with it (assistants, calls, campaigns) lives in that organization. Keep it on your server, never in a browser or a mobile app. Check an API key tells you whether a key works.
Quickstart: place a call and get its result
- 01
Create an assistantPOST /assistants
A
name, apromptand avoice: the voice's language is the language of the call. You can skip this step and send an inlineassistantwhen you place the call.Requestcurl -X POST "https://www.getrevox.com/api/assistants" \ -H "Authorization: Bearer $REVOX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Appointment reminders", "prompt": "You are Julie, the assistant of the Acme dental practice. You call {{first_name}} to remind them of their appointment on {{appointment_date}} and ask them to confirm it. If they cannot come, offer to call them back to set a new date and ask when suits them best. Keep the call short and friendly.", "first_sentence": "Bonjour {{first_name}}, ici Julie du cabinet dentaire Acme. Je vous appelle au sujet de votre rendez-vous.", "first_sentence_mode": "static", "voice": { "provider": "cartesia", "id": "4325f426-c4e0-418e-a0e5-97fcdfcdf8e6" }, "webhook_url": "https://example.com/webhooks/revox", "structured_output_config": [ { "name": "appointment_confirmed", "type": "boolean", "description": "True when the person confirmed they will come.", "required": true }, { "name": "preferred_callback_time", "type": "datetime", "description": "When the person wants to be called back to set a new date, if they asked to." } ] }'const res = await fetch("https://www.getrevox.com/api/assistants", { method: "POST", headers: { Authorization: `Bearer ${process.env.REVOX_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ name: "Appointment reminders", prompt: "You are Julie, the assistant of the Acme dental practice. You call {{first_name}} to remind them of their appointment on {{appointment_date}} and ask them to confirm it. If they cannot come, offer to call them back to set a new date and ask when suits them best. Keep the call short and friendly.", first_sentence: "Bonjour {{first_name}}, ici Julie du cabinet dentaire Acme. Je vous appelle au sujet de votre rendez-vous.", first_sentence_mode: "static", voice: { provider: "cartesia", id: "4325f426-c4e0-418e-a0e5-97fcdfcdf8e6", }, webhook_url: "https://example.com/webhooks/revox", structured_output_config: [ { name: "appointment_confirmed", type: "boolean", description: "True when the person confirmed they will come.", required: true, }, { name: "preferred_callback_time", type: "datetime", description: "When the person wants to be called back to set a new date, if they asked to.", }, ], }), }); const data = await res.json(); console.log(data);import os import requests response = requests.post( "https://www.getrevox.com/api/assistants", headers={"Authorization": f"Bearer {os.environ['REVOX_API_KEY']}"}, json={ "name": "Appointment reminders", "prompt": "You are Julie, the assistant of the Acme dental practice. You call {{first_name}} to remind them of their appointment on {{appointment_date}} and ask them to confirm it. If they cannot come, offer to call them back to set a new date and ask when suits them best. Keep the call short and friendly.", "first_sentence": "Bonjour {{first_name}}, ici Julie du cabinet dentaire Acme. Je vous appelle au sujet de votre rendez-vous.", "first_sentence_mode": "static", "voice": { "provider": "cartesia", "id": "4325f426-c4e0-418e-a0e5-97fcdfcdf8e6", }, "webhook_url": "https://example.com/webhooks/revox", "structured_output_config": [ { "name": "appointment_confirmed", "type": "boolean", "description": "True when the person confirmed they will come.", "required": True, }, { "name": "preferred_callback_time", "type": "datetime", "description": "When the person wants to be called back to set a new date, if they asked to.", }, ], }, timeout=30, ) response.raise_for_status() print(response.json())The French voice makes every call French, even with a prompt written in English. Each call sends first_name and appointment_date in prompt_variables; the extracted values come back in structured_output of each attempt, and the call is posted to webhook_url once it is over.
- 02
Place the callPOST /call
The
phone_numberin E.164 format and theassistant_id.prompt_variablesfills the{{variables}}of the prompt for this contact. The response holds thecalland itsidright away: the call itself happens next.Requestcurl -X POST "https://www.getrevox.com/api/call" \ -H "Authorization: Bearer $REVOX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "phone_number": "+33612345678", "assistant_id": "3f6c2a1e-8b4d-4c7a-9e2f-5d1b7a9c0e34", "prompt_variables": { "first_name": "Marie", "appointment_date": "Thursday, November 12 at 10am" }, "metadata": { "crm_id": "lead_48213" } }'const res = await fetch("https://www.getrevox.com/api/call", { method: "POST", headers: { Authorization: `Bearer ${process.env.REVOX_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ phone_number: "+33612345678", assistant_id: "3f6c2a1e-8b4d-4c7a-9e2f-5d1b7a9c0e34", prompt_variables: { first_name: "Marie", appointment_date: "Thursday, November 12 at 10am", }, metadata: { crm_id: "lead_48213", }, }), }); const data = await res.json(); console.log(data);import os import requests response = requests.post( "https://www.getrevox.com/api/call", headers={"Authorization": f"Bearer {os.environ['REVOX_API_KEY']}"}, json={ "phone_number": "+33612345678", "assistant_id": "3f6c2a1e-8b4d-4c7a-9e2f-5d1b7a9c0e34", "prompt_variables": { "first_name": "Marie", "appointment_date": "Thursday, November 12 at 10am", }, "metadata": { "crm_id": "lead_48213", }, }, timeout=30, ) response.raise_for_status() print(response.json())Calls with the assistant of the Create an assistant example. prompt_variables fill its {{first_name}} and {{appointment_date}}; metadata comes back as sent on the call.
- 03
Get the resultGET /call/{id}
Poll the call every 5 to 10 seconds until its
statusiscompleted,cancelledorerrored, or set the assistant'swebhook_urland Revox POSTs the call to you (see Webhooks). Then readoutcomeandoutcome_summary, and the latest attempt's transcript, recording andstructured_outputinlast_call_attempt.Requestcurl -X GET "https://www.getrevox.com/api/call/8d2f6b1a-4c9e-4f37-b215-6a0e9c3d7f12" \ -H "Authorization: Bearer $REVOX_API_KEY"const res = await fetch("https://www.getrevox.com/api/call/8d2f6b1a-4c9e-4f37-b215-6a0e9c3d7f12", { method: "GET", headers: { Authorization: `Bearer ${process.env.REVOX_API_KEY}`, }, }); const data = await res.json(); console.log(data);import os import requests response = requests.get( "https://www.getrevox.com/api/call/8d2f6b1a-4c9e-4f37-b215-6a0e9c3d7f12", headers={"Authorization": f"Bearer {os.environ['REVOX_API_KEY']}"}, timeout=30, ) response.raise_for_status() print(response.json())
Calls and attempts
A call is an order that can take several attempts: when nobody answers, Revox calls back following the assistant's call_retry_config, inside its calling windows, sometimes over days. Each dial is an attempt in call_attempts. A call's final statuses are completed, cancelled or errored; a callee who asks to be called back at a given time sends the call back to scheduled when attempts are left.
To call a list, create a campaign with an assistant and its contacts (nothing is dialed yet), then launch its calls. Revox paces them (max_concurrent_calls), respects calling windows and retries, and keeps the campaign's statistics.
Conventions
- Revox IDs (calls, assistants, campaigns…) are UUIDs; a voice id is its provider's. Phone numbers are E.164:
+33612345678. - Timestamps are ISO 8601 in UTC. Send them ending in
Z(2026-11-09T08:30:00Z): offsets such as+01:00are rejected. - Field names are snake_case, except a few camelCase ones (in the voice endpoints, and
unpatchedCallsNotice), written as each page shows them. - Unknown body fields are ignored without an error: copy field names from the pages.
- Endpoints that say "No body" take none: send the request without one.
- Use
https:/:/ www.getrevox.com/ api getrevox.comanswers with a 301 redirect, which most HTTP clients replay as a GET.
Errors
Errors use standard status codes. Their JSON body carries error (a message), except validation failures and unexpected errors, which carry message:
400: a field or parameter failed validation:message: "Request validation failed"andbodyErrors.issues(orqueryParameterErrors.issues), each with thepathof the field and amessage. A request the API understands but refuses (an empty campaign name, nothing to launch, a call that cannot be paused now) is also a 400, witherror.401: the API key is missing or invalid.402: the organization has run out of credits (code: "INSUFFICIENT_BALANCE").403: the resource belongs to another organization.404: the resource does not exist in your organization.409: the resource's state forbids it, for example cancelling a finished call.500: unexpected server error,{"message": "Server Error"}. Retry later.502: a provider Revox relies on failed (voice cloning). Retry later.
SDKs
Official SDKs, generated from this API, may lag behind this reference:
npm install @revoxai/sdk # TypeScript
pip install revox # Python
gem install revox # RubyFor AI agents
- If your client speaks MCP, the MCP server covers the main workflow as tools (assistants, voices, calendars, single calls and their results), guides prompt writing and can wait for a call to finish. Running campaigns (it can only list them), phone numbers, exports and voice cloning are REST only.
- Every page exists in Markdown: add
.mdto its URL, or sendAccept: text/markdown. llms.txt indexes them with recipes; llms-full.txt has everything in one file. - Field descriptions are the source of truth: they say what
nulland an omitted field mean when the two differ, and the "Before you call" box of an endpoint lists the rules the schema cannot express.
Reference
- Authentication1 endpoint
Every request carries an API key as a Bearer token.
- Calls10 endpoints
A call is one order to call one phone number with an assistant.
- Assistants24 endpoints
An assistant is the voice agent that places and answers calls: its prompt, voice, first sentence and LLM, the data it extracts after each call, its tools and the calendars it books meetings on.
- Campaigns13 endpoints
A campaign calls a list of contacts with one assistant: Revox paces the calls, retries them inside the calling windows and keeps the campaign's statistics.
- Voices5 endpoints
The voices an assistant can speak with: preset voices from Cartesia, ElevenLabs and Gradium, plus the voices you cloned.
- Phone Numbers3 endpoints
Your organization's phone numbers: the caller ID of outbound calls, and the assistant that answers inbound calls on each number.
- Users1 endpoint
The user the API key belongs to.
- Usage1 endpoint
What your organization consumed: credits (1 credit = 1 worked contact), calls and time on the line, over any period and per assistant and campaign, with the balance and the date it runs out at the recent pace.