Skip to main content
Webhooks push game, position, official, and payment changes to your HTTPS endpoint so you don’t have to poll. Register endpoints via 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 a POST with body:
Headers:

Signature verification

Your endpoint’s secret (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:
The signature covers the body only — there is no timestamp component or built-in replay window. A captured delivery could be replayed later and would still verify. Mitigate on your side: deduplicate on X-Whistle-Delivery (which also handles retry duplicates) and treat webhook data as a trigger to re-fetch authoritative state via the REST API rather than as the state itself.

Retries and deduplication

  • The first attempt is immediate (8-second timeout). Any 2xx from 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 exhausted and dropped.
  • Retries re-send the byte-identical payload with the same X-Whistle-Delivery id — idempotent processing keyed on that header is safe.
  • Respond 2xx fast (enqueue, then process async). Slow handlers risk the 8-second timeout, which counts as a failure.
  • Inspect history anytime: GET /webhooks/{webhookId}/deliveries shows status, attempts, your last HTTP status, and the exact payload.

Secure receiver example

Managing endpoints

  • Register: POST /webhooks (HTTPS URLs only; empty events = all events). The endpoint’s source is 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.
Endpoints are owned by your 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.
Last modified on July 10, 2026