Getting Started

Quickstart

Create a webhook, verify incoming deliveries, and test your integration by replaying the Canadian Grand Prix demo. No credit card required.

Prerequisites
  • A free RaceHooks account: sign up at racehooks.io/signup and verify your email (see the Authentication guide)
  • Your API credentials: client_id and client_secret from the console API Keys page
  • A publicly reachable HTTPS endpoint (localhost and private addresses are rejected (Simulate included), so expose a local server through a tunnel or use a request-capture URL)
  • curl, Node.js, or Python for the API calls below
1

Get your token

Exchange your API client credentials for a Bearer token. Create them on the API Keys page. Use a Bearer token for the authenticated endpoints in this guide. The public historical and IndyCar APIs do not require authentication. Tokens expire after 12 hours.

bash
curl -X POST https://api.racehooks.io/v1/oauth \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "your-client-id",
    "client_secret": "your-client-secret",
    "grant_type": "client_credentials"
  }'

# Response — the token is an opaque string (not a JWT); treat it as a secret
{
  "access_token": "vN3xKq81tYw2LmR9bC6dF7gHjS5aU0eIPo4Z",
  "token_type": "Bearer",
  "expires_in": 43200
}
✦
New here? First create your account and verify your email, then create your API credentials on the API Keys page, or fetch them programmatically with POST /v1/oauth/credentials.
2

Register your webhook

Register an endpoint URL and subscribe it to a feed. This example uses driver.list, a feed open to every plan carrying the session roster, so this call works on a Free account.

ℹ
Live timing feeds like timing.data (lap times, sector times, gaps, positions) require the Developer plan. Subscribing to one on Free returns 402. Free includes five live feeds (session.status, session.track-status, session.lap-count, weather.data, driver.list), 3 endpoints, and 5,000 deliveries a month. Replays follow the same rule: a Simulate run on Free delivers Free feeds only. The exception is the curated demo race (Step 4), which delivers the full Analytics feed set to any plan.
curl -X POST https://api.racehooks.io/v1/webhooks \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "webhookUrl": "https://your-app.com/f1",
    "feedId": "driver.list"
  }'

# Response (abridged)
{
  "data": {
    "webhook": {
      "webhookId": "V1StGXR8_Z5jdHi6B-myT",
      "feedId": "driver.list",
      "seriesId": "f1",
      "webhookUrl": "https://your-app.com/f1",
      "webhookMethod": "post",
      "active": true,
      "subscriptionTier": "free",
      ...
    },
    "webhookSecret": "3f8a9c1d5e7b2f4a6c8d0e1f3a5b7c9d2e4f6a8b0c1d3e5f7a9b1c3d5e7f9a1c",
    "tier": "free"
  }
}
# data.webhookSecret is used to verify signatures
✦
The webhookSecret is returned at creation and used to verify incoming signatures. If you lose it, retrieve it anytime with GET /v1/webhooks/:id/secret, or issue a new one with POST /v1/webhooks/:id/rotate-secret.
3

Handle incoming deliveries

RaceHooks POSTs a JSON payload to your endpoint for every matching event. Every delivery, on every plan (Free included), carries an X-RaceHooks-Signature header, which holds an HMAC-SHA256 signature you can use to verify the payload originated from RaceHooks. It also carries X-RaceHooks-Signature-V1, which signs the send time too, so you can reject replayed deliveries; see Webhooks.

This driver.list payload comes from the Canadian GP demo session (2026-canada_r) replayed in Step 4:

json
{
  "feed": "driver.list",
  "sessionId": "2026-canada_r",
  "utc": "2026-10-05T18:49:56.756Z",
  "drivers": [
    {
      "driverId": "antonelli-kimi",
      "constructorId": "mercedes",
      "number": "12",
      "tla": "ANT",
      "name": "Kimi Antonelli",
      "team": "Mercedes"
    },
    {
      "driverId": "russell-george",
      "constructorId": "mercedes",
      "number": "63",
      "tla": "RUS",
      "name": "George Russell",
      "team": "Mercedes"
    }
  ]
}

To verify the signature:

webhook-handler.ts
// Node.js — verify an incoming RaceHooks delivery
import crypto from 'crypto';

function verifySignature(
  payload: string,              // req.body as raw string
  signature: string | undefined, // X-RaceHooks-Signature header value
  secret: string                // your webhook secret
): boolean {
  if (!signature) return false;
  const expected = Buffer.from(
    'sha256=' + crypto.createHmac('sha256', secret).update(payload, 'utf8').digest('hex')
  );
  const received = Buffer.from(signature);
  // timingSafeEqual throws on unequal lengths, so check first
  return expected.length === received.length && crypto.timingSafeEqual(expected, received);
}
4

Test with Simulate

You don't need to wait for a live race to test. Use Simulate to replay this season's F1 sessions against your registered webhooks at anywhere from 0.1× to 120× real time (default 10×; the console offers 1×, 5×, 10×, 30× and Instant). The full historical archive is on Custom.

bash
# 1. Prepare the artifact (main API, Bearer header)
curl -X POST https://api.racehooks.io/v1/simulate/prepare \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{ "sessionId": "2026-canada_r" }'

# 2. Play it into your webhooks at 10x — on the simulate host, token as a query param
curl "https://simulate.racehooks.io/v1/simulate/stream?session=2026-canada_r&speed=10&sinks=webhook&token=${TOKEN}"

# Deliveries arrive at your endpoint exactly as they would live.
# The demo session is pre-warmed; for other sessions, poll
# GET https://api.racehooks.io/v1/simulate/status?session=<id> until status is "ready".

The simulation host is the one exception to the Bearer header: it takes the token as a token query parameter, as in the second command above. Every other call in this guide uses the Authorization header.

What to expect from the Canadian GP: session.status reports the start, session.lap-count and timing.data follow every lap, and events.race carries the incidents: the pass for the lead on lap 30 and the virtual safety car on lap 31. Every delivery in a replay has X-RaceHooks-Mode: replay, so you can tell it from live data; see a full delivery with headers, the race events reference and the model feeds you can add next.

Replay delivery volume: a replay POSTs every recorded event to every active endpoint (tens of thousands of deliveries for a full race, compressed by the speed multiplier). Free webhook testing services (webhook.site and similar) rate-limit under that load; use speed=1 with a single endpoint for clean samples. The curated demo race additionally delivers the full Analytics feed set to all endpoints regardless of plan. See delivery volume during replays.

You can also start a simulation from the Simulate page in the console. Pick one of this season's races, set the speed, and watch deliveries arrive in your logs in real time.

What's next
Browse all 50+ feeds
See cadences, payload schemas, and access class
→
Build a fantasy leaderboard
Scoring API, pit-time leaderboard, and an open-source scorer (Developer plan)
→
API reference
Full endpoint documentation with request/response schemas
→
Add the analytics feeds
Tyre state, win probability and pit prediction, per driver every lap (Custom plan)
→
Feed catalog →