Comportamento de entrega
O payload padrão, o limite de 5 segundos, por que não há novas tentativas e o que significa cada status de entrega.
A entrega de webhooks é simples por decisão de projeto, e essa simplicidade tem consequências para o seu receptor: uma tentativa HTTP, cinco segundos, nenhuma nova tentativa. Leia esta página antes de decidir quanto trabalho seu handler executará de forma síncrona.
O payload padrão
Todos os eventos, exceto listing.submission, chegam com a mesma estrutura no nível superior, com os campos específicos do evento dentro de 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" }}Os campos opcionais dentro de data são omitidos quando estão vazios, em vez de serem enviados como null. Programe de forma defensiva: trate uma chave ausente e um null explícito da mesma maneira e nunca presuma que uma chave documentada como opcional estará presente.
Duas exceções
O limite de 5 segundos
Cada entrega consiste em um único POST com timeout de conexão de 5 segundos e timeout de leitura de 5 segundos. Se o seu endpoint não responder dentro do prazo, a tentativa será abandonada e registrada como timeout.
Esse limite se aplica à execução completa do seu handler. A única implementação segura é:
- Verifique a assinatura.
- Grave o payload em um armazenamento persistente: uma fila, uma tabela ou um log.
- Retorne
200.
Todo o restante (enriquecimento, distribuição para múltiplos destinos, chamadas de volta à REST API, qualquer operação que envolva terceiros) deve ser executado após o consumo dessa fila.
Não há novas tentativas
Cada entrega é tentada exatamente uma vez. Não há backoff, fila de novas tentativas nem fila de mensagens não entregues. Se o seu endpoint ficar indisponível por dois minutos, os eventos disparados nesses dois minutos serão perdidos. Eles não chegarão depois.
Duas consequências que precisam ficar explícitas:
- Redirecionamentos não são seguidos. Os redirecionamentos são totalmente desativados, portanto, um
301ou302retornado pelo seu endpoint é registrado como falha na entrega, sem que o redirecionamento para uma segunda URL seja seguido. Configure a URL dos seus webhooks com a URL final. Fique atento aos redirecionamentos do domínio sem subdomínio parawwwe aos redirecionamentos que acrescentam uma barra final, que muitos servidores web adicionam por padrão. - Somente um
2xxconta como entrega concluída.3xx,4xxe5xxsão todos registrados como falhas.
Duplicatas e ordenação
- Você pode receber o mesmo evento duas vezes e o mesmo id para duas alterações diferentes. Os identificadores em
data(um id de interação, um id de item de publicação, um id de conta conectada) identificam o recurso, não a alteração.interaction.reviewé disparado novamente com o mesmo id de interação sempre que a avaliação muda, e nenhum payload contém uma versão ou um campo de data da última atualização, portanto, um handler que descarta permanentemente eventos com base no id +eventelimina edições reais silenciosamente. Em vez disso, detecte duplicatas exatas: calcule o hash dos bytes brutos do corpo e ignore repetições do mesmo hash dentro de uma janela curta e limitada (minutos, não para sempre). Um corpo diferente para o mesmo id é uma nova alteração, não uma duplicata. Em seguida, consulte novamente o recurso pela API REST e considere essa leitura como a fonte de referência; use o id do recurso como chave da gravação em vez de ignorá-la. - A ordenação não é garantida, e
timestampnão resolve isso. Os eventos vêm de vários fluxos independentes e são entregues conforme chegam, portanto, umlocal_post.publishedpode chegar antes dolocal_post.createdque você esperava receber primeiro. Não ordene duas alterações no mesmo recurso portimestamp: ele é registrado quando a entrega é montada, não quando a alteração ocorreu, e não há versão nem número de sequência em nenhuma parte do payload. Quando a ordem for relevante, consulte novamente o recurso e use o que a API retornar. profile.updatedé limitado por debounce a uma entrega por local a cada 60 segundos, no início da janela. Isso é uma supressão efetiva, não um atraso: a primeira edição abre a janela e é entregue, todas as edições dentro da janela são descartadas e nunca chegam, echanged_fieldsdescreve apenas a edição que abriu a janela. Portanto, o evento chega até você no início da janela, de modo que uma nova leitura disparada pela chegada dele só consegue ver essa primeira edição. Agende uma segunda leitura após o fechamento da janela, pelo menos 60 segundos após o evento, e também reconcilie os locais em intervalos regulares, pois a própria notificação pode se perder: uma tentativa, sem nova tentativa. Nenhum outro evento está sujeito a debounce.
Recuperação após a perda de um evento
Não há novas tentativas nem reenvio, portanto, cada família precisa de uma leitura de referência à qual você possa recorrer. Reconcilie em intervalos programados, não apenas quando algo parecer errado.
Resultados da entrega
Cada tentativa, incluindo aquelas que nem chegam a ser enviadas, é registrada com um status. Estas são as strings exatas.
Lista de verificação para o receptor
- Verifique a assinatura de cada requisição; retorne
401e não processe nada se ela não corresponder à assinatura esperada. - Calcule o hash dos bytes brutos do corpo, nunca de um objeto serializado novamente.
- Retorne
2xxem bem menos de 5 segundos; coloque o processamento na fila. - Use os IDs contidos em
datacomo chaves em cada operação de gravação do handler para que uma repetição produza o mesmo resultado, mas nunca considere que um ID repetido significa que não há nada a fazer. - Não deduza a ordem dos eventos pela ordem de chegada e não ordene por
timestamp. - Normalize
location_idpara uma string ao recebê-lo. - Ignore os valores de
eventque você não reconhecer e, ainda assim, retorne200. - Disponibilize a URL dos webhooks como uma URL final, sem redirecionamentos.
- Faça a reconciliação periodicamente com a API REST; não há novas tentativas para recuperar entregas malsucedidas.