Skip to Content

Webhooks

Ontvang realtime events via HTTP POST naar jouw endpoint

Laatst bijgewerkt op

Webhooks ontvangen realtime events via HTTP POST naar een door jou geconfigureerde URL. Dezelfde events zijn ook beschikbaar via SSE. Webhooks zijn per organisatie geconfigureerd - elke organisatie heeft zijn eigen webhooks.

Beheer

Zie de OpenAPI-specificatie voor volledige request- en response-schema's.

MethodPadBeschrijving
GET/api/orgs/:orgId/webhooksWebhooks ophalen
GET/api/orgs/:orgId/webhooks/delivery-statsLeveringsstatistieken ophalen
POST/api/orgs/:orgId/webhooks/retry-deliveriesLeveringen opnieuw proberen. Body: mode (failed of force) en optioneel id voor één webhook. failed: alleen definitief mislukte leveringen, direct. force: wachtende en definitief mislukte leveringen op de achtergrond, negeert wachttijden.
GET/api/orgs/:orgId/webhooks/:idWebhook op ID ophalen
POST/api/orgs/:orgId/webhooksWebhook aanmaken
PATCH/api/orgs/:orgId/webhooks/:idWebhook bijwerken
DELETE/api/orgs/:orgId/webhooks/:idWebhook verwijderen

Webhook aanmaken

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 - HTTPS-endpoint die POST-requests accepteert
  • subscribedEventKeys - Array van event keys of ["*"] voor alle events. De volledige lijst staat in Tillor onder Profielmenu → Ontwikkelaars bij Webhook toevoegen → Geabonneerde gebeurtenissen.

Een paar events komen zo vaak voor dat je ze niet kunt kiezen en dat ze ook niet via * aankomen, zoals de fysieke staat van barrières, het typen in de inbox, controller-logs en voertuigaanwezigheid. Die staan niet in de lijst hieronder. Welke events je kunt kiezen, hangt ook af van je permissies.

  • enabled - true om levering in te schakelen

Je mag alleen events kiezen waarvoor je organisatielid de juiste permissie heeft (bijv. banktransacties voor bankAccountTransaction:*). Wildcard * is alleen beschikbaar voor leden met volledige toegang (*). Bij een ongeldige combinatie geeft de API een foutmelding. Een webhook stuurt de volledige payload door, met de gekoppelde gegevens (zoals de klant bij een reservatie). Daarom moet je ook die domeinen mogen lezen om een webhook aan te maken, de URL of events te wijzigen of hem weer in te schakelen.


Webhook-payload

Elke webhook-levering is een POST met:

Headers:

  • Content-Type: application/json
  • X-Webhook-Event-ID - stabiele unieke ID voor deze logische levering (zelfde waarde bij retries)
  • X-Webhook-Signature - HMAC-SHA256 handtekening van de body, formaat sha256=<hex> (zie Handtekening verifiëren)

Body:

{
  "event": "invoice:created",
  "data": {},
  "timestamp": 1735689600000,
  "traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
  "spanId": "00f067aa0ba902b7",
  "triggeredBy": {
    "id": "usr_63x8jp68is",
    "name": "Niels"
  }
}
VeldTypeBeschrijving
eventstringEvent key (bijv. invoice:created)
dataobjectEvent-specifieke payload
timestampnumberUnix timestamp (ms) wanneer het event werd uitgezonden
traceIdstringOpenTelemetry trace-id van de Tillor-actie die dit event veroorzaakte. Geef deze door bij support; het is geen geheim.
spanIdstring (optioneel)Span binnen die trace
triggeredByobject | nullGebruiker die de actie uitvoerde (id, name). null bij systeemacties (cron, bank-sync, …)

Zie Voorbeelden voor volledige payload-voorbeelden.


Handtekening verifiëren

Elke webhook bevat een eigen signing secret (64 hex-karakters, zichtbaar in de webhooktabel via Ondertekeningssleutel tonen op Profielmenu → Ontwikkelaars). Tillor ondertekent elke POST met die secret zodat jij kunt verifiëren dat het verzoek écht van Tillor komt en dat de body niet is aangepast.

Hoe Tillor ondertekent:

  1. Bereken HMAC-SHA256(signingSecret, raw_request_body) (lowercase hex).
  2. Stuur dat als X-Webhook-Signature: sha256=<hex>.

Hoe jij verifieert:

  1. Lees de ruwe request-body (vóór JSON-parsen - anders matcht de hash niet).
  2. Bereken zelf HMAC-SHA256(signingSecret, raw_body) in hex.
  3. Vergelijk met de waarde achter sha256= uit de X-Webhook-Signature header met een constant-time vergelijking.
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);
}

