call.completed
The event carrying a finished call's analysis.
Delivered when a call finishes processing.
{
"event": "call.completed",
"occurred_at": "2026-08-05T09:24:11Z",
"delivery": { "idempotency_key": "3f9a1c22-...", "attempt": 1 },
"data": {
"call": {
"reference": "cl_7Yx2bQ...",
"provider": "your-dialler",
"provider_call_id": "CALL-88213",
"idempotency_key": "CALL-88213",
"status": "completed",
"direction": "outbound",
"started_at": "2026-08-05T09:14:00Z",
"ended_at": "2026-08-05T09:21:33Z",
"duration_ms": 453000,
"counterparty_e164": "+441234567890",
"language_profile": "en-GB",
"speaker_count": 2
},
"analysis": {
"version": 1,
"summary": "…",
"sentiment": "positive",
"sentiment_score": 0.62,
"customer_intent": "…",
"decision_maker": "…",
"budget_state": "…",
"timeline_state": "…",
"outcome": "…",
"risk_level": "low",
"confidence": 0.81
}
}
}Four things to get right
Deduplicate on delivery.idempotency_key, never on a hash of the body. delivery.attempt
changes between retries, so the body changes too. Hashing it makes every retry look like a new
event.
delivery.idempotency_key and data.call.idempotency_key are different fields. The first is
ours and identifies the event. The second is yours, echoed back. See
correlation identifiers.
analysis is null, never {}, when no analysis was produced. You must be able to tell "no
analysis for this call" from "the analysis was empty". This is reachable on a call whose status is
completed.
data.call.reference is the call's identifier. It is opaque and stable, and it is scoped to
your organization. Call Lens does not expose internal numeric identifiers on any surface.
Fields
| Field | Type | Notes |
|---|---|---|
event | string | Always call.completed. |
occurred_at | string | ISO 8601. |
delivery.idempotency_key | string | Deduplicate on this. |
delivery.attempt | integer | 1-based. Changes between retries. |
data.call.reference | string | Opaque, stable, per-organization. |
data.call.provider | string | null | Echoed from your submission. |
data.call.provider_call_id | string | null | Echoed verbatim. |
data.call.idempotency_key | string | null | Echoed verbatim. |
data.call.status | string | Terminal status. |
data.call.direction | string | null | inbound, outbound, unknown. |
data.call.started_at | string | null | ISO 8601. |
data.call.ended_at | string | null | ISO 8601. |
data.call.duration_ms | integer | null | Measured, falling back to what you reported. |
data.call.counterparty_e164 | string | null | |
data.call.language_profile | string | null | |
data.call.speaker_count | integer | null | |
data.analysis | object | null | null when no analysis exists. |
data.analysis.summary | string | null | Model-generated. Unredacted — see overview. |
data.analysis.sentiment | string | null | |
data.analysis.sentiment_score | number | null | |
data.analysis.customer_intent | string | null | |
data.analysis.decision_maker | string | null | |
data.analysis.budget_state | string | null | |
data.analysis.timeline_state | string | null | |
data.analysis.outcome | string | null | |
data.analysis.risk_level | string | null | |
data.analysis.confidence | number | null |