Webhooks
Receba avisos assinados sobre execuções externas e consulte os resultados pela API.
Nesta página
Configure o destino na conta
Na conta, abra API → Webhooks. Cadastre uma URL HTTPS pública do seu servidor na porta 443, com certificado válido, e selecione os eventos e as automações publicadas. O Bearer externo não cria ou altera destinos.
O segredo de assinatura aparece uma única vez. Guarde o texto completo no servidor receptor. O destino não aceita IP literal, rede privada, credenciais na URL ou redirecionamentos.
Eventos disponíveis
Apenas novas execuções externas das automações e eventos selecionados geram avisos. Testes manuais, cancelamentos e envios não admitidos não geram eventos. Não há entrega retroativa para novos destinos.
| Evento | Significado |
|---|---|
| automation.completed | Processamento concluído. |
| automation.partial | Resultado parcial, inclusive falha de etapa configurada para continuar. |
| automation.failed | Execução encerrada com falha. |
{ "id": "UUID_DO_EVENTO", "type": "automation.completed", "createdAt": "DATA_ISO", "data": { "automationId": "UUID_DA_AUTOMACAO", "runId": "UUID_DA_EXECUCAO", "version": 1, "status": "COMPLETED", "origin": "api", "files": 1, "completed": 1, "failed": 0, "cancelled": 0 }}Verifique a assinatura antes de usar o evento
- Preserve os bytes originais do body antes de fazer parse JSON.
- Valide Duckfile-Timestamp com tolerância de ±300 segundos.
- Calcule HMAC-SHA256 de timestamp + ponto + rawBody usando o texto completo do segredo como chave UTF-8.
- Compare em tempo constante com Duckfile-Signature no formato v1=hex. Trate eventos duplicados pelo Duckfile-Event-Id no escopo do receptor.
import { createHmac, timingSafeEqual } from 'node:crypto'; function verify(secret, timestamp, signature, rawBody) { if (!/^\d{10}$/.test(timestamp ?? '') || Math.abs(Date.now() / 1000 - Number(timestamp)) > 300 || !/^v1=[a-f0-9]{64}$/.test(signature ?? '')) return false; const expected = createHmac('sha256', secret) .update(timestamp + '.').update(rawBody).digest(); const received = Buffer.from(signature.slice(3), 'hex'); return received.length === expected.length && timingSafeEqual(received, expected);}// rawBody deve ser um Buffer preservado pelo seu servidor.// Depois de validar, deduplique o evento antes de produzir efeitos.Retentativas e resultados
A entrega é pelo menos uma vez: o mesmo evento pode chegar novamente. São até seis tentativas por ciclo, com intervalos de 1 min, 5 min, 15 min, 1 h e 4 h, na janela máxima de 24 h. Timestamp e assinatura mudam por tentativa; o ID e o corpo do evento permanecem.
Falhas de rede, 408, 425, 429 e 5xx podem ter nova tentativa. Redirecionamentos e demais 4xx encerram a entrega. A conta permite até dois reenvios manuais elegíveis; eles repetem o aviso, não o processamento.
O webhook não contém arquivos, nomes ou URLs de download. Consulte GET /runs/:id pelo runId do evento com uma chave read e baixe enquanto os resultados estiverem disponíveis. Resultados novos expiram em até 15 minutos após concluir. A janela de 24 h do webhook não prolonga essa disponibilidade.