April 2026
6 min read
Share article

Vapi End-of-Call Report Webhook: Setup, Payload, and Production Use (2026)

Vapi end-of-call report webhook setup and payload

The end-of-call report is where most of the useful data from a Vapi call actually lives. The full transcript, a GPT-summarized version of the conversation, any structured data you asked the model to extract, the recording URL, the cost breakdown, and all the metadata about the call arrive in a single webhook fired once when the call ends. This guide covers the exact payload structure and what to do with each field.

When the End-of-Call Report Fires

The webhook fires once, roughly 5 to 15 seconds after the call ends. The delay is because Vapi runs the summary generation and structured data extraction via the LLM after the call terminates. The webhook does not fire for calls that failed to connect or dropped before any conversation happened, though you can configure it to fire on those edge cases via the serverUrl events configuration.

Setting It Up

The server URL and event subscription can be set at three levels: org-wide, per-assistant, or per-phone-number. For most builds, set it at the assistant level so different assistants can send to different webhooks. In the Vapi dashboard, open the assistant, scroll to the Advanced section, and set Server URL to your n8n or custom backend endpoint. In the Server URL Events list, enable end-of-call-report.

The webhook should respond with a 200 status within 20 seconds or Vapi will retry up to 3 times with exponential backoff. Keep your end-of-call handler fast by doing heavy work asynchronously (push to a queue, return 200 immediately).

The Payload Structure

The payload is an object with a message property containing type (end-of-call-report), endedReason (why the call ended), recordingUrl (signed URL to the audio), stereoRecordingUrl (two-track audio with separate caller/agent channels), summary (LLM-generated call summary), transcript (full text transcript with speaker labels), structuredData (any fields you configured the model to extract), analysis (higher-level analysis object with successEvaluation), cost (total and per-provider breakdown), costBreakdown (detailed cost array), durationSeconds, and a call object with IDs and metadata.

The endedReason Field

This tells you why the call ended. Common values: customer-ended-call (hung up normally), assistant-ended-call (assistant said goodbye and ended), silence-timed-out (caller went silent too long), customer-did-not-answer (outbound only), pipeline-error (something broke). Branch your workflow on this field. A customer-ended-call that happened after a booking was confirmed is a success. A silence-timed-out after 3 turns is probably a bug in your silence threshold.

Typical endedReason Distribution in Production

customer-ended-call (normal hangup)62%
assistant-ended-call (agent completed flow)22%
silence-timed-out9%
customer-did-not-answer (outbound)4%
pipeline-error or other3%

Using Structured Data Extraction

The structuredData field is populated by asking the LLM to extract specific fields from the transcript after the call. Configure this in the assistant's Analysis Plan. Define a JSON schema of fields you want extracted (e.g., appointmentDate, serviceRequested, callerName, desiredOutcome), and Vapi runs an LLM pass to populate them.

This is far more reliable than trying to extract fields mid-call with tool calls because the LLM has the full conversation context when it does the extraction. Use it for anything that does not need to happen mid-call: lead qualification, sentiment tagging, appointment details, follow-up flags.

Using the Success Evaluator

The analysis object contains a successEvaluation field that runs after the call to judge whether the call succeeded against criteria you define. You configure the success rubric (e.g., "Return true if the caller booked an appointment, false otherwise"), and Vapi returns a boolean or structured response.

This is excellent for dashboards and alerting. Track the rate of successful calls over time. When it drops, something changed in your prompt, your knowledge base, or your tool calls. Investigate immediately.

What to Do With the Report in n8n

The end-of-call handler is usually the biggest n8n workflow in a voice agent build. Typical pattern: parse the payload, branch on endedReason and successEvaluation. For successful bookings, sync to CRM (HubSpot, GoHighLevel, Airtable), send SMS confirmation to caller, notify business owner in Slack, kick off the reminder sequence. For unsuccessful calls, log the failure, flag for review, optionally trigger a follow-up outreach.

Log every single call regardless of outcome to a persistent store. The transcript and structured data are invaluable when a customer later disputes what was said or when you need to debug a pattern of failures.

Recording URLs and Expiration

The recording URL is a signed URL that expires. If you want long-term access, download the recording immediately when the end-of-call webhook fires and store it in your own infrastructure. A common pattern is an n8n HTTP Request node that downloads the recording and pushes it to S3 or Google Cloud Storage.

Cost Tracking

The costBreakdown array shows exactly what each provider charged for that specific call. This is gold for unit economics. Append every call's cost breakdown to a database so you can build real dashboards of cost per call, cost per successful outcome, and cost per provider. If one provider's cost spikes, you see it immediately.

Retry Logic and Idempotency

Vapi retries failed end-of-call webhooks up to 3 times. If your handler is not idempotent, a retry can double-book appointments or send duplicate SMS. Use the call.id as an idempotency key. At the start of your handler, check whether you have already processed this call.id and return early if so.

Downstream Actions Triggered by End-of-Call Payload

Log transcript + metadata to database100%
Sync structured data to CRM88%
Send SMS confirmation to caller72%
Alert staff in Slack on specific outcomes65%
Download recording to long-term storage58%

Common Mistakes

Not validating the payload signature or secret header. The endpoint is public; without validation, someone can POST fake end-of-call reports and trigger your downstream actions. Not handling retries idempotently. Parsing structured data without checking if the field exists (the LLM sometimes omits fields it cannot confidently extract). Relying on the recording URL more than 7 days later; signed URLs expire.

The end-of-call report is probably the most important webhook in your Vapi stack. Invest in it. Log everything, handle errors gracefully, and version the schema so you can evolve it over time.

Community & Training

Join 215+ AI Agency Owners

Get free access to our all-in-one outreach platform, AI content templates, and a community of builders landing clients in days.

Access the Free Sprint
22 people joined this week