Webhooks
Configure endpoints para receber eventos em tempo real, eliminando a necessidade de polling. O sistema faz até 5 tentativas com backoff exponencial antes de marcar uma entrega como falha.
Eventos Disponíveis
nfse.issuedNFS-e emitida com sucesso. Contém chNFSe e nNFSe.
nfse.errorFalha na emissão. Contém errorCode e errorMessage.
nfse.cancelledNFS-e cancelada com sucesso. Contém cancelledAt (timestamp ISO 8601).
nfse.documents_readyDocumentos cacheados no CDN. Contém xmlUrl, pdfUrl, cancelXmlUrl (para notas canceladas), documentStatus e cachedAt.
batch.completedLote finalizado. Contém total, issued, errors.
Estrutura do Payload
Todos os eventos seguem a mesma estrutura de envelope. O campo data varia por evento.
{
"event": "nfse.issued",
"deliveryId": "del_xyz789",
"timestamp": "2026-03-12T19:00:00.000Z",
"data": {
"invoiceId": "inv_abc123",
"chNFSe": "4321000001234",
"nNFSe": "00001"
}
}Headers enviados com cada requisição:
| Header | Valor |
|---|---|
| Content-Type | application/json |
| X-Notaas-Event | Nome do evento (ex: nfse.issued) |
| X-Notaas-Delivery | ID único da entrega (UUID) |
| X-Notaas-Signature | HMAC-SHA256 do body — presente apenas se o endpoint tiver secret configurado |
⚠️ Assinatura HMAC
O header X-Notaas-Signature só é enviado quando o endpoint tem um secret configurado. Configure o secret no Dashboard → Developers → Webhooks → Editar endpoint.
ℹ️ Compatibilidade
Campos adicionais podem ser incluídos nos payloads de webhook sem aviso prévio. Seu código deve ignorar campos desconhecidos para manter compatibilidade futura (Postel's Law).
Validar Assinatura (HMAC)
O valor do header X-Notaas-Signature é calculado como sha256=HMAC-SHA256(secret, rawBody). Você deve recalcular a assinatura no seu servidor e comparar com timing-safe equality.
import crypto from 'crypto';
app.post('/webhook/notaas', (req, res) => {
// IMPORTANTE: req.rawBody deve ser a string bruta antes do JSON.parse
const rawBody = req.rawBody;
const received = req.headers['x-notaas-signature'] ?? '';
const expected =
'sha256=' +
crypto
.createHmac('sha256', process.env.NOTAAS_WEBHOOK_SECRET)
.update(rawBody)
.digest('hex');
const valid = crypto.timingSafeEqual(
Buffer.from(received),
Buffer.from(expected),
);
if (!valid) return res.status(401).send('Assinatura inválida');
// Idempotência: evitar reprocessar em retries
const deliveryId = req.headers['x-notaas-delivery'];
if (alreadyProcessed(deliveryId)) return res.status(200).send('ok');
const payload = JSON.parse(rawBody);
console.log(payload.event, payload.data);
res.status(200).send('ok');
});Retry Policy
Uma entrega é considerada falha quando o endpoint retorna status não-2xx ou ocorre erro de rede/timeout (10s). O sistema tenta novamente até 5 vezes com delays crescentes:
| Tentativa | Delay |
|---|---|
| 1ª | Imediato |
| 2ª | 1 minuto |
| 3ª | 5 minutos |
| 4ª | 30 minutos |
| 5ª | 2 horas |
Após 5 tentativas falhas, a entrega é marcada como failed. Você pode consultar o histórico em Dashboard → Webhooks → Histórico.
Configurar Endpoint via API
curl -X POST https://platform.notaas.com.br/api/v1/webhooks/endpoints \
-H "Content-Type: application/json" \
-H "x-api-key: ntaas_XXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-d '{
"url": "https://minha-api.com/webhooks/notaas",
"events": ["nfse.issued", "nfse.error"],
"secret": "meu-secret-para-assinar"
}'Parâmetros do Endpoint
Use o header X-Notaas-Delivery para garantir idempotência — armazene os IDs processados e ignore repetições em caso de retry.
POST /webhooks/endpoints
| Campo | Tipo | Req? | Descrição |
|---|---|---|---|
| url | string | sim | URL HTTPS que receberá o POST |
| events | string[] | sim | Lista de eventos: nfse.issued, nfse.error, nfse.cancelled, nfse.documents_ready, batch.completed |
| secret | string | não | Secret para assinar payloads com HMAC-SHA256 (opcional, mas recomendado em produção) |
| active | boolean | não | Ativo por padrão (true) |