orkasa

Guías

Webhooks

Cuatro cambios de estado que Orkasa te empuja en el momento en que pasan.

Consultar una lista te dice que un negocio se cerró hasta un minuto tarde, y te cuesta una petición por minuto para siempre. Un webhook te lo dice cuando pasa.

event_typese dispara cuandopermisocontenido
deal_wonuna operación llega a won · sold · rentedoperations:readla operación
offer_accepteduna oferta llega a acceptedoffers:readla oferta
signature_signedun documento de firma llega a signedsignatures:readla firma
document_completedun documento llega a received o verifieddocuments:readel documento

Cada contenido lo produce el mismo serializador que el endpoint de lista equivalente: un campo significa lo mismo lo hayas consultado o te lo hayan empujado. Y el permiso para suscribirte es el :read del propio recurso — solo te podemos avisar de lo que ya podías leer.

Suscribirse

curl -X POST "$ORKASA_API/hooks" \
  -H "Authorization: Bearer $ORKASA_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "event_type": "deal_won",
    "target_url": "https://hooks.zapier.com/hooks/catch/123/abc/"
  }'

Responde 201 con un { "id": "…" } plano, sin envoltorio data, porque Zapier guarda el cuerpo entero como su subscribeData. target_url tiene que ser https.

Darse de baja

curl -X DELETE "$ORKASA_API/hooks/<id>" -H "Authorization: Bearer $ORKASA_KEY"

204, siempre. Una baja repetida o de algo que ya no existe no es un error: así un Zap que se está desmontando nunca falla en ese paso.

Probar sin esperar un evento

curl "$ORKASA_API/hooks/sample?event_type=deal_won" \
  -H "Authorization: Bearer $ORKASA_KEY"

Devuelve filas recientes que ya están en el estado terminal del evento, en el envoltorio normal. Un webhook de tipo REST-hook no tiene pasado que enseñar mientras construyes el Zap; esto llena ese hueco, y sirve también como alternativa por consulta.

Cómo se entrega

Suscribirse arma un disparador en la base de datos, no una consulta periódica. En la transición que califica —y solo en la primera— la fila entra en una bandeja de salida, pero solo si alguien está escuchando: sin suscripción para esa agencia y ese evento, no se escribe nada. El silencio no cuesta.

Un cron vacía la bandeja cada minuto:

POST <target_url>
x-orkasa-event: deal_won
x-orkasa-signature: sha256=<hmac del cuerpo exacto>
content-type: application/json

La firma es HMAC-SHA256 sobre los bytes exactos que se enviaron. Zapier no la verifica —su URL de captura ya es el secreto— pero cualquier otro consumidor debería, y la cabecera sencillamente no aparece si no hay secreto configurado.

Como mucho una vez por destino

Es el valor por defecto correcto para un consumidor que no deduplica:

  • todos los destinos respondieron 2xx → entregado;
  • todos fallaron → se reintenta en la vuelta siguiente, hasta 3 intentos. Es seguro: nadie lo vio;
  • algunos funcionaron, o se acabaron los intentos → se marca entregado y se anota la razón. Reintentar volvería a llamar a los destinos que ya lo recibieron, y una ejecución duplicada de un Zap es peor que una perdida;
  • la suscripción desapareció antes de serializar → no hay nada que enviar.

La tabla de la bandeja se llama outbound_webhook_events, no webhook_events: ese nombre ya lo ocupa el registro entrante de Stripe, Meta y WhatsApp. No tienen nada que ver.