API Reference

API Reference

The RaceHooks API is a REST API returning JSON. All requests are authenticated via Bearer token and versioned under /v1. The API is sport-agnostic at the infrastructure level — feeds, webhooks, and simulate endpoints will serve all supported sports as the platform expands beyond F1.

Base URLhttps://api.racehooks.io/v1

Authentication

RaceHooks uses OAuth 2.0 client credentials. Exchange your client_id and client_secret (from the console Keys page) for a Bearer token. All other endpoints require this token in the Authorization header. Tokens expire after 24 hours.

POST/v1/oauth
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"
  }'

# Response
{
  "token":     "eyJhbGc...",
  "expiresAt": "2026-06-07T12:00:00Z"
}

# All subsequent requests:
curl https://api.racehooks.io/v1/webhooks \
  -H "Authorization: Bearer eyJhbGc..."

Webhooks

Create, list, update, delete, and test webhook endpoint registrations.

Create a webhook

POST/v1/webhooks
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/f1",
    "feedId": "timingdata",
    "filters": {
      "driverNumbers": ["1", "4", "16"]
    }
  }'
FieldTypeDescription
webhookUrlstring (required)The HTTPS endpoint to receive deliveries. Must be publicly reachable.
feedIdstring (required)The feed to subscribe to. See the feed catalog for valid IDs.
filtersobject (optional){ driverNumbers: string[] } — filter deliveries to specific driver numbers. Empty = all drivers.
The webhookSecret is returned once in the create response. Store it securely — it cannot be retrieved again.

List webhooks

GET/v1/webhooks
json
# Response
{
  "data": {
    "webhooks": [
      {
        "webhookId": "wh_7a3b9c2d",
        "webhookUrl": "https://your-app.com/f1",
        "feedId": "timingdata",
        "active": true,
        "createdAt": "2026-06-01T12:00:00Z"
      }
    ]
  }
}

Update a webhook

PATCH/v1/webhooks/:id
FieldTypeDescription
activeboolean (optional)Pause (false) or resume (true) deliveries to this webhook.

Delete a webhook

DELETE/v1/webhooks/:id

Delivery logs

GET/v1/webhooks/:id/logs
json
# GET /v1/webhooks/:id/logs?limit=50
{
  "data": {
    "logs": [
      {
        "logId": "log_a1b2c3",
        "webhookId": "wh_7a3b9c2d",
        "statusCode": 200,
        "latencyMs": 142,
        "createdAt": "2026-06-01T14:22:31Z",
        "responseBody": "ok"
      }
    ]
  }
}
FieldTypeDescription
limitinteger (query)Number of log entries to return. Default 50, max 500.
cursorstring (query)Pagination cursor from a previous response for the next page.

Send a test delivery

POST/v1/webhooks/:id/test

Sends a synthetic payload to the registered endpoint using sample data. Useful for verifying your endpoint is reachable and signature verification is working.

Rotate webhook secret

POST/v1/webhooks/:id/rotate-secret

Generates a new webhook secret. Both old and new secrets are valid for 60 seconds during the rotation window, then only the new secret is accepted.

Feeds

GET/v1/feeds

Returns all available feeds with their tier requirements, delivery cadence, and descriptions.

json
# GET /v1/feeds
{
  "data": {
    "feeds": [
      {
        "feedId": "timingdata",
        "name": "Timing Data",
        "tier": "starter",
        "cadence": "per_lap",
        "description": "Per-driver lap times, sector times, gaps, and position data."
      },
      {
        "feedId": "cardata",
        "name": "Car Data",
        "tier": "starter",
        "cadence": "270ms",
        "description": "Per-car telemetry: speed, throttle, brake, gear, RPM, DRS state."
      }
    ]
  }
}

Simulate

Replay any historical session against your registered webhooks. Currently supports F1 sessions back to 2018.

Start a simulation

POST/v1/simulate
FieldTypeDescription
sessionIdstring (required)Session ID from GET /v1/events. Format: {year}-{circuit}-{session}, e.g. 2024-british-r1.
speedstring (optional)"1x" | "5x" | "10x". Default: "1x".

Poll simulation status

GET/v1/simulate/:id
bash
# Start a simulation
curl -X POST https://api.racehooks.io/v1/simulate \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "sessionId": "2024-british-r1",
    "speed": "10x"
  }'

# Poll for status
curl https://api.racehooks.io/v1/simulate/sim_9f2c \
  -H "Authorization: Bearer ${TOKEN}"

# Response when complete
{
  "data": {
    "simulationId": "sim_9f2c",
    "status": "completed",
    "eventsDispatched": 48201,
    "deliveriesSent": 48201,
    "successRate": 0.998,
    "completedAt": "2026-06-01T14:35:00Z"
  }
}

Cancel a simulation

DELETE/v1/simulate/:id

Events

GET/v1/events

Returns the race calendar for all supported sports with sessions and their statuses. Currently returns F1 season data. Use this to get sessionId values for the Simulate endpoint, and to detect when live sessions are starting.

json
# GET /v1/events
{
  "data": {
    "events": [
      {
        "eventId": "2026-british",
        "name": "British Grand Prix",
        "circuitName": "Silverstone",
        "round": 12,
        "sessions": [
          {
            "sessionId": "2026-british-q",
            "type": "Qualifying",
            "startDate": "2026-07-05T14:00:00Z",
            "status": "upcoming"
          },
          {
            "sessionId": "2026-british-r1",
            "type": "Race",
            "startDate": "2026-07-06T14:00:00Z",
            "status": "upcoming"
          }
        ]
      }
    ]
  }
}

Usage

Delivery statistics for the authenticated client. All usage data resets at the start of each calendar month.

Summary

GET/v1/usage
FieldTypeDescription
deliveryCountnumberTotal webhook deliveries in the current billing window.
successCountnumberDeliveries that received a 2xx response from your endpoint.
failureCountnumberDeliveries that received a non-2xx response or timed out.
windowStartstringISO 8601 timestamp for the start of the current billing window.

Breakdown by feed

GET/v1/usage/by-feed

Returns per-feed delivery counts. Useful for understanding which feeds are generating the most traffic.

FieldTypeDescription
byFeed[].feedIdstringFeed identifier.
byFeed[].deliveryCountnumberTotal deliveries for this feed in the current window.

Latency percentiles

GET/v1/usage/latency

Returns p50, p95, and p99 delivery latency per feed, measured from when the F1 event was detected to when your endpoint acknowledged it.

FieldTypeDescription
byFeed[].feedIdstringFeed identifier.
byFeed[].p50numberMedian delivery latency in milliseconds.
byFeed[].p95number95th percentile latency in milliseconds.
byFeed[].p99number99th percentile latency in milliseconds.
byFeed[].sampleCountnumberNumber of deliveries included in the sample.

Error codes

All error responses return a JSON body with a message field describing the error.

StatusTitleDescription
400Bad RequestInvalid request body or missing required fields. Check the error message for specifics.
401UnauthorizedMissing or invalid Bearer token. Re-authenticate to get a new token.
403ForbiddenValid token but insufficient tier for this resource (e.g. Analytics feed on Free tier).
404Not FoundThe requested resource (webhook, simulation, etc.) does not exist or belongs to another account.
409ConflictTypically: webhook limit reached for your tier. Upgrade or delete an existing webhook.
429Too Many RequestsRate limit exceeded. See the X-RateLimit-Remaining header. Back off and retry.
503Service UnavailableStripe Checkout/Portal not configured (during beta). Contact support.
← Analytics referenceQuestions? Contact support →