conversation.ended
The conversation ended webhook is triggered when conversation ends.
Webhook payload
Here is an example of the POST request JSON payload:
1 { 2 "event_type": "conversation.ended", 3 "data": { 4 "conversation": { 5 "id": "conv_894dcb66-c3dd-4160-8606-30387e8ab9b5", 6 "agent": { 7 "id": "agent_123", 8 "name": "Customer Support", 9 "is_deleted": false 10 }, 11 "workspace": "phonic", 12 "project": { 13 "id": "proj_8e5bdac5-868d-46fa-b397-439e777f7bfd", 14 "name": "main" 15 }, 16 "external_id": null, 17 "model": "merritt", 18 "welcome_message": "Hey, how can I help?", 19 "template_variables": {}, 20 "input_format": "pcm_44100", 21 "output_format": "pcm_44100", 22 "live_transcript": "Hey, how can I help?", 23 "post_call_transcript": null, 24 "duration_ms": 46537, 25 "background_noise_level": 0.1, 26 "background_noise": null, 27 "boosted_keywords": null, 28 "min_words_to_interrupt": 1, 29 "default_language": "en", 30 "additional_languages": [], 31 "multilingual_mode": "request", 32 "push_to_talk": false, 33 "no_input_poke_sec": null, 34 "no_input_poke_text": null, 35 "no_input_end_conversation_sec": null, 36 "audio_url": "...", 37 "started_at": "2025-07-14T11:35:40.617Z", 38 "ended_at": "2025-07-14T11:36:27.154Z", 39 "ended_by": "user", 40 "task_results": {}, 41 "items": [ 42 { 43 "item_idx": 0, 44 "role": "assistant", 45 "live_transcript": "Hey, how can I help?", 46 "voice_id": "grant", 47 "system_prompt": "Help the user to book a dentist appointment.", 48 "audio_speed": 1, 49 "duration_ms": 26.71, 50 "started_at": "2025-07-14T11:35:41.717Z", 51 "tool_calls": [] 52 } 53 ] 54 }, 55 "call_info": { 56 "from_phone_number": "+17124583766", 57 "to_phone_number": "+19189397081" 58 } 59 }, 60 "created_at": "2025-07-14T11:36:33.768Z" 61 }
Example usage
Here’s an example of how to handle the webhook in a Hono app:
1 import { Hono } from "hono"; 2 import { Webhook } from "svix"; 3 4 const app = new Hono(); 5 6 app.post("/webhooks/phonic", async (c) => { 7 if (!process.env.PHONIC_WEBHOOK_SECRET) { 8 return c.text("Bad Request", 400); 9 } 10 11 const wh = new Webhook(process.env.PHONIC_WEBHOOK_SECRET); 12 const rawBody = await c.req.text(); 13 14 try { 15 const payload = wh.verify(rawBody, { 16 "svix-id": c.req.header("svix-id") ?? "", 17 "svix-timestamp": c.req.header("svix-timestamp") ?? "", 18 "svix-signature": c.req.header("svix-signature") ?? "", 19 }); 20 21 console.log(JSON.stringify(payload, null, 2)); 22 23 return c.text("OK", 200); 24 } catch (error) { 25 console.error("Failed to verify webhook:", error); 26 27 return c.text("Bad Request", 400); 28 } 29 }); 30 31 export default app;