Webhooks
Receba eventos em tempo real através de HTTP POST para o seu endpoint
Última atualização em
Os webhooks recebem eventos em tempo real através de HTTP POST para um URL configurado por si. Os mesmos eventos estão também disponíveis através de SSE. Os webhooks são configurados por organização - cada organização tem os seus próprios webhooks.
Gestão
Consulte a especificação OpenAPI para os esquemas completos de pedido e resposta.
| Método | Caminho | Descrição |
|---|---|---|
| GET | /api/orgs/:orgId/webhooks | Obter webhooks |
| GET | /api/orgs/:orgId/webhooks/delivery-stats | Obter estatísticas de entrega |
| POST | /api/orgs/:orgId/webhooks/retry-deliveries | Repetir entregas. Corpo: mode (failed ou force) e, opcionalmente, id para um único webhook. failed: apenas entregas definitivamente falhadas, de imediato. force: entregas em espera e definitivamente falhadas, em segundo plano, ignorando os tempos de espera. |
| GET | /api/orgs/:orgId/webhooks/:id | Obter um webhook por ID |
| POST | /api/orgs/:orgId/webhooks | Criar um webhook |
| PATCH | /api/orgs/:orgId/webhooks/:id | Atualizar um webhook |
| DELETE | /api/orgs/:orgId/webhooks/:id | Eliminar um webhook |
Criar um webhook
POST /api/orgs/org_abc123/webhooks
Content-Type: application/json
x-api-key: tkn_xxx{
"url": "https://jouw-server.com/webhooks/tillor",
"subscribedEventKeys": ["invoice:created", "invoice:paid", "customer:updated"],
"enabled": true
}- url - Endpoint HTTPS que aceita pedidos POST
- subscribedEventKeys - Array de chaves de eventos ou
["*"]para todos os eventos. A lista completa está no Tillor em Conta → Programadores, em Adicionar webhook → Eventos subscritos.
Alguns eventos ocorrem com tanta frequência que não os pode escolher e que também não chegam através de *, como o estado físico das cancelas, a escrita na caixa de entrada, os registos de controladores e a presença de veículos. Esses não constam da lista abaixo. Os eventos que pode escolher dependem também das suas permissões.
- enabled -
truepara ativar a entrega
Só pode escolher eventos para os quais o seu membro da organização tenha a permissão adequada (por ex. transações bancárias para bankAccountTransaction:*). O wildcard * só está disponível para membros com acesso total (*). Perante uma combinação inválida, a API devolve um erro. Um webhook reencaminha o payload completo, com os dados associados (como o cliente numa reserva). Por isso, tem de poder ler também esses domínios para criar um webhook, alterar o URL ou os eventos, ou voltar a ativá-lo.
Payload do webhook
Cada entrega de webhook é um POST com:
Cabeçalhos:
Content-Type: application/jsonX-Webhook-Event-ID- ID único estável desta entrega lógica (o mesmo valor nas novas tentativas)X-Webhook-Signature- assinatura HMAC-SHA256 do corpo, formatosha256=<hex>(consulte Verificar a assinatura)
Corpo:
{
"event": "invoice:created",
"data": {},
"timestamp": 1735689600000,
"traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
"spanId": "00f067aa0ba902b7",
"triggeredBy": {
"id": "usr_63x8jp68is",
"name": "Niels"
}
}| Campo | Tipo | Descrição |
|---|---|---|
event | string | Chave do evento (por ex. invoice:created) |
data | object | Payload específico do evento |
timestamp | number | Unix timestamp (ms) em que o evento foi emitido |
traceId | string | ID de trace OpenTelemetry da ação do Tillor que causou este evento. Indique-o ao suporte; não é um segredo. |
spanId | string (opcional) | Span dentro desse trace |
triggeredBy | object | null | Utilizador que executou a ação (id, name). null em ações do sistema (cron, sincronização bancária, …) |
Consulte Exemplos para exemplos completos de payload.
Verificar a assinatura
Cada webhook tem o seu próprio segredo de assinatura (64 carateres hexadecimais, visível na tabela de webhooks em Mostrar segredo de assinatura em Conta → Programadores). O Tillor assina cada POST com esse segredo para que possa verificar que o pedido vem mesmo do Tillor e que o corpo não foi alterado.
Como o Tillor assina:
- Calcula
HMAC-SHA256(signingSecret, raw_request_body)(hexadecimal em minúsculas). - Envia-o como
X-Webhook-Signature: sha256=<hex>.
Como verifica:
- Leia o corpo bruto do pedido (antes do parse de JSON - caso contrário o hash não coincide).
- Calcule você mesmo
HMAC-SHA256(signingSecret, raw_body)em hexadecimal. - Compare com o valor a seguir a
sha256=no cabeçalhoX-Webhook-Signaturecom uma comparação de tempo constante.
import crypto from "node:crypto";
function verifyTillorWebhook(rawBody, headerSignature, signingSecret) {
const expected = crypto.createHmac("sha256", signingSecret).update(rawBody).digest("hex");
const received = headerSignature.replace(/^sha256=/, "");
const a = Buffer.from(expected, "hex");
const b = Buffer.from(received, "hex");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}Trate o segredo como uma palavra-passe
Pode mostrar o segredo de assinatura no Tillor através de Mostrar segredo de assinatura na tabela de webhooks. Guarde-o como segredo (variável de ambiente, cofre) e nunca o registe em logs. Suspeita de uma fuga? Elimine o webhook e crie um novo; assim obtém um novo segredo.
Comportamento de entrega e novas tentativas
- Responda com um estado 2xx para confirmar o sucesso.
- Numa entrega falhada (não 2xx, erro de rede ou destino bloqueado), o Tillor volta a tentar a entrega automaticamente com intervalos cada vez maiores. Cada tentativa reutiliza o mesmo payload, a mesma assinatura e o mesmo ID de evento (idempotente).
| Tentativa | Tempo de espera desde a tentativa anterior |
|---|---|
| 1 | de imediato |
| 2 | 1 segundo |
| 3 | 2 segundos |
| 4 | 4 segundos |
| 5 | 8 segundos |
| 6 | 5 minutos |
| 7 | 30 minutos |
| 8 | 2 horas |
| 9 | 6 horas |
| 10 | 24 horas |
- Se uma das tentativas tiver sucesso (2xx) → a entrega está concluída.
- Se também a tentativa 10 (após 24 h) falhar → a entrega é marcada definitivamente como falhada e não volta a ser tentada.
- Se entretanto o webhook for desativado, o Tillor deixa de tentar de novo.
Idempotência
Cada nova tentativa reutiliza o mesmo X-Webhook-Event-ID e o mesmo X-Webhook-Signature. Elimine duplicados do seu lado com base nesse cabeçalho, para que uma nova tentativa bem-sucedida após um 200 lento não cause processamento duplicado.
Notificações em caso de falhas persistentes
Se as entregas de um endpoint de webhook continuarem a falhar, o Tillor envia no máximo duas notificações por incidente (por endpoint):
- Após 5 minutos de falhas persistentes - e-mail para o endereço de e-mail da organização (
supportEmail, caso contrárioemail) e para os membros da organização com direitos para alterar as definições da organização, mais push (se estiver ativado) para esses membros. O e-mail indica desde quando as entregas falham. As datas no e-mail usam o fuso horário de Definições > Geral (por defeitoEurope/Brussels). - Em caso de falha definitiva - os mesmos destinatários recebem uma notificação quando o primeiro evento desse incidente é marcado como definitivamente falhado após todas as tentativas.
Não recebe uma notificação por cada evento falhado. Assim que todas as entregas falhadas de um endpoint forem resolvidas (entregues com sucesso), um incidente seguinte recomeça com as mesmas regras.
Em Conta → Programadores, a tabela de webhooks mostra por endpoint um estado de entrega compacto (números de entregas à espera de nova tentativa e definitivamente falhadas). Clique no ícone ℹ para detalhes, incluindo a mensagem de erro completa e o payload da tentativa mais recente.
- Repetir entregas falhadas (↻): apenas as entregas definitivamente falhadas desse webhook.
- Forçar repetição (⚡): todas as entregas em espera e definitivamente falhadas desse webhook, independentemente dos tempos de espera planeados. O Tillor inicia isto em segundo plano para que filas grandes (por ex. milhares de eventos) sejam processadas em segurança.
- Forçar repetição de todos, em cima à direita ao lado de Adicionar webhook: o mesmo para todos os webhooks ativados na organização.
Tipos de eventos
As chaves de eventos usam o formato entity:action ou entity:subresource:action. A lista completa, com a permissão de cada evento e um exemplo de payload, está no Índice de eventos. Essa página é gerada a partir do código e por isso está sempre completa. As mesmas chaves estão no Tillor em Conta → Programadores, em Adicionar webhook → Eventos subscritos.
Webhooks vs SSE
| Caso de uso | Recomendação |
|---|---|
| Integração do lado do servidor | Webhooks - O seu servidor recebe POSTs |
| Registo simples | Webhooks - Configuração mínima |
| Painel em tempo real, atualizações em direto na aplicação | SSE - Uma ligação, baixa latência. |
| Muitos tipos de eventos, filtragem do lado do cliente | SSE - Utilize o parâmetro de consulta events para limitar o tráfego. |
Relacionado
- OpenAPI - Especificação completa da API
- API HTTP - API REST e chaves de API
- SSE - Os mesmos eventos através de Server-Sent Events
- Automatizações - Enviar mensagens próprias a partir de uma automatização