Comportamiento de las entregas
El contenido estándar de la solicitud, el límite de 5 segundos, por qué no hay reintentos y qué significa cada estado de entrega.
La entrega de webhooks es sencilla por diseño, y esa sencillez tiene consecuencias para tu receptor: un solo intento HTTP, cinco segundos, ningún reintento. Lee esta página antes de decidir cuánto trabajo ejecutará tu manejador de forma síncrona.
La estructura estándar de los datos
Todos los eventos excepto listing.submission llegan con la misma estructura de nivel superior, con los campos específicos del evento anidados bajo data.
{ "event": "connection.location_connected", "timestamp": "2026-08-25T14:32:10Z", "account_id": 11073, "location_id": "279381", "data": { "platform": "google", "connected_account_id": "ba03bc4b-9f8c-4d3b-8e93-9628034c63cc" }}Los campos opcionales dentro de data se omiten cuando están vacíos, en lugar de enviarse como null. Programa de forma defensiva: trata una clave ausente y un null explícito de la misma manera, y nunca des por hecho que una clave documentada como opcional estará presente.
Dos excepciones
El plazo de 5 segundos
Cada entrega consiste en un único POST con un tiempo de espera de conexión de 5 segundos y un tiempo de espera de lectura de 5 segundos. Si tu endpoint no ha respondido a tiempo, el intento se abandona y se registra como timeout.
Ese plazo abarca toda la ejecución de tu manejador. El único diseño seguro es el siguiente:
- Verifica la firma.
- Guarda los datos en un medio de almacenamiento persistente: una cola, una tabla o un registro.
- Devuelve
200.
Todo lo demás (enriquecer los datos, distribuirlos entre varios destinos, volver a llamar a la API REST o cualquier operación que interactúe con un tercero) debe ejecutarse al procesar los datos de esa cola.
No hay reintentos
Cada entrega se intenta exactamente una vez. No hay esperas progresivas, cola de reintentos ni cola de mensajes no entregados. Si tu endpoint no está disponible durante dos minutos, los eventos que se generaron en esos dos minutos se pierden. No llegarán más tarde.
Conviene dejar claras dos consecuencias:
- No se siguen las redirecciones. Las redirecciones están completamente deshabilitadas, por lo que un
301o un302de tu endpoint se registra como una entrega fallida, sin seguir la redirección a una segunda URL. Configura la URL de tus webhooks con la URL final. Presta atención a las redirecciones del dominio sin subdominio awwwy a las que añaden una barra final, que muchos servidores web incluyen de forma predeterminada. - Solo un
2xxcuenta como entrega completada.3xx,4xxy5xxse registran como fallos.
Duplicados y orden
- Puedes recibir el mismo evento dos veces y el mismo id para dos cambios distintos. Los identificadores dentro de
data(un id de interacción, un id de elemento de publicación, un id de cuenta conectada) identifican el recurso, no el cambio.interaction.reviewvuelve a emitirse con el mismo id de interacción cada vez que cambia la reseña, y ningún cuerpo de evento incluye una versión ni un campo updated-at, por lo que un manejador que descarta de forma permanente los eventos según el id +eventdescarta cambios reales sin avisar. En su lugar, detecta duplicados exactos: calcula un hash de los bytes sin procesar del cuerpo e ignora las repeticiones del mismo hash dentro de un intervalo breve y limitado (minutos, no indefinidamente). Un cuerpo distinto para el mismo id es un cambio nuevo, no un duplicado. Después, vuelve a consultar el recurso mediante la API REST y considera esa lectura como la fuente de referencia; usa el id del recurso como clave para la escritura en lugar de omitirla. - El orden no está garantizado, y
timestampno lo corregirá. Los eventos proceden de varios canales independientes y se entregan a medida que llegan, por lo que unlocal_post.publishedpuede llegar antes dellocal_post.createdque esperabas recibir primero. No ordenes dos cambios del mismo recurso portimestamp: se registra cuando se prepara la entrega, no cuando se produjo el cambio, y no hay ninguna versión ni número de secuencia en el cuerpo del evento. Cuando el orden sea relevante, vuelve a consultar el recurso y usa lo que devuelva la API. profile.updatedse limita a una entrega por ubicación cada 60 segundos, que se realiza al inicio del intervalo. Los eventos se suprimen, no se retrasan: la primera modificación abre el intervalo y se entrega, todas las modificaciones dentro del intervalo se descartan y nunca llegan, ychanged_fieldsdescribe únicamente la modificación que abrió el intervalo. Por tanto, el evento te llega al inicio del intervalo, de modo que una nueva lectura activada por su llegada solo puede mostrar esa primera modificación. Programa una segunda lectura una vez cerrado el intervalo, al menos 60 segundos después del evento, y reconcilia también las ubicaciones de forma periódica, porque la propia notificación puede perderse: un solo intento, sin reintentos. Esta limitación no se aplica a ningún otro evento.
Recuperación ante un evento perdido
No hay reintentos ni reproducción de eventos, por lo que cada familia necesita una lectura de referencia a la que puedas recurrir. Reconcilia los datos de forma periódica, no solo cuando algo parezca incorrecto.
Resultados de entrega
Cada intento, incluso si no llega a enviarse, se registra con un estado. Estas son las cadenas exactas.
Lista de comprobación para el receptor
- Verifica la firma de cada solicitud; devuelve
401y no proceses nada si no coincide. - Calcula el hash de los bytes del cuerpo sin procesar, nunca de un objeto vuelto a serializar.
- Devuelve
2xxen mucho menos de 5 segundos; pon el trabajo en cola. - Usa los identificadores incluidos en
datacomo claves de cada escritura del manejador para que una repetición produzca el mismo resultado, pero nunca interpretes un identificador repetido como una indicación de que no hay nada que hacer. - No deduzcas el orden a partir del orden de llegada ni ordenes por
timestamp. - Normaliza
location_ida una cadena al recibirlo. - Ignora los valores de
eventque no reconozcas y devuelve200de todos modos. - Sirve la URL de webhooks como URL final, sin redirecciones.
- Concilia los datos periódicamente con la REST API; no hay reintentos que permitan recuperarlos.