Behandel de secret als wachtwoord

De signing secret kun je in Tillor tonen via Ondertekeningssleutel tonen in de webhooktabel. Sla 'm op als secret (env var, vault) en log 'm nooit. Vermoed je een lek? Verwijder de webhook en maak een nieuwe aan; daarmee krijg je een nieuwe secret.


Leveringsgedrag en retries

  • Antwoord met een 2xx-status om succes te bevestigen.
  • Bij een mislukte levering (niet-2xx, netwerkfout of geblokkeerd doel) probeert Tillor de levering automatisch opnieuw met steeds langere tussenpozen. Elke poging hergebruikt dezelfde payload, dezelfde handtekening en hetzelfde event-id (idempotent).
PogingWachttijd sinds vorige poging
1direct
21 seconde
32 seconden
44 seconden
58 seconden
65 minuten
730 minuten
82 uur
96 uur
1024 uur
  • Slaagt één van de pogingen (2xx) → de levering is afgerond.
  • Slaagt ook poging 10 (na 24u) niet → de levering wordt definitief gemarkeerd als mislukt en niet verder geprobeerd.
  • Wordt de webhook intussen uitgeschakeld, dan stopt Tillor met opnieuw proberen.

Idempotentie

Elke retry hergebruikt dezelfde X-Webhook-Event-ID en X-Webhook-Signature. Dedupliceer aan jouw kant op die header zodat een succesvolle retry na een trage 200 geen dubbele verwerking veroorzaakt.

Meldingen bij aanhoudende fouten

Als leveringen voor een webhook-endpoint blijven mislukken, stuurt Tillor maximaal twee meldingen per incident (per endpoint):

  1. Na 5 minuten aanhoudende fouten - e-mail naar het organisatie-e-mailadres (supportEmail, anders email) en naar organisatieleden met rechten om organisatie-instellingen te wijzigen, plus push (indien ingeschakeld) voor die leden. De e-mail vermeldt sinds wanneer de leveringen mislukken. Datums in de e-mail gebruiken de tijdzone uit Instellingen > Algemeen (standaard Europe/Brussels).
  2. Bij definitieve mislukking - dezelfde ontvangers krijgen één melding wanneer het eerste event in dat incident na alle pogingen definitief mislukt is gemarkeerd.

Je krijgt geen melding per mislukt event. Zodra alle mislukte leveringen voor een endpoint zijn opgelost (succesvol afgeleverd), start een volgend incident opnieuw met dezelfde regels.

Op Profielmenu → Ontwikkelaars toont de webhooktabel per endpoint een compacte leveringsstatus (aantallen wachtend op opnieuw proberen en definitief mislukt). Klik op het ℹ-icoon voor details, inclusief de volledige foutmelding en de payload van de meest recente poging.

  • Mislukte opnieuw proberen (↻): alleen definitief mislukte leveringen voor die webhook.
  • Forceer opnieuw proberen (⚡): alle wachtende én definitief mislukte leveringen voor die webhook, ongeacht geplande wachttijden. Tillor start dit op de achtergrond zodat grote wachtrijen (bijv. duizenden events) veilig verwerkt worden.
  • Alles forceer opnieuw proberen rechtsboven naast Webhook toevoegen: hetzelfde voor alle ingeschakelde webhooks in de organisatie.

Event types

Event keys gebruiken het formaat entity:action of entity:subresource:action. De volledige lijst, met de permissie per event en een voorbeeld-payload, staat in de Event-index. Die pagina wordt uit de code gegenereerd en is dus altijd volledig. Dezelfde keys staan in Tillor onder Profielmenu → Ontwikkelaars bij Webhook toevoegen → Geabonneerde gebeurtenissen.


Webhooks vs SSE

Use caseAanbeveling
Server-side integratieWebhooks - Jouw server ontvangt POSTs
Eenvoudige loggingWebhooks - Minimale setup
Realtime dashboard, live updates in appSSE - Eén verbinding, lage latentie.
Veel event types, client-side filterenSSE - Gebruik events query-param om verkeer te beperken.

Gerelateerd

  • OpenAPI - Volledige API-specificatie
  • HTTP API - REST API en API-sleutels
  • SSE - Zelfde events via Server-Sent Events
  • Automatiseringen - Eigen berichten versturen vanuit een automatisering
Was deze pagina nuttig?

Op deze pagina