API reference
Calls
Place an outbound call with an agent, schedule it, and stop it.
A call request creates an execution: the record of one call, with its status, transcript, costs and telephony details. The request returns as soon as the execution is queued; a worker then dials and runs the conversation. Read the result with the Executions routes or receive it on the agent's webhook.
Both routes need Authorization: Bearer <key>. Errors use the standard body {"error": <status>, "message": "..."}.
| Operation | Method and path |
|---|---|
| Make a call | POST /call |
| Stop a call | POST /call/{execution_id}/stop |
Engines and test numbers
Each call runs on an engine. The engine is taken from agent_data.engine, then from the agent's agent_config.engine, then from the platform default (DEFAULT_ENGINE, which is mock unless the operator changes it).
| Engine | What it does |
|---|---|
mock | A deterministic simulation. No phone rings. The whole lifecycle runs: statuses, transcript, costs, logs, webhooks and a playable recording made of tones. |
own | The platform's own voice engine. It needs a telephony provider and speech and language models configured by the operator. |
oss | Open-source engine (optional). A third-party open-source voice engine that the operator can run next to the platform. Available only where the operator has set it up; otherwise the call ends failed with OSS_ENGINE_WS_URL is not configured. The id this engine had before October 2026 is still accepted and is stored as oss. |
On the mock engine the last four digits of recipient_phone_number choose the outcome.
| Number ends in | Outcome |
|---|---|
0000 | no-answer |
1111 | busy |
2222 | failed, with error_message Mock telephony failure |
3333 | Voicemail. The call ends with answered_by_voice_mail set to true, unless the agent's task_config.voicemail is false. |
| anything else | A conversation that ends completed |
In a simulated conversation the caller's lines come from agent_data.mock_script, an array of strings. Without it the caller says three stock lines. agent_data.mock_tool_calls scripts function tool calls: [{"turn": 1, "name": "...", "arguments": {...}}]. Keys of agent_data that start with mock_ are never passed to a live engine.
Note: Mock calls run faster than real time by default (
MOCK_TIME_SCALE). See Testing without a phone.
Operations
Make a call
POST /call
Queues an outbound call from an agent to one phone number, now or at a scheduled time.
Auth: API key or session token. Role: member and up. When the operator sets REQUIRE_VERIFIED_EMAIL, the login must have a verified email address.
This route accepts an Idempotency-Key header: a retry with the same key and body returns the first response instead of placing a second call. See Idempotency. It is also one of the routes with the lower rate limit; see Rate limits.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key | header | string | no | 1 to 200 printable ASCII characters. |
agent_id | body | string (UUID) | yes | The agent that makes the call. |
recipient_phone_number | body | string | yes | E.164, for example +919876500012. |
from_phone_number | body | string | no | Caller ID in E.164. |
scheduled_at | body | string | no | ISO 8601 timestamp with a UTC offset (Z is accepted), no sooner than 2 minutes from now. |
user_data | body | object | no | Values for the placeholders in the welcome message and prompts. |
agent_data | body | object | no | Per-call options: engine, webhook_url (overrides the agent's webhook for this call), mock_script, mock_tool_calls. |
retry_config | body | object | no | Automatic retries. See below. |
bypass_call_guardrails | body | boolean | no | Ignore the agent's calling hours. Default false. |
retry_config fields and defaults:
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Turn retries on. |
max_retries | integer | 3 | Capped at 3. |
retry_on_statuses | array | ["no-answer", "busy", "failed"] | Final statuses that trigger a retry. |
retry_on_voicemail | boolean | false | Retry when voicemail answered. |
retry_intervals_minutes | array | [30, 60, 120] | Wait before each retry. |
A retried call keeps the same execution id.
Request
curl -X POST https://api.sevennadi.si/call \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: renewal-2026-10-13-asha" \
-d '{
"agent_id": "f412f2b1-3493-4458-bcf2-8676cc798edd",
"recipient_phone_number": "+919876500012",
"from_phone_number": "+918045550100",
"user_data": {"name": "Asha"},
"agent_data": {"engine": "mock", "mock_script": ["Yes, speaking.", "Please renew it. Thank you, bye!"]}
}'Response 200 OK
{
"message": "done",
"status": "queued",
"execution_id": "0b6c2c4e-7a55-4b0f-9a07-3d6b1f9f2a11"
}status in this response is always queued. The execution itself starts as queued, scheduled (when you sent scheduled_at) or rescheduled (when the time falls outside the agent's calling hours). In the last case the response also carries "rescheduled": true and the new scheduled_at. A warnings array is added when the call is allowed but worth a look, for example a number found on a do-not-disturb registry while the account's dnd_check is warn.
Errors
| Status | Message |
|---|---|
| 400 | agent_id is required |
| 400 | recipient_phone_number is required |
| 400 | recipient_phone_number must be in E.164 format, e.g. +919876543210 |
| 400 | Invalid from_phone_number |
| 400 | scheduled_at must be an ISO 8601 timestamp with a UTC offset |
| 400 | scheduled_at must include a UTC offset, e.g. +00:00 |
| 400 | Scheduled time should be at least 2 minutes in the future |
| 400 | Call not placed: suppressed: the number is on the account's do-not-call list |
| 400 | Call not placed: dnd: the number is on a do-not-disturb registry |
| 403 | Trial accounts can only call verified phone numbers. Verify <numbers> before calling. |
| 403 | Verify your email address first (Settings → Security, or the link we emailed you). |
| 404 | Agent not found |
| 409 | This Idempotency-Key was already used with a different request |
| 429 | Call not placed: frequency cap: already <n> outbound attempts to this number today |
| 429 | Too many requests. Back off and retry with exponential backoff. |
Some problems appear only after the request has been accepted. An account without enough balance gets an execution that ends in balance-low with error_message Insufficient wallet balance. The do-not-call list, the frequency cap and verified numbers are covered in Compliance and Verified numbers.
Stop a call
POST /call/{execution_id}/stop
Stops one call. A call that has not been dialed yet (scheduled, prepared, queued, rescheduled) becomes stopped at once. A call in progress is hung up by its worker shortly after; its transcript and costs up to that point are kept.
Auth: API key or session token. Role: member and up.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
execution_id | path | string (UUID) | yes | The execution returned by Make a call. |
Request
curl -X POST https://api.sevennadi.si/call/0b6c2c4e-7a55-4b0f-9a07-3d6b1f9f2a11/stop \
-H "Authorization: Bearer vk-0123456789abcdef0123456789abcdef"Response 200 OK
{
"message": "done",
"status": "stopped",
"execution_id": "0b6c2c4e-7a55-4b0f-9a07-3d6b1f9f2a11"
}For a call in progress the response says stopped before the execution reaches that status. Poll the execution or wait for the webhook to confirm.
Errors
| Status | Message |
|---|---|
| 400 | Execution is already <status> (the call has finished, or is in call-disconnected) |
| 404 | Execution not found |
Related
- To stop every waiting call of an agent, use Stop an agent's waiting calls.
- To call a list of contacts, use Batches.
- To test an agent by voice from a browser, see Voice test.