Webhooks

Webhook event

POST{your endpoint URL}All plans

One request per event and endpoint. Types: fixture.score (a side’s current score changed) and fixture.status (kick-off, a new period, a break, full time, postponed, canceled) for every live fixture your filters match; fixture.events (match events added, corrected or removed — goals with scorers, cards, substitutions) and fixture.lineups (from about 90 minutes before kick-off — the official lineups, usually out an hour before — and their changes in play) only for fixtures you name in the endpoint’s fixture ids; ping is the dashboard’s test. data.changes is the same partial Fixture as a WebSocket delta.

Verify every request: SportsAPI-Signature is t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>"> with the endpoint’s signing secret (shown once when you create or rotate it) — compare in constant time and reject a t older than a few minutes. Answer 2xx within 10 seconds; anything else (a redirect included) is retried after 10 s, 1 min, 5 min, 30 min, 2 h and 6 h, then marked failed. An endpoint that fails every attempt for 24 hours is disabled (re-enable it in the dashboard). Deliveries are not strictly ordered: use createdAt and the event id (also in SportsAPI-Event-Id) to drop duplicates. Only public https:// hosts are accepted.

Every /v2 call can also answer the common errors.

Example
POST https://your-server.example.com/sportsapi
SportsAPI-Signature: t=1793551606,v1=5f0c…
SportsAPI-Event: fixture.score
SportsAPI-Event-Id: evt_8a1f…
Content-Type: application/json

{ "id": "evt_8a1f…", "type": "fixture.score", "createdAt": "2026-11-01T16:46:46.208Z",
  "data": { "fixtureId": 211521, "sport": "football", "leagueId": 17,
            "changes": { "homeScore": { "current": 1, "periods": { "period1": 1 } } } } }

// Node: verify the signature
const [t, v1] = header.split(',').map((p) => p.split('=')[1]);
const expected = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
const ok = crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected)) && Date.now() / 1000 - Number(t) < 300;