Pular para o conteúdo principal
Documentação

Webhooks assinados

Receba eventos em tempo real no seu servidor, com validação HMAC SHA-256 contra falsificações.

Eventos disponíveis

Receba eventos em tempo real no seu servidor, com validação HMAC SHA-256 contra falsificações.

CampoTipoDescrição
email.senteventEmail aceito pelo MTA e entregue ao provedor de destino.
email.deliveredeventProvedor de destino confirmou a entrega na caixa de entrada.
email.bouncedeventBounce permanente destinatário inexistente ou política do provedor.
email.complainedeventDestinatário marcou o email como spam. Adicione à supressão automaticamente.
email.openedeventEmail aberto pelo destinatário (pixel tracking).
email.clickedeventLink clicado (tracking).
email.failedeventFalha definitiva após retentativas.
email.suppressedeventEmail bloqueado pela lista de supressão.
email.delivery_delayedeventEntrega atrasada (greylisting / rate limit do destino).

1. Cadastre o endpoint

Forneça uma URL HTTPS válida e a lista de eventos que deseja receber. Recomendamos fortemente cadastrar um secret.

curl
curl -X POST https://api.coffeemail.com.br/v1/product/webhooks \  -H "Authorization: Bearer $COFFEEMAIL_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "url": "https://sua-api.com.br/webhooks/coffeemail",    "events": ["email.delivered", "email.bounced", "email.complained"],    "secret": "whsec_meusegredocompartilhado"  }'

2. Valide a assinatura HMAC

Cada requisição chega com o header X-CoffeeMail-Signature contendo HMAC SHA-256 do corpo cru. Use coffeemail.webhooks.verifySignature() no seu handler.

handler.ts
import { Webhook } from '@coffeemail/node';import http from 'node:http'; const wh = new Webhook(process.env.COFFEEMAIL_WEBHOOK_SECRET!); http.createServer(async (req, res) => {  const signature = req.headers['x-coffeemail-signature'] as string;  const raw = await readBody(req);   try {    wh.verify(raw, signature);  } catch (err) {    res.statusCode = 401;    return res.end('Invalid signature');  }   const event = JSON.parse(raw.toString('utf-8'));  res.statusCode = 202;  res.end('OK');}).listen(3000);

3. Responda em < 5s

Responda 200 OK rápido. Se precisar processar de forma assíncrona, enfileire localmente e retorne 202. Workloads lentos disparam retries exponenciais.

4. Implemente idempotência

Cada payload inclui um event id único. Persista-o no seu banco para descartar duplicatas. Use upsert por id.

idempotency.ts
const event = JSON.parse(raw.toString('utf-8'));const eventId = event.id; await db.processedEvents.upsert({  where: { id: eventId },  create: {    id: eventId,    type: event.type,    payload: event,    receivedAt: new Date(),  },  update: {},});

5. Teste o endpoint

Use POST /v1/product/webhooks/:id/test para disparar um evento simulado. O endpoint recebe um payload fictício com assinatura válida.

test-webhook.ts
const { data } = await coffeemail.webhooks.test('wh_123');console.log('Status recebido:', data.statusCode);
Sempre use tls: true no seu handler. Endereços HTTP simples (porta 80) não são aceitos — a CoffeeMail exige HTTPS válido com certificado confiável.