Webhooks

Receba notificações em tempo real quando eventos acontecem na plataforma.

Webhooks são URLs do seu sistema que a Adalink chama quando algo acontece (um agente terminou de executar, um arquivo foi processado, etc). Em vez de você ficar perguntando se mudou alguma coisa, a gente avisa.

1. Registrar um webhook

Crie o webhook informando a URL de destino, os eventos que quer receber e (opcional) o endpointPath se quiser receber chamadas externas via /v1/webhooks/{endpointPath}.

curl
curl -X POST https://api.adalink.ai/v1/webhooks \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://seuapp.com/hooks/adalink",
    "events": ["agent.run.completed", "file.processed"],
    "endpointPath": "fluxo-suporte"
  }'

# Resposta inclui o secret usado para validar a assinatura HMAC.
{
  "id": "wh_01J...",
  "url": "https://seuapp.com/hooks/adalink",
  "events": ["agent.run.completed", "file.processed"],
  "secret": "whsec_..."
}

2. Validar a assinatura HMAC

Toda chamada vem com o header X-Adalink-Signature contendo HMAC-SHA256 do body, usando o secret retornado quando você criou o webhook. Verifique antes de processar — ignore qualquer chamada sem assinatura válida.

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

function isValid(rawBody: string, signature: string, secret: string): boolean {
  const expected = 'sha256=' + createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  const a = Buffer.from(expected);
  const b = Buffer.from(signature);
  if (a.length !== b.length) return false;
  return timingSafeEqual(a, b);
}

// No seu handler:
const signature = req.headers['x-adalink-signature'];
if (!isValid(req.rawBody, signature, process.env.ADALINK_WEBHOOK_SECRET)) {
  return res.status(401).end();
}

3. Payload

Todo evento segue o mesmo formato: id (UUID v7), type (ex: agent.run.completed), createdAt (ISO 8601), data (objeto com os dados do evento).

json
{
  "id": "evt_01J3K2N7PXMQXR4F0Y7T8Z6P3D",
  "type": "agent.run.completed",
  "createdAt": "2026-05-05T13:42:18.317Z",
  "data": {
    "agentId": "agt_01J...",
    "runId": "run_01J...",
    "status": "succeeded",
    "durationMs": 4321,
    "output": "..."
  }
}

Retry e idempotência

Se sua URL retornar 5xx ou levar mais de 30s, a Adalink reenvia o evento com backoff exponencial (1s, 5s, 30s, 5min, 30min) por até 24h. O id do evento é estável — use-o como chave de idempotência.

Rotacionar o secret

Use POST /v1/webhooks/{id}/rotate-secret para gerar um novo secret. O secret antigo continua válido por 24h para você atualizar seus servidores sem downtime.

Testar antes de ir para produção

POST /v1/webhooks/{id}/test dispara um payload de exemplo na sua URL. Use também POST /v1/webhooks/{id}/test/start para abrir uma janela de captura — a próxima chamada externa fica em fila para inspeção em vez de ser entregue.