POST /webhooks.
Event catalog
*
officialId on position.released is present only for in-app releases; API-driven unassigns omit it. Several official.* payloads likewise vary by origin — treat fields beyond the ones guaranteed above as optional.
Some events (game.completed, official.no_show, payment.*) are produced only by in-app actions — webhooks are the only way an integration observes them.
Delivery format
Every delivery is aPOST with body:
Signature verification
Your endpoint’ssecret (whsec_…) is returned once, in the POST /webhooks response. Verify every delivery by recomputing the HMAC over the exact raw body (before any JSON parsing) and comparing in constant time:
Retries and deduplication
- The first attempt is immediate (8-second timeout). Any
2xxfrom you counts as delivered. - On failure, retries follow this backoff: 1m, 5m, 30m, 2h, 6h, 12h — 7 attempts total over roughly 20 hours, then the delivery is marked
exhaustedand dropped. - Retries re-send the byte-identical payload with the same
X-Whistle-Deliveryid — idempotent processing keyed on that header is safe. - Respond
2xxfast (enqueue, then process async). Slow handlers risk the 8-second timeout, which counts as a failure. - Inspect history anytime:
GET /webhooks/{webhookId}/deliveriesshows status, attempts, your last HTTP status, and the exact payload.
Secure receiver example
Managing endpoints
- Register:
POST /webhooks(HTTPS URLs only; emptyevents= all events). The endpoint’ssourceis derived from your key. - List:
GET /webhooks(secrets never shown). - Delete:
DELETE /webhooks/{webhookId}— destructive; delivery history goes with it. - There is no update, pause, or secret-rotation endpoint — to rotate a secret or change the URL/events, register a new endpoint, cut over, then delete the old one.
source: you see and manage only your own endpoints (anyone else’s answer 404 endpoint_not_found, same as nonexistent ones), and fan-out is scoped — your endpoints receive events only for leagues your key can read.
