Place an AI call
POST /
Asks an existing outbound AI agent to call one lead once.
Scope: calls:write
Access: The key's member needs the Manual call permission in the agent's campaign and must be able to see the lead; creating the lead by phone also needs permission to manage that campaign's leads.
The caller owns when to call. The call is placed by the agent you name, in its normal outbound mode with its own first message and prompt, exactly as when the campaign calls a lead; it is not treated as a callback. The agent must be an enabled outbound voice agent in a campaign the key may reach (otherwise 404), and that campaign is the call's campaign.
Name the lead with lead_id (a lead in the agent's campaign) or with phone. With phone, the campaign's lead with that number is called as it is; if there is none, it is created exactly as POST /v1/leads creates it, before the call is checked, so a call that is then refused still leaves the new lead behind. To send more details, create or update the lead first and call it by lead_id.
Every call goes through DialEcho's existing automated-call checks, when you send the request and again right before dialing: a number on the do-not-call list or one that cannot be called is refused with 409, and outside the lead's calling hours the call is accepted as scheduled and starts at scheduled_for without another request from you. Once a call is requested for a lead, the campaign's own automated dialing leaves that lead alone.
Idempotency-Key is required so retries never dial a person twice: DialEcho places at most one call per key. The same request with the same key returns the same call_id with the call's current status, as long as the key's member may still see the lead; otherwise it is 404 not_found, as a new request for that lead would be. Derive the key from what the call is for, for example info-form:<lead_id>, so one event can never cause two calls. Every request, replays included, also draws from the per-key call limit.
Headers
| Name | Type | Required | Description |
|---|---|---|---|
Idempotency-Key | string | Yes | Identifies this call for your API key. Reusing it with a different body is 409 idempotency_conflict. 16 to 128 printable ASCII characters, no spaces. |
Body
Content type: application/json
| Name | Type | Required | Description |
|---|---|---|---|
agent_id | UUID | Yes | An enabled outbound voice agent. |
lead_id | UUID | No | A lead in the agent's campaign, for example the lead_id POST /v1/leads returned. Send exactly one of lead_id or phone. |
phone | string | No | Normalized to E.164 like POST /v1/leads. Send exactly one of lead_id or phone. Up to 40 characters. |
first_name | string | No | Only with phone; used only when the lead is created. Up to 100 characters. |
last_name | string | No | Only with phone; used only when the lead is created. Up to 100 characters. |
email | string | No | Only with phone; used only when the lead is created. A valid email address, up to 254 characters. |
Response
Status: 202 Accepted
A new request always answers queued or scheduled. The other statuses are what a replay of the same request reports once the call has moved on. Responses never contain the lead's personal data.
| Name | Type | Description |
|---|---|---|
call_id | UUID | The call; the same value on every replay. |
lead_id | UUID | The lead being called. |
status | string | queued: starting now (normally within seconds). scheduled: outside calling hours, starts at scheduled_for. dialing: placed. completed: answered. no_answer: not answered, busy or voicemail; not retried. failed: could not be placed (for example the checks before dialing refused it), or DialEcho restarted while starting it and it is never dialed again. canceled: canceled in DialEcho before it was placed. One of queued, scheduled, dialing, completed, no_answer, failed, canceled. |
scheduled_for | timestamp | Only present when status is scheduled: when the call starts (RFC 3339, UTC). |
Example request
curl
bash
curl -X POST "https://development.agencydevworks.ai/v1/calls" \
-H "Authorization: Bearer dei_your_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: info-form:aaaaaaaa-0000-4000-8000-000000000001" \
-d '{
"agent_id": "99999999-0000-4000-8000-000000000001",
"lead_id": "aaaaaaaa-0000-4000-8000-000000000001"
}'JavaScript
js
const response = await fetch("https://development.agencydevworks.ai/v1/calls", {
method: "POST",
headers: {
"Authorization": "Bearer dei_your_key",
"Content-Type": "application/json",
"Idempotency-Key": "info-form:aaaaaaaa-0000-4000-8000-000000000001",
},
body: JSON.stringify({
"agent_id": "99999999-0000-4000-8000-000000000001",
"lead_id": "aaaaaaaa-0000-4000-8000-000000000001"
}),
});
const data = await response.json();Example response
Status: 202 Accepted
json
{
"call_id": "33333333-0000-4000-8000-000000000001",
"lead_id": "aaaaaaaa-0000-4000-8000-000000000001",
"status": "scheduled",
"scheduled_for": "2026-11-02T14:00:00Z"
}Errors
| HTTP | Code | When |
|---|---|---|
| 403 | insufficient_scope | The key does not have calls:write. |
| 403 | permission_denied | The key's member may not place AI calls in the agent's campaign, or (with phone) may not manage its leads. |
| 404 | not_found | The agent does not exist, is not an enabled outbound agent or is outside the key's campaigns, or the lead is not in the agent's campaign or the member cannot see it (a replay of an earlier request included). |
| 409 | do_not_call | The number is on the do-not-call list. Final; do not retry. |
| 409 | invalid_phone | The lead's number cannot be called. Final; do not retry. |
| 409 | not_callable | The lead is outside calling hours and no later calling window can be found. |
| 409 | idempotency_conflict | The Idempotency-Key was already used for a different request. Nothing was dialed. |
| 413 | payload_too_large | The body is larger than 1 MB. It was not read and nothing was dialed. |
| 422 | invalid_request | The body or header is invalid: a missing or malformed Idempotency-Key, unknown fields, an invalid phone or email, or not exactly one of lead_id and phone (or names sent with lead_id), which is reported as field body. |
| 503 | dependency_unavailable | The do-not-call list or the campaign's calling-hours settings cannot be read right now. Nothing was placed; retry with the same Idempotency-Key. |
Every endpoint can also answer 401 invalid_api_key, 429 rate_limited and 503 dependency_unavailable. See Errors in the overview.
Related endpoints
- POST
/· Create or update a leadv1/ leads - GET
/· Retrieve a conversionv1/ leads/ {lead_id}/ conversion