Webhooks

Race Events

raceevent is a synthetic feed generated by RaceHooks from live race data. Instead of receiving raw position arrays and computing events yourself, you subscribe once and receive pre-detected, structured events — overtakes, pit stops, safety cars, fastest laps, retirements, and more. This feed is currently available for F1. Equivalent synthetic event feeds for other supported sports will be documented here as they launch.

Feed ID
raceevent
STARTERGENERATED
Cadence: event-driven · available on Starter and above · path: _generated (synthesized — not a direct feed subscription)

Subscribe

bash
curl -X POST https://api.racehooks.io/v1/webhooks \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "webhookUrl": "https://your-app.com/race-events",
    "feedId": "raceevent"
  }'
subscribe.ts
import { RaceHooks } from "racehooks";

const rh = new RaceHooks({
  clientId:     process.env.RACEHOOKS_CLIENT_ID!,
  clientSecret: process.env.RACEHOOKS_CLIENT_SECRET!,
});

// All race events for the entire field
const { webhook, webhookSecret } = await rh.webhooks.create({
  feedId:     "raceevent",
  webhookUrl: "https://your-app.com/race-events",
});

// Overtakes and pit stops for your fantasy team only
await rh.webhooks.create({
  feedId:     "raceevent",
  webhookUrl: "https://scoring.myapp.com/hook",
  filters: { drivers: ["VER", "NOR", "LEC"] },
});

Payload structure

Every raceevent delivery shares a common envelope with an event-specific data object:

FieldTypeDescription
typestringAlways "raceevent" — identifies this as a race event payload.
sessionIdstringUnique identifier for the current F1 session.
eventstringEvent type — one of the 12 types listed below.
lapnumberCurrent race lap number when the event fired.
utcstringISO 8601 timestamp of when the event was detected.
dataobjectEvent-specific data. Schema varies per event type.

Event types

session.startAll

Session status transitions to Started.

json
// data field
{ "sessionType": "Race", "sessionName": "2026 British Grand Prix — Race" }
session.endAll

Session status transitions to Finished or Finalised.

json
// data field
{ "sessionType": "Race", "sessionName": "2026 British Grand Prix — Race" }
overtakeRace / Sprint

A driver gains a position on-track (not via pit strategy).

json
// data field
{
  "driver":       "4",
  "tla":          "NOR",
  "team":         "McLaren F1 Team",
  "fromPosition": 2,
  "toPosition":   1,
  "displaced": {
    "driver": "1",
    "tla":    "VER",
    "team":   "Red Bull Racing"
  }
}
pit.entryAll

Driver enters the pit lane.

json
// data field
{ "driver": "16", "tla": "LEC", "team": "Scuderia Ferrari", "lap": 28 }
pit.exitAll

Driver exits the pit lane.

json
// data field
{
  "driver":    "16",
  "tla":       "LEC",
  "team":      "Scuderia Ferrari",
  "lap":       28,
  "pitCount":  2,
  "durationMs": 23800
}
lead.changeRace / Sprint

The race leader changes.

json
// data field
{
  "driver": "4",
  "tla":    "NOR",
  "team":   "McLaren F1 Team",
  "lap":    34,
  "from": { "driver": "1", "tla": "VER" }
}
safety.car.deployedAll

Safety Car or Virtual Safety Car deployed.

json
// data field
{ "type": "SC", "lap": 21 }  // type: "SC" | "VSC"
safety.car.clearedAll

Safety Car period ending or cleared.

json
// data field
{ "type": "SC", "lap": 23 }
fastest.lapAll

A new session fastest lap is set.

json
// data field
{
  "driver":    "1",
  "tla":       "VER",
  "team":      "Red Bull Racing",
  "lap":       44,
  "lapTimeMs": 89441,
  "lapTime":   "1:29.441"
}
retirementAll

A driver retires from the session.

json
// data field
{
  "driver": "14",
  "tla":    "ALO",
  "team":   "Aston Martin F1 Team",
  "lap":    31
}
qualifying.hot_lap.startedQualifying / Sprint Shoot-out

A driver begins a timed flying lap in qualifying.

json
// data field
{
  "driver": "1",
  "tla":    "VER",
  "team":   "Red Bull Racing",
  "lap":    5
}
qualifying.hot_lap.abortedQualifying / Sprint Shoot-out

A driver abandons their flying lap (slows, pits, yellow flag).

json
// data field
{
  "driver": "1",
  "tla":    "VER",
  "team":   "Red Bull Racing",
  "lap":    5
}

Handle deliveries

race-events-handler.ts
// Express endpoint
app.post("/race-events", express.raw({ type: "application/json" }), (req, res) => {
  const payload = JSON.parse(req.body.toString());

  switch (payload.event) {
    case "overtake":
      console.log(`${payload.data.tla} overtook ${payload.data.displaced.tla} for P${payload.data.toPosition}`);
      break;
    case "pit.entry":
      console.log(`${payload.data.tla} into the pits on lap ${payload.data.lap}`);
      break;
    case "fastest.lap":
      console.log(`Fastest lap: ${payload.data.tla} ${payload.data.lapTime}`);
      break;
    case "safety.car.deployed":
      console.log(`${payload.data.type} deployed on lap ${payload.data.lap}`);
      break;
    case "retirement":
      console.log(`${payload.data.tla} has retired on lap ${payload.data.lap}`);
      break;
  }
  res.sendStatus(200);
});

Filtering race events

Use filters.drivers to scope race events to specific drivers. This is especially useful for fantasy scoring engines or fan apps that only care about a specific team or driver combination.

Position filters (positions.min / positions.max) are not applied to raceevent deliveries, since events like safety.car.deployed are session-wide and have no single position to filter on.
← WebhooksNode.js SDK →