Domínios e entrega
Webhooks e eventos
Oito tipos de evento, entregues no seu endpoint com assinatura HMAC, ou consultados sob demanda em /v1/events.
A ida está em O caminho da mensagem, e termina no destinatário. Esta página começa exatamente ali.
Os oito eventos
| Tipo | Quando dispara |
|---|---|
send | A mensagem foi aceita e saiu daqui. |
delivery | O servidor do destinatário confirmou o recebimento. |
bounce | Devolveu. O motivo vem em data. |
complaint | A pessoa marcou como spam. |
reject | Recusada antes de sair, por exemplo por supressão. |
rendering_failure | O template não conseguiu ser montado. |
open | Abertura, se o tracking estiver ligado. |
click | Clique em link, se o tracking estiver ligado. |
Para ver cada um destes acontecendo sem depender da realidade, mande para os apelidos de teste.
Registrar um webhook
curl -X POST https://api.jetsend.com.br/v1/webhooks \ -H "Authorization: Bearer $JETSEND_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://seusistema.com.br/hooks/jetsend", "eventos": ["delivery", "bounce", "complaint"] }'A resposta traz o segredo da assinatura. Ele aparece uma vez; guarde. A URL precisa ser http:// ou https:// completa e apontar para um endereço público: endpoint que resolve para IP interno é recusado no cadastro, porque aceitar isso transformaria o nosso servidor numa ponte para a sua rede privada.
O que chega
{ "type": "bounce", "message_id": "9f1c0f2e-6d3b-4f0a-9a1e-2c7d8b5a3e10", "to": "cliente@exemplo.com", "subject": "Sua fatura de setembro", "occurred_at": "2026-09-28T14:12:03.221Z", "data": null}Junto vão três cabeçalhos:
x-jetsend-event, o tipo, igual aotypedo corpo;x-jetsend-timestamp, o instante em segundos;x-jetsend-signature, o HMAC SHA-256.
Conferir a assinatura
A assinatura é o HMAC SHA-256 de timestamp + "." + corpo, com o seu segredo como chave. Confira antes de processar: sem isso, qualquer um que descubra a sua URL pode inventar uma devolução e fazer o seu sistema dar baixa num cliente que está ativo.
import { createHmac, timingSafeEqual } from "node:crypto";export function assinaturaConfere(req, segredo) { const timestamp = req.headers["x-jetsend-timestamp"]; const recebida = req.headers["x-jetsend-signature"]; const corpo = req.rawBody; // o corpo CRU, antes do JSON.parse const esperada = createHmac("sha256", segredo) .update(`${timestamp}.${corpo}`) .digest("hex"); const a = Buffer.from(esperada, "utf8"); const b = Buffer.from(String(recebida), "utf8"); if (a.length !== b.length) return false; return timingSafeEqual(a, b);}Dois detalhes que costumam morder. Use o corpo cru, antes de qualquer JSON.parse: reserializar muda espaços e a ordem das chaves, e a assinatura não bate mais. E compare com timingSafeEqual, não com ===: comparação de string vaza pelo tempo o tamanho do prefixo correto, e isso é suficiente para descobrir a assinatura tentativa a tentativa.
Consultar sem webhook
curl "https://api.jetsend.com.br/v1/events?tipo=bounce&limit=50" \ -H "Authorization: Bearer $JETSEND_API_KEY"GET /v1/events aceita messageId, tipo, limit (até 200) e cursor para paginar. Serve para reconciliar depois de uma queda do seu endpoint, quando você quer buscar o que perdeu em vez de esperar.
Lista de supressão
Devolução permanente e marcação de spam entram automaticamente na lista de supressão da sua conta, e envios seguintes para aquele endereço são recusados antes de sair. GET /v1/bloqueios lista, e DELETE /v1/bloqueios/:id remove uma entrada sua. Entradas globais da plataforma não são removíveis pela conta.
