Visão Geral
Acontece: o cliente jura que não recebeu o webhook do pagamento, ou seu endpoint ficou meia hora fora do ar e perdeu uma rajada de eventos. A Garu guarda todo evento de webhook emitido — entregue ou não — e você pode listar, inspecionar e reenviar qualquer um pela API, SDK, CLI ou direto pelo seu agente de IA. Hoje existem dois endpoints de reenvio. Use/resend para tudo a partir de agora — o /retry segue funcionando mas tem dois problemas que /resend resolve.
Endpoints
GET /api/v1/webhook-events— lista com filtros (status, tipo de evento, endpoint).GET /api/v1/webhook-events/:uuid— detalhes de um evento (payload, tentativas, último HTTP,manualResendOf).POST /api/v1/webhook-events/:uuid/resend— clona e entrega o clone. Use este.POST /api/v1/webhook-events/:uuid/retry— reseta o original e reentrega. Legado.
Os endpoints aceitam chave de API do seller (
sk_test_… / sk_live_…) ou sessão JWT do dashboard. Use a chave de API para automação; o dashboard usa o JWT por baixo dos panos.Status do evento
Toda entrega de webhook tem um destes três status:Mudança no Idempotency-Key
A Garu sempre mandou um headerIdempotency-Key nos POSTs para o seu endpoint. O que mudou na v0.11.0:
O ponto crítico:
/resend e o botão “Reenviar” agora mandam uma chave HTTP distinta da chave da entrega original. Três caminhos no seu handler:
- Dedup pelo valor bruto do header: já trata
resend_<uuid>como entrega nova naturalmente —resend_Xnunca colide comevt_Y. Nenhuma mudança de código. Mas pré-v0.11.0 o resend chegava com a mesma chave do original e seu dedup descartava silenciosamente; agora ele passa, e sua idempotência de negócio precisa segurar. - Dedup pelo
payload.id: descarta o resend, porquepayload.idé idêntico entre original e clone. Atualize. - Dedup com normalização do header (strip de prefixo, regex, comparações truncadas): pode esconder a distinção entre
evt_…eresend_…. Atualize.
payload.id — o mais comum entre handlers que efetivamente quebram com a mudança.
Código do receiver — antes/depois
Fluxo: listar com falha → escolher → reenviar
- cURL
- Dashboard
- SDK / CLI / MCP
Limite de chamadas
/resend e /retry têm rate limit de 20 requisições por minuto por IP cada. É o suficiente para reprocessar um lote considerável sem pesar nos seus endpoints — e impede que um script em loop infinito martele um receiver que está fora do ar.
O que /resend faz por dentro
- Cria uma linha nova na tabela de eventos, com
manualResendOfapontando para o original. - Copia o
payloadexatamente como foi gerado —payload.id(evt_…) é preservado. - Calcula o
Idempotency-Keyoutbound comoresend_<uuid_do_clone>antes do POST para seu endpoint. - Dispara a entrega imediatamente, em background. Se falhar, aplica a retry policy padrão (1min, 5min, 30min, 2h, 8h, 16h até
failed). - Não toca no original. Ele fica para sempre no status terminal (
success/failed), com todas as tentativas e respostas históricas preservadas. É o que você quer para auditoria.
Quando reenviar (e quando não)
Reenvie quando: seu endpoint ficou fora do ar
Reenvie quando: seu endpoint ficou fora do ar
Janelas de indisponibilidade curtas (deploy, restart, k8s drain) frequentemente passam dos 26h da retry policy se forem aninhadas a outros incidentes. Reenviar é a forma de recuperar a fila sem precisar de plumbing manual.
Reenvie quando: o cliente diz que não recebeu
Reenvie quando: o cliente diz que não recebeu
Suporte clássico. Localiza o evento via filtro
eventType + janela de tempo, confirma que o status está failed (ou success mas o cliente não processou), reenvia com /resend.Reenvie quando: você precisa replay para QA / homologação
Reenvie quando: você precisa replay para QA / homologação
/resend funciona em eventos success também. Dispara um clone para o mesmo endpoint, útil para validar que mudanças no handler ainda processam o payload corretamente.Não reenvie quando: o evento já está success e seu sistema processou
Não reenvie quando: o evento já está success e seu sistema processou
Reenviar duplica a notificação. Sua idempotência de negócio (chave do seu domínio, não do header) deve absorver, mas é trabalho à toa.
Não reenvie quando: a falha é determinística
Não reenvie quando: a falha é determinística
Se seu endpoint devolve 4xx por bug ou validação, o reenvio vai falhar de novo. Corrija o handler primeiro e depois reenvie.
Permissões
Por papel padrão da Garu:- Owner / Administrator / Developer: listar, ver e reenviar.
- Support: listar e ver; reenvio depende de permissão
webhook:edit. - View Only: somente listar e ver.
Próximos passos
API: /resend
Referência completa do endpoint de reenvio por clone
API: /retry (legado)
Endpoint legado que muta o original in place
Detalhes do evento
Inspecione
manualResendOf, tentativas e payloadCódigos de falha
Roteie falhas de pagamento pelo enum normalizado