ConvoiAi
Browse docs

Calls

Create a Call

Try this API

Start a web call or an outbound phone call from a single endpoint, set type to "web" or "outbound_phone".

7 min read

Endpoint

http
POST /api/v1/public/calls

A single endpoint creates both call types. Set type to "web" to connect a browser participant to a Convoi agent over LiveKit, or "outbound_phone" to dial an E.164 number from one of your provisioned Convoi numbers.

Headers

Optional: include an Idempotency-Key header (any random UUID) to make this POST safe to retry within a 24-hour window. Repeating the same key returns the original call instead of creating a duplicate.

http
Idempotency-Key: 6f1c4b7e-… (any UUID)

Web call: minimal

Set type to "web" and provide an agent_id (the agent that will run the call). Convoi provisions a LiveKit room, mints a participant token, and returns both in the response.

json
{
  "type": "web",
  "agent_id": "agt_b88d642dd68747f28305c428b209xxxx"
}

Web call: with overrides

agent_overrides lets you tweak the agent's first message, system prompt, or any LLM/TTS/STT setting for this call only, without editing the agent itself.

json
{
  "type": "web",
  "agent_id": "agt_b88d642dd68747f28305c428b209xxxx",
  "participant_name": "xyz",
  "agent_overrides": {
    "first_message": "Hi, how can I help?",
    "system_prompt": "You are a concise support agent.",
    "llm":  { "model": "gpt-4o-mini", "temperature": 0.7 },
    "tts":  { "voice_id": "rachel", "speed": 1.0 },
    "stt":  { "language": "en", "model": "nova-2" },
    "knowledge_base_ids": ["kb_3a1c…32hex…"]
  },
  "metadata": { "source": "landing-page", "user_ref": "u_42" }
}
FieldTypeRequiredNotes
typestringyesMust be "web".
agent_idstringyesAn agent on your account.
participant_namestringnoDisplay name for the participant in LiveKit.
agent_overridesobjectnoPer-call overrides: first_message, system_prompt, llm, tts, stt, knowledge_base_ids.
metadataobjectnoFree-form key/value pairs returned with every call event.

Web call: response

json
{
  "id": "call_01HX…",
  "object": "call",
  "type": "web",
  "status": "initiated",
  "agent_id": "agt_…",
  "room_id": "…",
  "livekit": {
    "url": "wss://your-livekit-host",
    "token": "eyJhbGciOi…",
    "participant_identity": "public-…"
  },
  "duration_seconds": 0.0,
  "cost": { "amount": 0.0, "currency": "USD" },
  "metadata": { "source": "landing-page" },
  "created_at": "...",
  "updated_at": "..."
}

Pass livekit.url and livekit.token to the LiveKit client SDK in your browser to join the call. The agent joins automatically as soon as the participant connects. duration_seconds and cost.amount update as the call progresses.

Outbound phone call: minimal

Set type to "outbound_phone" and provide the destination number, the Convoi-managed phone_number_id to dial from, and the agent that should run the call.

json
{
  "type": "outbound_phone",
  "agent_id": "agt_b88d642dd68747f28305c428b209xxxx",
  "customer": { "number": "+92310000053", "name": "xyz" },
  "phone_number_id": "phn_c38155f043624745a66d2e28c185xxxx"
}

Outbound phone call: full

json
{
  "type": "outbound_phone",
  "agent_id": "agt_b88d642dd68747f28305c428b209xxxx",
  "customer": {
    "number": "+0000000",
    "name": "xyz",
    "metadata": { "lead_id": "L-12345" }
  },
  "phone_number_id": "phn_c38155f043624745a66d2e28c185xxxx",
  "agent_overrides": {
    "first_message": "Hi Wasay, this is a quick callback from Convoi."
  },
  "metadata": { "campaign": "may-outreach" }
}
FieldTypeRequiredNotes
typestringyesMust be "outbound_phone".
agent_idstringyes*An agent id (agt_…) or a workforce id (sqd_…). *Provide either agent_id or squad_id.
squad_idstringnoAlternative place to pass a workforce id (sqd_…).
phone_number_idstringyesID of one of your Convoi-managed numbers.
customer.numberstringyesE.164 (e.g. +971501234567).
customer.namestringnoDisplay name for transcripts and dashboards.
customer.metadataobjectnoFree-form per-customer attributes.
agent_overridesobjectnoPer-call overrides: first_message, system_prompt, llm, tts, stt, knowledge_base_ids.
metadataobjectnoFree-form per-call attributes.

Outbound phone call: with a Workforce

A Workforce is a squad of agents that hand off to each other during a call. To place an outbound call handled by a Workforce, use the exact same request shape as a single-agent call, no body changes required. Wherever you pass an agent id (agt_…), you can pass a workforce id (sqd_…) instead, the API tells them apart by their prefix. You can also pass it explicitly in the squad_id field.

bashDial a workforce
curl -X POST https://go.convoi.ai/backend/api/v1/public/calls \
  -H "Authorization: Bearer sk_live_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 7c1f8e9a-..." \
  -d '{
    "type": "outbound_phone",
    "agent_id": "sqd_3fa85f6457174562b3fc2c963f66afa6",
    "customer": { "number": "+9715XXXXXXXX", "name": "Ahmed" },
    "phone_number_id": "phn_9b2c..."
  }'

The call starts with the workforce's start agent, then hands off between members automatically as the conversation requires. Sending customer.name substitutes {name} / {contact_name} placeholders in the greeting, so the call opens with e.g. "Hi Ahmed, …". If omitted, it falls back to "there".

jsonExample response (201 Created)
{
  "id": "call_8a7d...",
  "object": "call",
  "type": "outbound_phone",
  "status": "initiated",
  "agent_id": null,
  "squad_id": "sqd_3fa85f6457174562b3fc2c963f66afa6",
  "phone_number_id": "phn_9b2c...",
  "customer": { "number": "+9715XXXXXXXX" },
  "room_id": "…",
  "created_at": "2026-06-05T10:00:00Z",
  "updated_at": "2026-06-05T10:00:00Z"
}

Poll GET /api/v1/public/calls/{id} for live status. A single-agent call returns agent_id populated and squad_id null; a workforce call is the reverse.

  • Workforce is supported for type "outbound_phone" only. A sqd_… id sent with type "web" returns 422, web calls are single-agent.
  • Workforce calls require a private key (sk_live_…); public keys (pk_live_) are rejected with 403.
  • Idempotency: send an Idempotency-Key header; identical retries within 24h replay the original response.

Outbound phone call: response

The response mirrors the web-call response, except livekit and room_id are null. customer is populated; status begins at "initiated" and transitions through "active" → "completed" (or one of the terminal failure states). duration_seconds and cost.amount update as the call progresses.

Related in Calls