Saltar al contenido principal
WEBHOOK

Encabezados

X-Listo-Signature
string
requerido

Comprueba que el evento vino de nosotros. El valor es t=<unix seconds>,v1=<hex>, donde el hex es un HMAC-SHA256, con tu secreto de firma como llave, sobre la cadena "<t>.<raw request body>".

Para verificarlo: separa el encabezado por la coma, reconstruye "<t>.<body>" a partir de los bytes CRUDOS que recibiste (nunca un objeto parseado y vuelto a serializar, porque los espacios en blanco y las secuencias de escape cambiarían la firma), calcula el HMAC y compáralo con v1 en tiempo constante. Rechaza todo lo que no coincida.

Después revisa el reloj. Rechaza un evento cuyo t esté a más de 5 minutos de distancia de ahora en CUALQUIERA de las dos direcciones: un t muy en el pasado es el replay que este esquema existe para detener, y uno muy en el futuro es el mismo ataque con un reloj que nadie revisó.

Pueden estar activos dos secretos a la vez para que puedas rotar sin tiempo de inactividad: agrega el nuevo, acepta cualquiera de los dos, promuévelo y luego elimina el anterior. Siempre firmamos con el primario.

Ejemplo:

"t=1753728063,v1=8d2f4a1b6c7e9f0a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f607182"

Cuerpo

application/json

Los campos que comparten todos los eventos. La entrega es al menos una vez y sin orden por diseño: deduplica por id, y ordena por created_at o por las marcas de tiempo propias del objeto, no por orden de llegada. type y data los agrega cada evento, porque sus valores dependen de cuál evento sea.

id
string
requerido

El id del evento, con prefijo evt_. Deduplica por este.

Ejemplo:

"evt_9pQ2vX7mKdR4tYb1nZ3sLwCe"

created_at
string<date-time>
requerido

Cuándo se registró el evento, ISO-8601 en UTC.

Ejemplo:

"2026-07-28T18:41:03Z"

type
enum<string>
requerido

Qué evento es este.

Opciones disponibles:
delivery.status_changed
data
object
requerido

La forma de un envío: cada campo que puede llevar el objeto, con la nulabilidad que realmente tiene cada uno. Es la respuesta de cada operación que responde un envío (la creación, la consulta, una fila de lista, la reprogramación, la cancelación, el reintento y el reembolso) y el data de cada evento completo de envío, así que UN tipo sostiene todos ellos.

Cada operación devuelve el objeto completo. Un campo que una llamada dada todavía no puede tener está presente y es null en lugar de faltar: una respuesta de creación tiene courier en null, porque todavía no se asigna ningún repartidor, y una reprogramación solo responde con un pedido que sigue programado, así que su delivered_at es null.

El dinero va en centavos enteros, las marcas de tiempo son ISO-8601 en UTC, y cada enumeración de abajo es nuestra y no una copia de la de un tercero.

test
boolean

Presente, y en true, solo en un evento de prueba que pediste con POST /v1/test_webhooks. Un evento real no trae el campo en absoluto. El data de un evento de prueba es una muestra cuyos ids no corresponden a nada.

Ejemplo:

true

Respuesta

200

Responde con cualquier 2xx, lo más rápido que puedas, para confirmar el evento. Haz el trabajo después. Cualquier otra respuesta se reintenta.