A webhook is a registered endpoint URL paired with a feed subscription. RaceHooks POSTs a JSON payload to that URL for every matching event during a live session. The webhook infrastructure is sport-agnostic — the same endpoint, signature verification, and filter system works across every sport RaceHooks supports. Each webhook is scoped to a single feed, and you can apply filters to narrow which events trigger a delivery.
Lifecycle
Webhooks have three operational states:
activeDeliveries are sent for every matching event. This is the default state after creation.
pausedNo deliveries are sent. The webhook remains registered and can be resumed at any time without losing configuration.
deletedPermanently removed. All logs are retained for 90 days after deletion.
Create a webhook
Each webhook subscribes to exactly one feed. To receive multiple feeds at the same endpoint, create one webhook per feed. The webhookSecret is returned once at creation time — store it immediately.
The webhookSecret is shown exactly once. If you lose it, rotate it from the webhook detail page or via POST /v1/webhooks/:id/rotate-secret. The old secret continues working for 60 seconds after rotation to allow in-flight deliveries to complete.
Request fields
Field
Type
Description
webhookUrl
string
Your HTTPS endpoint URL. Must be publicly reachable. Localhost is supported during Simulate replays.
feedId
string
The feed to subscribe to. See Feed catalog for all available IDs.
webhookMethod
string?
HTTP method for deliveries. Defaults to POST. Can be PUT.
filters
object?
Optional delivery filter. See Filters below.
Filters
Filters let you narrow which events trigger a delivery. They are evaluated per payload before each delivery attempt — only matching events are sent. Filters are supported on per-driver feeds (timingdata, cardata, position, etc.) and on the synthetic raceevent feed.
Available filters
Field
Type
Description
drivers
string[]
Three-letter driver codes (TLAs). e.g. ["VER", "NOR"]. Resolved to driver numbers at delivery time.
driverNumbers
string[]
Raw driver racing numbers. e.g. ["1", "4"]. Use drivers (TLAs) for readability.
constructors
string[]
Team name keywords (case-insensitive partial match). e.g. ["ferrari", "mclaren"]. Resolved to all drivers on those teams using the current session's DriverList.
positions
{ min?: number; max?: number }
Race position range. Only delivers when at least one matching driver is within the specified position window.
Filters are combined with AND logic: if you specify both constructors and positions, a payload is delivered only when a constructor driver is within the position range.
✦
Constructor filters use fuzzy matching — "red bull" and "redbull" both match Red Bull Racing. The driver list is resolved live from the current session's DriverList feed, so mid-season team swaps are handled automatically.
HMAC signatures
On the Starter plan and above, every delivery includes an X-RaceHooks-Signature header containing an HMAC-SHA256 signature of the request body. Verifying this header proves the delivery originated from RaceHooks and the body was not tampered with in transit.
Always verify against the raw request body bytes, not the parsed JSON object. Use a timing-safe comparison function (timingSafeEqual in Node.js, hmac.compare_digest in Python, subtle.ConstantTimeCompare in Go) to prevent timing attacks.
import crypto from "crypto";
import { verifySignature } from "racehooks"; // or implement manually
// Express example — use raw body middleware
app.use("/f1-hook", express.raw({ type: "application/json" }));
app.post("/f1-hook", (req, res) => {
const sig = req.headers["x-racehooks-signature"] as string;
const ok = verifySignature(req.body, sig, process.env.WEBHOOK_SECRET!);
if (!ok) return res.status(401).send("Invalid signature");
const payload = JSON.parse(req.body.toString());
// handle payload...
res.sendStatus(200);
});
Rotate a secret
If a secret is compromised or you want to rotate it for security hygiene, call the rotation endpoint. The old secret continues to work for 60 seconds to allow any in-flight deliveries to complete.
bash
curl -X POST https://api.racehooks.io/v1/webhooks/wh_7a3b9c2d/rotate-secret \
-H "Authorization: Bearer ${TOKEN}"
# Response — new secret shown once
{
"data": {
"webhookSecret": "whsec_b4c8d..."
}
}
⚠
After rotation, the new secret is shown once in the response. Update your verification code before the 60-second overlap window expires.
Delivery SLA and retries
RaceHooks retries failed deliveries with exponential backoff:
AttemptDelay
1 (initial)Immediate
21 second
35 seconds
430 seconds
A delivery is considered successful when your endpoint returns a 2xx status code within 10 seconds. Any other response (timeout, 4xx, 5xx) triggers a retry.
The Pro and Analytics tiers include a 99.5% and 99.9% delivery SLA respectively, measured per calendar month. Enterprise SLAs are contractual.