{ "id": "evt_02def...", "type": "call.completed", "created_at": "2026-04-30T18:35:44.987Z", "data": { "id": "call_conv_01abcdef", "agent_id": "agent_8801kpabc123", "status": "completed", "duration_seconds": 211, "transcript_summary": "El lead aceptó agendar una demo para el 5 de mayo a las 11am.", "termination_reason": "user_hung_up", "started_at": "2026-04-30T18:32:13Z", "ended_at": "2026-04-30T18:35:44Z" }}
Aunque hagamos retry solo en errores, un mismo evento puede llegarte 2 veces (ej. tu endpoint procesó OK pero la respuesta 200 se perdió en la red). Por eso te mandamos X-Ryvo-Event-Id: guarda los IDs procesados y descarta duplicados.
const processed = new Set() // en producción, usa Redis o tu DBapp.post("/webhook/ryvo", async (req, res) => { const eventId = req.headers["x-ryvo-event-id"] if (processed.has(eventId)) return res.sendStatus(200) processed.add(eventId) // ... tu lógica res.sendStatus(200)})
Tu endpoint debe responder 200 en menos de 10 segundos. Si necesitas hacer trabajo lento (LLM call, sync a una API externa), responde 200 inmediato y procesa async (cola, background job).