Places an outbound call from a number in your workspace to any phone number. The call is created in the registered state and the dial starts in the background. Track its progress with Get call, the call stream or your webhooks.
The agent is the override_agent_id you pass, or a weighted pick from the outbound_agents of from_number.
Request#
Body#
| Field | Type | Required | Description |
|---|---|---|---|
from_number |
string | Yes | Number that places the call, in E.164 format. It must be a phone number in this workspace. |
to_number |
string | Yes | Number to call. Must match E.164 (^\+[1-9]\d{6,14}$) unless ignore_e164_validation is true. |
override_agent_id |
string | No | Agent to use for this call. When omitted, one agent is picked from the number's outbound_agents by weight. |
override_agent_version |
integer or string | No | Agent version to use. A number, or on this path a version reference: latest, latest_published or an environment tag name such as prod. When omitted and the number has an outbound version binding, the binding's reference is used. When omitted otherwise, the latest version runs. |
retell_llm_dynamic_variables |
object | No | Values for {{variables}} in the prompt. Non-string values are stored as JSON strings. Default {}. |
metadata |
object | No | Any JSON you want stored on the call and sent back in webhooks. Default {}. |
custom_sip_headers |
object | No | Extra SIP headers on the outbound INVITE, as { "X-Header": "value" }. Names must be HTTP token characters. Values can use {{dynamic_variables}}; line breaks are replaced with spaces. |
honor_internal_dnc |
boolean | No | When true, refuse to dial a number whose contact is flagged do-not-call. Default false. |
idempotency_key |
string | No | 1 to 200 characters. A second request with the same key within 1 hour returns the first call instead of dialling again. |
ignore_e164_validation |
boolean | No | Skip the E.164 check on to_number. Default false. |
agent_override |
object | No | Per-call configuration merged over the stored agent and engine. See agent_override. |
agent_override#
| Field | Type | Description |
|---|---|---|
agent |
object | Agent fields to override for this call, using the field names of Create agent. ring_duration_ms here sets how long the destination rings. |
retell_llm |
object | Response engine fields to override, using the field names of Create Retell LLM. |
conversation_flow |
object | Flow fields to override, using the field names of Create conversation flow. |
The override objects are stored on the call as given and applied when the runtime loads the call. They are not validated against the agent schema at request time.
Environment tags and pre-call workflows#
When override_agent_version (or the number's binding) names an environment tag, the call's metadata.environment_tag is set to the tag name and the tag's dynamic variables apply below the request's own variables. If the agent has a pre-call workflow, its outputs are merged into retell_llm_dynamic_variables before the call is created.
Example request#
curl -X POST "https://api.tried.com.au/v2/create-phone-call" \
-H "Authorization: Bearer $TRIED_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from_number": "+61291234567",
"to_number": "+61412345678",
"override_agent_id": "agent_3f9a1c0b2d4e5f6a7b8c9d0e",
"retell_llm_dynamic_variables": {
"customer_name": "Sam",
"appointment_time": "2:30 pm Thursday"
},
"metadata": {
"crm_id": "A-1042"
},
"idempotency_key": "reminder-A-1042-2026-10-21"
}'const res = await fetch("https://api.tried.com.au/v2/create-phone-call", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TRIED_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"from_number": "+61291234567",
"to_number": "+61412345678",
"override_agent_id": "agent_3f9a1c0b2d4e5f6a7b8c9d0e",
"retell_llm_dynamic_variables": {
"customer_name": "Sam",
"appointment_time": "2:30 pm Thursday"
},
"metadata": {
"crm_id": "A-1042"
},
"idempotency_key": "reminder-A-1042-2026-10-21"
}),
});
const data = await res.json();import os, requests
res = requests.post(
"https://api.tried.com.au/v2/create-phone-call",
headers={"Authorization": f"Bearer {os.environ['TRIED_API_KEY']}"},
json={
"from_number": "+61291234567",
"to_number": "+61412345678",
"override_agent_id": "agent_3f9a1c0b2d4e5f6a7b8c9d0e",
"retell_llm_dynamic_variables": {
"customer_name": "Sam",
"appointment_time": "2:30 pm Thursday",
},
"metadata": {
"crm_id": "A-1042",
},
"idempotency_key": "reminder-A-1042-2026-10-21",
},
)
data = res.json()Response#
201 Created with the call object. The call starts in registered and moves to ongoing when the callee answers.
{
"call_id": "call_8d1e0f2a3b4c5d6e7f8a9b0c",
"call_type": "phone_call",
"agent_id": "agent_3f9a1c0b2d4e5f6a7b8c9d0e",
"agent_version": 4,
"agent_name": "Appointment reminders",
"call_status": "registered",
"direction": "outbound",
"from_number": "+61291234567",
"to_number": "+61412345678",
"metadata": { "crm_id": "A-1042" },
"retell_llm_dynamic_variables": { "customer_name": "Sam", "appointment_time": "2:30 pm Thursday" },
"collected_dynamic_variables": {},
"start_timestamp": null,
"end_timestamp": null,
"duration_ms": null,
"transcript": "",
"transcript_object": [],
"transcript_with_tool_calls": [],
"recording_url": null,
"recording_multi_channel_url": null,
"public_log_url": null,
"knowledge_base_retrieved_contents_url": null,
"transfer_destination": null,
"llm_token_usage": null,
"disconnection_reason": null,
"call_analysis": null,
"latency": {},
"call_cost": null,
"batch_call_id": null,
"contact_id": "contact_5a6b7c8d9e0f1a2b3c4d5e6f"
}If the dial fails before the call is handed to telephony, the call is stored with call_status: "error" and disconnection_reason: "dial_failed", and the request returns 500.
Errors#
| Status | When |
|---|---|
400 |
Validation failed, to_number is not E.164, to_number is outside the number's allowed_outbound_country_list, the number has no outbound agent and no override_agent_id, a custom SIP header name is invalid, the destination is on the do-not-call list (honor_internal_dnc), or a version reference is unknown. |
401 |
Missing or invalid API key. |
402 |
Credit exhausted, monthly budget reached, or an invoice is overdue. The body includes error_code (credit_exhausted, budget_reached, invoice_overdue). |
403 |
The key's IP allowlist or scopes reject the request. This route needs the calls scope. Business verification (KYC) is not approved, or the account needs verification before outbound calls (error_code: "verification_needed"). |
404 |
from_number is not a number in this workspace, or the agent or version does not exist. |
409 |
A request with the same idempotency_key is still being processed. |
429 |
Rate limit exceeded. See Rate limits. The workspace concurrency limit or the number's CPS limit is reached. |
500 |
The dial could not be placed. |
See Errors for the body format.
Compatibility notes#
POST /create-phone-call is an alias that runs the same handler but skips version reference resolution, the budget and account state checks and pre-call workflows (the credit balance check still runs), so override_agent_version must be a number there.