---
title: "Webhooks · Documentação da API Zaiped"
description: "Cadastre um endpoint HTTPS com POST /webhooks e os eventos que quer. Cada evento vira uma entrega: um POST com corpo JSON e três headers. O segredo de assinatura é devolvido uma vez, na criação. A URL precisa ser https e apontar para um host público: endereço de rede privada, loopback e link-local são recusados, e para testar na sua máquina use um túnel."
lang: "pt-BR"
canonical: "https://zaiped.com/developers/docs/webhooks"
alternate: "https://zaiped.com/en/developers/docs/webhooks"
---

# Webhooks

Cadastre um endpoint HTTPS com POST /webhooks e os eventos que quer. Cada evento vira uma entrega: um POST com corpo JSON e três headers. O segredo de assinatura é devolvido uma vez, na criação. A URL precisa ser https e apontar para um host público: endereço de rede privada, loopback e link-local são recusados, e para testar na sua máquina use um túnel.

## Eventos

- message.received: um cliente mandou mensagem. Traz wamid, from, phoneNumberId, type, text, os campos de mídia, replyPayload, flowResponse, order e o messageId da Zaiped para GET /media.
- message.status: uma mensagem sua foi entregue, lida ou falhou, com error e pricing.
- template.status: o veredito da Meta sobre um modelo.
- number.update: mudanças de qualidade, limite de envio ou nome de exibição.
- account.notice: avisos da WABA, inclusive acesso perdido.
- call.event: eventos e status de chamada de voz.

## O corpo

```
{
  "id": "YOUR_DELIVERY_ID",
  "event": "message.received",
  "createdAt": 1757160000000,
  "data": { "wamid": "wamid.HBg...", "from": "+5511999999999", "type": "text", "text": "Oi", "messageId": "..." }
}
```

## Headers e assinatura

- X-Zaiped-Event: o nome do evento.
- X-Zaiped-Delivery: o id da entrega, o mesmo em todas as tentativas dela. Use para deduplicar.
- X-Zaiped-Signature: t=TIMESTAMP,v1=HEX, onde v1 é HMAC-SHA256(secret, "TIMESTAMP.CORPO_CRU").

```
// Node.js
import { createHmac, timingSafeEqual } from "node:crypto";

function verify(rawBody, header, secret) {
  const [t, v1] = header.split(",").map((part) => part.slice(part.indexOf("=") + 1));
  const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  return timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}
```

## Uma entrega por evento

A Meta reentrega o mesmo evento quando não tem certeza de que o recebemos, e nós absorvemos isso: um evento de origem gera UMA entrega por endpoint, com um X-Zaiped-Delivery só. O que se repete é a tentativa da MESMA entrega, quando o seu endpoint não responde 2xx, e aí o id é o mesmo. Guarde o id que já processou e ignore repetição: é a rede que sobra para o caso raro de um evento sem identidade estável, que preferimos entregar duas vezes a engolir.

## Retentativa

Responda 2xx rápido. Qualquer outra coisa, ou um timeout de dez segundos, agenda uma retentativa depois de um minuto, depois cinco, trinta, duas horas e doze horas. São seis tentativas ao todo (a primeira mais as cinco esperas); depois delas a entrega é marcada como failed e fica no registro por trinta dias. GET /webhooks/{webhookId}/deliveries lista as recentes; POST .../test manda um evento de teste.