Skip to content
RaceHooks for Fantasy

Live scoring
your users can explain.

Show each scoring component, update provisional scores as the session runs, and build a leaderboard your users can follow. Scoring is included on Developer; predictive model outputs are a separate Custom evaluation.

The core integration below is available on Developer — $99/mo, self-serve.
League standingsEXAMPLE UI
Your leagueRound 16 · Italy
1
Box Box Box
VERNORLEC
141
+28
2
Undercut Club
PIARUSHAM
133
+12
3
Purple Sector
ANTLECALO
118
-4

Italian GP · Before lights-out

Started 19th.
Scored 79.

Our model made Antonelli the top projected finishing scorer from the back of the grid. Antonelli won.

  • Average car starting P19−5.5 pts
  • Model projection for Antonelli+13.2 pts
  • Finishing points scored+25 pts

One race. Finishing points only in the projection; the P19 average is finish, places gained or lost and retirements over 17 starters; the 79 adds places gained, overtakes and fastest lap. Qualifying excluded. Model: RaceHooks.

01 · What you build

What fantasy teams build on RaceHooks

Season-long leagues

Score a full weekend automatically the moment the flag drops — finishing position, qualifying, positions gained and lost, fastest lap, places lost, and DNF penalties, each as a separate line your users can audit. Standings and schedule come from the same API, so a league runs a season without a second data source.

Built from
fantasy/races/:raceId/scoreshistorical/:season/driverStandingshistorical/:season/races

Daily fantasy & salary cap

Price a slate from real history — prior results, qualifying, stints, and pit stops per driver and constructor — then settle it on the same breakdown your users saw all race. Sprint weekends score on the compressed points table automatically via ?session=sprint.

Built from
fantasy/races/:raceId/scores?session=sprinthistorical/:season/:round/resultsfantasy/session/:sessionId/pit-times

Pick'em & prediction games

Settle propositions as they resolve rather than after the race: the race-events feed emits overtakes, retirements, penalties, fastest laps, and lead changes as discrete events, each carrying the driver it belongs to.

Built from
events.racefantasy/session/:sessionId/scores

Live leaderboards & second screen

Subscribe to fantasy.scores and a fresh leaderboard arrives whenever a point actually changes — no polling loop, and a lap ticking over is not a delivery. Take the provisional breakdown as delivered, or run the open-source scorer over race events with your own rules — official-style, DFS-style, or fully custom, with a budget-aware roster optimizer included.

Built from
fantasy.scoresevents.racefantasy/session/:sessionId/scoresracehooks-f1-fantasy-scorer
02 · What your users see

One payload, straight onto the screen

The breakdown object is already shaped like a scoring UI — one number per category, per driver, updating lap by lap. These are the three screens most fantasy products put in front of a user: the detail and the ticker are those fields directly, and a league table is just their totals summed over a roster.

Driver detailEXAMPLE UI
VER · Verstappen
Red Bull Racing
47
Race position
+25
Qualifying
+10
Fastest lap
+10
Positions gained
+2
DNF penalty
0

Every component of `breakdown` on its own line — so a user can see exactly where all 47 points came from, and a disputed score settles itself.

Live in-race scoringEXAMPLE UI
EXAMPLE · PROVISIONALLAP 34/53
LECP125
NORP218
ALORetired · lap 33-20

The provisional session endpoint, polled or pushed — position and DNF components move lap by lap, the rest stay null until the flag.

↑ all of it, from this payload
GET /v1/fantasy/session/2026-italy_r/scores — provisional, mid-race
{
  "data": {
    "sessionId": "2026-italy_r",
    "live": true, "provisional": true,
    "sessionType": "grand_prix",
    "currentLap": 34, "totalLaps": 53,
    "scores": [{
      "driver": "leclerc-charles", "tla": "LEC", "team": "Ferrari",
      "breakdown": {
        "racePosPoints": 25, "beatTeammateRace": 0, "dnfPenalty": 0,
        "qualiPosPoints": null, "q3Bonus": null,
        "positionsGained": null, "positionsGainedPoints": 0,
        "fastestLapPoints": null, "beatTeammateQuali": null,
        "total": 28
      }
    }]
  }
}

Example interfaces, rendered from the fields above: your product, your design system. Nothing here is a template you have to adopt.

03 · Endpoints

The endpoints that build it

Every route is Bearer-authenticated and versioned under /v1. Base URL https://api.racehooks.io/v1.

