Skip to main content
POST
/
webhooks
/
calls
Upload a call
curl --request POST \
  --url https://api.zelto.ai/webhooks/calls \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "call": {
    "externalId": "<string>",
    "startedAt": "2023-11-07T05:31:56Z",
    "endedAt": "2023-11-07T05:31:56Z",
    "durationSeconds": 1,
    "endedReason": "<string>",
    "cost": 1,
    "recordingUrl": "<string>",
    "customer": {
      "number": "<string>",
      "name": "<string>"
    }
  },
  "agent": {
    "externalId": "<string>",
    "name": "<string>"
  },
  "agentId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "version": "<string>",
  "systemPrompt": "<string>",
  "metadata": {}
}
'
{
  "received": true
}

Authorizations

Authorization
string
header
required

Send Authorization: Bearer YOUR_API_KEY. The key resolves to a single organization.

Headers

X-Zelto-Provider
enum<string>
default:zelto

Which schema the request body uses. Defaults to zelto (the canonical CallIngest shape, also used by livekit). Native vapi / retell webhook payloads are also accepted.

Available options:
zelto,
vapi,
retell,
livekit

Body

application/json

When X-Zelto-Provider is zelto (or omitted), the canonical CallIngest body. When vapi / retell, that provider's native webhook payload.

Zelto's canonical call upload shape (X-Zelto-Provider: zelto). Provide either agent.externalId (find-or-create) or agentId (attach to an existing agent).

call
object
required
agent
object

Find-or-create an agent by your own id. Required unless agentId is given.

agentId
string<uuid>

Attach to an existing Zelto agent. Takes precedence over agent.externalId.

version
string

Version label for the agent build that handled this call (e.g. v3 or a prompt hash). Recorded as the call's agent version so analytics can segment by it. Optional; wins over any rotating-id derivation when both apply.

Required string length: 1 - 255
transcript
object
systemPrompt
string

Agent system prompt. A leading system transcript turn is used if this is omitted.

metadata
object

Free-form metadata stored on the conversation.

Response

Accepted for processing. Also returned for duplicate deliveries and dropped (non-terminal) events.

received
boolean
required