Skip to main content

Documentation Index

Fetch the complete documentation index at: https://ryvo-3dab4d1a.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Cuando tus agentes terminan llamadas (o fallan), Ryvo te manda un evento a una URL que tú configuras. Útil para:
  • Actualizar el deal en tu CRM con el resultado de la llamada.
  • Disparar un follow-up automatizado si la llamada falló.
  • Loggear el resumen de cada conversación en tu data warehouse.

Configurar tu webhook

  1. Entra a app.ryvo.so/developers.
  2. En la sección Webhook, agrega tu URL pública (HTTPS obligatorio).
  3. Copia el signing secret que generamos. Solo se muestra una vez — guárdalo en un secret manager. Lo necesitas para verificar la firma de cada evento.
La URL del webhook debe ser pública y aceptar peticiones POST. Si está detrás de un firewall o requiere auth, los eventos no van a llegar.

Eventos disponibles

EventoCuándo se dispara
call.initiatedCuando disparas una llamada vía POST /v1/calls.
call.completedCuando termina exitosamente una llamada.
call.failedCuando una llamada termina con error o no contesta.
Por defecto recibes todos los eventos. En el futuro vas a poder filtrar por tipo desde el portal.

Shape de un evento

Todos los eventos comparten esta estructura:
{
  "id": "<uuid>",
  "type": "call.completed",
  "created_at": "2026-04-30T18:35:42.123Z",
  "data": {
    /* campos específicos por tipo de evento */
  }
}

call.initiated

{
  "id": "evt_01abc...",
  "type": "call.initiated",
  "created_at": "2026-04-30T18:32:11.123Z",
  "data": {
    "id": "call_conv_01abcdef",
    "agent_id": "agent_8801kpabc123",
    "to": "+5215555550100",
    "metadata": {
      "lead_name": "Juan García"
    }
  }
}

call.completed

{
  "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"
  }
}

call.failed

{
  "id": "evt_03ghi...",
  "type": "call.failed",
  "created_at": "2026-04-30T18:32:25.456Z",
  "data": {
    "id": "call_conv_01abcdef",
    "agent_id": "agent_8801kpabc123",
    "status": "failed",
    "reason": "no_answer"
  }
}

Headers de cada delivery

HeaderValor
Content-Typeapplication/json
User-AgentRyvo-Webhook/1.0
X-Ryvo-Signaturet=<unix_secs>,v1=<hex_sha256> — verifica esto.
X-Ryvo-EventEl tipo de evento (ej. call.completed).
X-Ryvo-Event-IdUUID del evento — úsalo para idempotencia.
X-Ryvo-DeliveryUUID único de este intento de entrega.

Reintentos automáticos

Si tu endpoint responde con un código que no es 2xx o se cuelga más de 10 segundos, reintentamos automáticamente con backoff exponencial:
IntentoCuándo
1Inmediato cuando ocurre el evento.
25 minutos después.
330 minutos después.
42 horas después.
Después del 4to intento fallido, marcamos la entrega como exhausted y no volvemos a intentar. Puedes ver el historial en app.ryvo.so/developers.

Idempotencia del lado del receptor

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 DB

app.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)
})

Responde rápido

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).

Próximos pasos

Verificar firmas

Cómo validar que el evento viene de Ryvo y no de un atacante.

Probar tu webhook

Desde el portal puedes mandarte un evento de prueba.