Skip to main content

Start a Call

Starts an outbound call to a lead — either with a stored agent, or with an agent that exists only for this one call (an "inline"/"one-time" agent).

Endpoint​

POST /api/calls/initiate

Authentication​

Requires a valid Bearer JWT. The call is associated with the project_id from the token.

Request body​

Use exactly one of the two agent fields — never both:

FieldTypeRequiredDescription
lead_idstringyesID of the lead to call.
agent_idstringnoID of a stored agent.
agentobjectnoConfiguration for a one-time ("inline") agent. See below.

If neither is given, the call uses the phone number's default agent.

Variant A: stored agent​

{
"lead_id": "123e4567-e89b-12d3-a456-426614174000",
"agent_id": "456e7890-e89b-12d3-a456-426614174000"
}

Variant B: inline agent (one-time call)​

For a call whose script exists only for this one call — without creating, polling, and deleting an agent around it.

{
"lead_id": "123e4567-e89b-12d3-a456-426614174000",
"agent": {
"name": "One-time call: rent increase, flat 3B",
"template_agent_id": "456e7890-e89b-12d3-a456-426614174000",
"ttl_minutes": 120,
"configuration": {
"agentSettings": {
"firstMessage": "Hello, this is an AI assistant from Muster Property Management. Am I speaking with Ms. {{last_name}}?",
"prompt": "You are delivering a notice: the rent for flat 3B increases by 42 euros starting 2027-02-01. Do not answer follow-up questions — note them and say the management office will get back to her."
}
}
}
}

Fields inside agent:

FieldTypeRequiredDescription
namestringnoLabel for the CRM and logs. Defaults to a dated "One-time call …" name. Max 255 characters.
configurationobjectyes*The agent configuration. agentSettings.firstMessage and agentSettings.prompt are required — on their own without template_agent_id, or together with it (see below).
template_agent_idstringnoID of a stored agent whose configuration is the merge base. Voice, booking, transfer and provider settings carry over; only the script changes.
ttl_minutesintegernoMinutes the agent outlives the call before it is deleted. Default 120, range 5–1440. Has to outlive post-call processing (transcript, summary, outcome, webhook).

* Without template_agent_id, agentSettings.firstMessage and agentSettings.prompt must be set directly in configuration. With template_agent_id, only the keys that should change need to be sent — the rest is inherited from the template.

Behavior​

  • Mutually exclusive. Sending agent_id and agent together returns 400.
  • An inline agent is stored. Even a one-time agent is created as a real agent row, because post-call processing (summary, outcome classification, customer webhook, email notification) reads the agent configuration again. It runs through the same gate as POST /api/agents (EU AI Act disclosure in the first message, summary-prompt length limit, language permission, staff-only provider fields) — an inline agent is a shortcut, not a second door into the configuration.
  • EU AI Act disclosure: agentSettings.firstMessage must disclose that an AI assistant is speaking (e.g. "… an AI assistant from …"). Omitting it is a 400.
  • Automatic deletion (TTL): The inline agent expires after ttl_minutes and is collected by a background reaper. While it exists it does not show up in the agent list and does not count against the AI-assistant plan limit.
  • template_agent_id: The template's configuration is the merge base; the request's configuration is merged over it key by key. An explicit JSON null removes an inherited block (e.g. to turn off booking or transfer for this one call). Voice, booking, transfer, provider settings and the after-call email notification are inherited along with it.
  • A failed dial attempt leaves the inline agent to expire rather than deleting it immediately — an error here doesn't prove nothing was dialed.

Success response​

{
"success": true,
"message": "Call initiated successfully",
"provider_call_id": "call-id-123",
"agent_id": "9f1c0f7e-2a44-4f9e-9a0b-2b7c1d3e4f50"
}

agent_id is only present for an inline agent — it is the id of the one-time agent that was minted. Use it to attribute the call activity, or to delete it yourself instead of waiting for expiry. With a stored agent_id or the default agent, this field is omitted from the response.

Error responses​

Both agent_id and agent sent

{
"success": false,
"message": "Send either agent_id or agent, not both: agent_id names a stored agent, agent defines a one-time one.",
"provider_call_id": null
}

Missing EU AI Act disclosure in the first message

{
"success": false,
"message": "First message must disclose that the caller is an AI (EU AI Act Art. 50). Add an AI disclosure to the start of the agent's first message, e.g. '… ein KI-Assistent von …' or '… an AI assistant from …'.",
"agent": null
}

agentSettings.firstMessage or agentSettings.prompt missing

{
"success": false,
"message": "agent.configuration.agentSettings.prompt is required and must not be empty",
"provider_call_id": null
}

Unknown template_agent_id

{
"success": false,
"message": "template_agent_id 456e7890-e89b-12d3-a456-426614174000 not found in this project",
"provider_call_id": null
}

Insufficient balance / not enough minutes

{
"success": false,
"message": "Insufficient minutes to start this call",
"provider_call_id": null
}

Database or provider error

{
"success": false,
"message": "Failed to initiate call: ...",
"provider_call_id": null
}