MethodPathWhat it gives you
GET/v1/fantasy/races/:raceId/scoresFinal estimated fantasy points per driver for a completed Grand Prix, with the full per-component breakdown. ?session=sprint scores the Sprint on its compressed table.
GET/v1/fantasy/session/:sessionId/scoresRunning provisional score while a session is on track. Position and DNF components update lap by lap; grid-derived and fastest-lap components stay null until the flag.
GET/v1/fantasy/session/:sessionId/pit-timesStationary pit-stop times ranked fastest to slowest with the session's fastest stop broken out — the constructor scoring category in most fantasy games.
POST/v1/webhooksSubscribe an endpoint to a feed. Filter to your league's roster at subscription time so you only pay for deliveries you score.
GET/v1/historical/:season/:round/resultsCompleted race results for slate pricing and backfill. Qualifying, laps, stints, pitstops, and fastestlaps sit alongside it.
GET/v1/historical/:season/driverStandingsChampionship standings by season — league context and season-long tiebreaks. constructorStandings mirrors it for teams.
Feeds you subscribe to
events.race40+ synthesized events — overtakes, pit stops, retirements, penalties, fastest laps, lead changes.
fantasy.scoresProvisional points per driver with the full breakdown, pushed when a score changes — the same numbers the fantasy REST routes return.
timing.dataLap and sector times, gaps, and running order — the live position every score is derived from.
pit.stopsPit stops as they complete, for constructor pit-time scoring. pit.lane-times carries the stationary time.
session.infoSession lifecycle — when to open scoring, when to finalise a classification.

Developer includes all 29 live data feeds, not just the ones above; the remaining 26 in the 56-feed catalog are the Custom analytics feeds. Every id, cadence, and payload schema is documented.

04 · Delivery

Three ways the data reaches you

Pick per integration. You can run all three against one API key. Webhook and SSE frames are both counted as deliveries (Free pauses at its monthly limit; Developer has no delivery limit); REST reads count against the request rate limit instead.

Webhook

Push · default

Register an HTTPS endpoint and subscribe it to feeds. RaceHooks POSTs events as source updates arrive. Every payload is HMAC-SHA256 signed, retried with exponential backoff on failure, and every attempt is logged in your console with headers, status, and latency.

POST /v1/webhooks
{ "webhookUrl": "https://your-app.com/hook",
  "feedId": "events.race" }
Best for: Server-side apps, scoring engines, alerting.

SSE stream

Push · no public URL

Open one long-lived connection and read frames as they arrive — no public webhook server to host or expose. Each frame is `event: <feedType>` + a JSON `data:` line, with a ping every 30s so proxies hold the connection open. Auth by Bearer header, or `?token=` for browser EventSource, which cannot set headers.

GET /v1/stream?feeds=raceevent,timingdata
Authorization: Bearer $TOKEN
Best for: Local development, dashboards, browser clients.

REST

Pull · on demand

Query completed and reference data directly whenever you need it: results, standings, laps, stints, pit stops, and the segment endpoints above. Use it to backfill history, hydrate a new user, or reconcile after an outage rather than to follow a live session.

GET /v1/historical/2026/16/results
Authorization: Bearer $TOKEN
Best for: Backfill, reference data, reconciliation.
05 · Before race day

Test the whole thing on a quiet Tuesday

Simulate replays a real current-season session through your own webhooks at any speed from 0.1× to 120×. Your integration receives the exact payloads it would in a live race (real data, known result) so you can validate fantasy logic end to end before a live session ever runs. Free includes 5 sessions, Developer 10; Custom replays the full archive.

How Simulate works →
Model evaluation · Custom

What the ML layer adds for fantasy

Everything above settles points that have already been scored. The ML layer prices what has not happened yet — which is what a projection, a captain pick, and a salary model are actually made of. Model outputs publish only on supported sessions, schedules and eligible race states. Review the output contracts and evaluation scope with us.

Finishing-position distributions

The full probability of every finishing position per driver, not a single projected place — so a projected-points number carries a distribution and a floor/ceiling instead of a point estimate.

Expected place differential

Positions a driver is expected to gain or lose from here, priced live. The positions-gained category is where most slates are won, and it is the hardest one to eyeball from the running order.

DNF risk per driver

A live retirement probability — the −15 that decides a captain pick, and the number a salary model needs to discount a fast car that keeps breaking.

Friday pre-race previews

Projections built from practice pace before lineups lock, so your users set a roster with a model behind it rather than last year's form.

Talk to usRead the model methodology →Delivery volumes, service levels and archive replay are agreed in your contract.

Start on the free tier.

Build and test a complete integration on historical and replayed sessions, with no credit card. Go Developer when you need it live.

Start freeCompare plans