Setup
Add ananalysis config to your agent:
Analysis Options
Event flow
A singlecall.ended webhook fires once post-call processing finishes — after the recording is persisted and analysis completes (~2-5s). It carries everything inline: transcript, recording, summary, and the full analysis, plus status, a derived ended_reason, and any metadata you set at call-init.
There is no separate analysis.completed event — the analysis is part of the call.ended payload. If you need the results before the webhook, poll the Get Analysis endpoint below.
TurnCall gates call.ended on both the recording and the analysis being ready:
- Analysis runs first, in parallel with the recording upload that started when the call disconnected.
- TurnCall polls
recording_statusuntil it reachescompletedorfailed(or a 15-second timeout elapses). call.endedis dispatched once, withrecording_statusalways included andrecording_urlincluded when present.
call.ended always fires — even if the recording fails or the timeout trips, the webhook still goes out so subscribers can rely on it as the end-of-call signal. Use recording_status to tell “no recording” apart from “still pending”:
payload. Use event_id as an idempotency key — it is stable across delivery retries and shared across subscribers, so you can dedupe redeliveries. agent_id reflects the agent that handled the event (handoff-aware). In the payload, ended_reason reports why the call ended — one of customer_ended_call, assistant_ended_call, customer_did_not_answer, customer_busy, voicemail, transferred, pipeline_error, telephony_failed, or unknown — and is more granular than the coarse status. metadata echoes back the custom fields you attached at call-init for CRM correlation.
If you need the recording earlier than call.ended, subscribe to recording.ready, which fires as soon as the file lands in storage.
Fetch a Recording
Stream the WAV directly from TurnCall — useful when you don’t want to expose your object-storage URLs to clients, or when the stored URL is presigned and short-lived:404 until the recording is persisted (watch recording_status on call.ended, or subscribe to recording.ready).