Overzicht
Ontvang TicketWave-gebeurtenissen als ondertekende HTTP-verzoeken in je eigen applicatie.
Webhooks
Een webhook is een HTTP-verzoek dat TicketWave naar jou stuurt. Telkens wanneer er iets gebeurt op je server — een ticket wordt geopend, een lid wordt op de zwarte lijst gezet — doet TicketWave een POST met een JSON-body naar een URL van jou.
Dat is het verschil met Log Channels: log channels schrijven een embed naar Discord zodat mensen het kunnen lezen, terwijl webhooks het ruwe event rechtstreeks aan je code doorgeven.
Webhooks zijn een premium functie. Zonder premium kunnen er geen endpoints worden aangemaakt en worden er geen events afgeleverd.
Een endpoint aanmaken
Open de endpoints-pagina
Server dashboard → Webhooks → Endpoints.
Voeg een endpoint toe
Klik op Add Endpoint en vul twee velden in:
| Field | Description |
|---|---|
| Endpoint URL | De https://-URL die de verzoeken ontvangt |
| Event Types | Welke events dit endpoint moet ontvangen |
Een endpoint ontvangt alleen de types die je aanvinkt. Niets selecteren is niet toegestaan — kies er minstens één.
Kopieer het signing secret
TicketWave genereert een signing secret (whsec_…) op het moment dat het endpoint wordt aangemaakt. Open de lijst met endpoints, toon het met het oog-icoon en kopieer het naar de configuratie van je applicatie.
Behandel het secret als een wachtwoord. Iedereen die het heeft, kan verzoeken vervalsen die je signature-check doorstaan. Bewaar het in een environment variable, nooit in je repository.
Stuur een testevent
Gebruik de knop Send test event (het papieren vliegtuigje) op de rij van het endpoint. Daarmee wordt een echt, volledig ondertekend verzoek afgeleverd met "test": true in de payload, zodat je kunt controleren of je ontvanger werkt voordat een echte ticket erop afhankelijk is.
Het resultaat verschijnt in de Webhooks-geschiedenis, net als elke andere levering.
Vereisten voor endpoints
| Requirement | Detail |
|---|---|
| Scheme | Alleen https:// — http:// wordt geweigerd |
| Host | Moet publiek resolvable zijn. Private, loopback-, link-local- en CGNAT-adressen worden geweigerd |
| Response | Elke 2xx-status telt als succes |
| Timeout | Je hebt 10 seconden om te reageren |
| Redirects | Worden niet gevolgd. Een 3xx telt als mislukking |
| Limit | Maximaal 5 endpoints per server |
De host-check gebeurt zowel wanneer je het endpoint opslaat als vóór elke afzonderlijke levering, dus een domein dat later naar een intern adres begint te resolven, krijgt geen leveringen meer.
Het verzoek
Elke levering is een POST met een JSON-body.
Headers
| Header | Example | Meaning |
|---|---|---|
Content-Type | application/json | Altijd JSON |
User-Agent | TicketWave-Webhooks/1.0.5 | De botversie die het heeft verzonden |
X-TicketWave-Event | ticket.created | Het eventtype |
X-TicketWave-Delivery | wh_3f2a… | Unieke id voor deze levering |
X-TicketWave-Timestamp | 1786224191 | Unix-seconden, onderdeel van de signature |
X-TicketWave-Signature | sha256=9f86d0… | HMAC van het verzoek |
Body
Elke payload gebruikt dezelfde envelop. Alleen data verschilt per eventtype:
{
"event": "ticket.created",
"timestamp": "2026-08-26T08:23:11.000Z",
"guild_id": "123456789012345678",
"data": {
"ticket_id": "ticket-1042",
"ticket_num_id": 1042,
"channel_id": "998877665544332211",
"category": "🤖 Support",
"user": { "id": "987654321098765432", "username": "Luna" },
"created_at": "2026-08-26T08:23:11.000Z"
}
}Zie de Event Reference voor het data-object van elk type.
De signature verifiëren
Iedereen die je endpoint-URL ontdekt, kan er een POST-verzoek naartoe sturen. De signature is hoe je een echte TicketWave-levering onderscheidt van een vervalste.
Altijd verifiëren. Een niet-geverifieerd endpoint dat dingen aanmaakt of sluit in je systeem is een open deur.
Hoe de signature wordt opgebouwd
TicketWave voegt de timestamp en de ruwe request-body samen met een punt, en voert daar HMAC-SHA256 op uit met je endpoint secret:
signed_payload = X-TicketWave-Timestamp + "." + raw_request_body
signature = HMAC_SHA256(signed_payload, your_endpoint_secret)De header bevat die digest hex-gecodeerd en met een prefix: sha256=<digest>.
Wat je ontvanger moet doen
Lees de ruwe body. Verifieer tegen de exacte bytes die je hebt ontvangen. Als je framework eerst JSON parseert en je het daarna opnieuw serialiseert, kunnen de volgorde van keys of de spaties veranderen en zal de digest niet overeenkomen.
Bereken de HMAC opnieuw over timestamp + "." + rawBody met je secret.
Vergelijk in constante tijd (crypto.timingSafeEqual in Node). Een gewone === lekt timinginformatie.
Controleer of de timestamp recent is — vijf minuten tolerantie is een goede standaard. De timestamp zit in de ondertekende payload, dus een aanvaller kan geen oud verzoek hergebruiken met een verse timestamp.
Een volledige implementatie staat op de pagina Example Server.
Retries
Een levering die mislukt, wordt automatisch opnieuw geprobeerd.
| Attempts | 3 (de eerste poging plus 2 retries) |
| Backoff | 1 seconde, daarna 5 seconden |
| Retried on | Netwerkfouten, time-outs, 408, 429 en alle 5xx |
| Not retried on | Alle andere 4xx — die betekenen dat je endpoint het verzoek bewust heeft geweigerd |
Door retries kan je endpoint dezelfde event twee keer ontvangen. Gebruik X-TicketWave-Delivery als idempotency key: onthoud de ids die je al hebt verwerkt en negeer herhalingen.
Leveringen zijn niet geordend. Als twee tickets op hetzelfde moment worden aangemaakt, kunnen de verzoeken in willekeurige volgorde aankomen — gebruik het timestamp-veld in de body als volgorde voor jou belangrijk is.
Leveringsgeschiedenis
Op de Webhooks-pagina van het dashboard staat elke levering met status, responsecode, duur en aantal pogingen. Open een rij om de exacte request-payload te zien die is verzonden en de response die je server heeft teruggegeven.
Mislukte leveringen kunnen vanaf de detailpagina opnieuw worden verzonden met Retry Webhook. Daarmee wordt dezelfde originele payload opnieuw naar hetzelfde endpoint gestuurd en wordt een nieuwe levering geregistreerd.
De geschiedenis wordt 30 dagen bewaard en daarna automatisch opgeruimd.
Problemen oplossen
| Problem | Fix |
|---|---|
| Het endpoint kan niet worden opgeslagen | De URL moet https:// zijn en naar een publiek adres resolven |
| Alles wordt als mislukt weergegeven zonder responsecode | Het verzoek heeft je nooit bereikt — time-out, DNS-fout of verbinding geweigerd |
| Signature komt nooit overeen | Je hasht de geparseerde body in plaats van de ruwe bytes, of je bent het timestamp + "."-voorvoegsel vergeten |
| Leveringen stoppen na een tijdje | Controleer of je host 4xx is gaan teruggeven — die worden niet opnieuw geprobeerd |
| Een event komt nooit aan | Het endpoint is niet geabonneerd op dat type, of de server heeft premium verloren |
| Dubbele events | Verwacht bij retries — dedupliceer op X-TicketWave-Delivery |
Volgende stappen
- Event Reference (Elk event en de bijbehorende payload)
- Example Server (Een uitvoerbare Express-ontvanger)
- Log Channels (Dezelfde events, maar gepost in Discord)
How is this guide?
