Skip to content
RaceHooks for Research & Teaching

Race history
for reproducible research.

Free public archive access with canonical driver and constructor identifiers. Results extend back to 1950; lap timing, stints, pit stops and weather have narrower, era-dependent coverage. Check the historical reference and record your request, retrieval date and returned coverage.

Lap-level recordsEXAMPLE UI
historical/:season/:round/lapsEXAMPLE ROW SHAPE
CarLapPosTimeCompound
VER1P11:33.402MEDIUM
LEC1P21:34.117MEDIUM
NOR1P31:34.640HARD
PIA1P41:35.008HARD
01 · What you build

What researchers and students build on RaceHooks

Reproducible datasets for papers

Publish the exact HTTP requests and save the responses used in your study, so a reviewer can inspect the collection process and reproduce your analysis. Driver and constructor identity is canonical across every season, so a merge across eras does not silently mismatch on a renamed team.

Built from
historical/seasonshistorical/:season/:round/resultshistorical/:season/:round/laps

Teaching datasets & student projects

A course needs data that is interesting, well-shaped, and available on the first evening without a procurement conversation. Results across seven decades, plus lap times, stints and pit stops where covered are enough for a term of regression, time-series, survival analysis, or classification work.

Built from
historical/:season/:round/lapshistorical/:season/:round/pitstopshistorical/:season/driverStandings

ML training corpora

Lap-level records with the context that makes them modellable — compound and tyre age, weather on the same clock, and the classification each session ended in. Enough structure to train on without spending the first month reconciling identities.

Built from
historical/:season/:round/stintshistorical/:season/:round/weatherdata/circuits

Sports science & engineering studies

Reliability by constructor, career trajectories by driver, circuit-by-circuit records, and per-round weather — the joins a study usually spends its first month building, already made and already keyed.

Built from
historical/constructors/:constructorId/reliabilityhistorical/drivers/:driverId/careerhistorical/circuits
02 · What your users see

One payload, straight onto the screen

What a research use of this actually looks like: a table you can join, a record you can cite, and the identity contract that makes both safe.

Why it reproducesEXAMPLE UI
REQUESTThe collection step is one HTTP call
Not a scraper against a page that has since been redesigned. Save the request parameters, retrieval date and response used in your methods.
SCHEMAThe same shape across every season
Results use a consistent schema; detailed timing fields vary by era and session. Check missingness before building a cross-era panel.
IDENTITYCanonical driver and constructor ids
Join on documented driverId and constructorId values; review identity mappings when your study spans renamed or reorganized teams.
Free archive access — no card, no expiry Cite the endpoint, parameters and access date; preserve your retrieved data for reproduction.

The difference between a dataset a reviewer can re-derive and one they have to take on trust is entirely in these three steps.

Where the free tier endsEXAMPLE UI
# limits
RH
racehooksAPP$0
FREE — the historical archive
Results, qualifying, laps, stints, pit stops, standings, weather. No expiry.
RH
racehooksAPP$0
FREE — live session state
Session status, track status, lap count, driver list, and weather during a session.
RH
racehooksAPPstep up
DEVELOPER — when a project gets users
The full live catalog by webhook or SSE, a flat price with no delivery limits, and higher rate limits.

Stated up front rather than discovered at a rate limit. Everything a study needs from the archive is on the free tier; the paid step is about live delivery volume, not about access to history.

↑ all of it, from this payload
GET /v1/historical/2024/1/laps — one request, a stable schema
{
  "season": 2024,
  "round": 1,
  "laps": [
    {
      "lap": 1,
      "driverId": "verstappen-max",
      "constructorId": "red-bull",
      "position": 1,
      "time": { "display": "1:33.402", "ms": 93402 }
    }
  ]
}

# driverId and constructorId are canonical and stable across seasons — the same
# ids the live feeds use. A join across eras keys on those, never on a name string.

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/historical/seasonsEvery season in the archive — the index a collection script starts from.
GET/v1/historical/:season/:round/resultsFinal classification for a round, with qualifying, sprint, and practice on sibling routes.
GET/v1/historical/:season/:round/lapsLap-by-lap times for a session — the row-level table most studies are actually built on.
GET/v1/historical/:season/:round/stintsCompound and stint plan per driver, with pitstops and weather on sibling routes for the same round.
GET/v1/historical/drivers/:driverId/careerA driver's full career record; the constructors routes carry the equivalent, including reliability by season.
GET/v1/historical/circuitsCanonical circuit identity and the rounds each has held — the key a cross-era join needs.
Feeds you subscribe to
session.statusSession lifecycle — started, aborted, finished, finalised. Free, and enough to timestamp a collection run.
session.track-statusGreen, yellow, safetyCar, red — one named status. Free, and the covariate most race models want.
session.lap-countCurrent lap and laps remaining. Free.
driver.listNumber, TLA, full name, team and team colour — the canonical identity every other payload keys to. Free.
weather.dataAir and track temperature, humidity, pressure, wind, and rainfall. Free, and on the same clock as the laps.
timing.dataPosition, gaps, lap and sector times, live. The Developer step up, when a study needs the session as it runs.

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 research 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 research

The archive above is free and stays free. Custom exists for work that needs the modelled layer or the raw channels underneath it — normally a lab with a grant, an industrial partner, or a licensing question. Model outputs publish only on supported sessions, schedules and eligible race states. Review the output contracts and evaluation scope with us.

Mini-sector timing

timing.mini-sectors is the high-granularity companion to lap timing — mini-sector progress ticks and speed-trap detail, for work where a lap is too coarse a unit.

Model outputs as a comparison baseline

The analytics feeds carry our own fitted surfaces — position distributions, true pace, tyre state — which is the honest thing to benchmark a new method against rather than a naive baseline.

Full-archive replay

Self-serve replay is capped at distinct current-season sessions. Custom lifts it to the whole archive, which matters when the object of study is the sequence rather than the table.

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