API Endpoints
The Race Platform API is a Hono app that runs
on Node locally (port 6161) and on Cloudflare Workers in
production.
All endpoints (except /health and /auth/*) require either:
- A Bearer JWT obtained via
POST /auth/login, or - An
X-API-Key: rk_…header issued from Admin → Integrations → API Keys.
Either credential carries the caller's accountId, which scopes
every subsequent query.
There are 35 route modules in apps/api/src/routes/. The
tables below group them by concern.
Auth + system
| Method | Path | Purpose |
|---|---|---|
GET | /health | Liveness check (no auth) |
POST | /auth/login | Email/password login → JWT |
POST | /auth/register | Register a new account / user |
GET POST | /auth/me | Current user profile |
Management entities
| Method | Path | Purpose |
|---|---|---|
GET POST | /championships | List / create |
GET PATCH DELETE | /championships/:id | Get / update / delete |
GET POST | /events | List / create |
GET PATCH DELETE | /events/:id | |
GET POST | /sessions | List (filter ?eventId=) / create |
GET PATCH DELETE | /sessions/:id | |
GET POST | /cars | |
GET PATCH DELETE | /cars/:id | |
GET POST | /drivers | |
GET PATCH DELETE | /drivers/:id | |
GET POST | /tracks | |
GET PATCH DELETE | /tracks/:id | |
GET POST | /lap-markers | List / create |
PATCH DELETE | /lap-markers/:id |
Event-scoped entities
| Method | Path | Purpose |
|---|---|---|
GET POST | /run-sheets | List (filter ?sessionId=&carId=) / create |
GET PATCH DELETE | /run-sheets/:id | |
GET POST | /laps | List (filter ?runSheetId= or ?sessionId=) / create |
GET PATCH DELETE | /laps/:id | |
GET POST | /setups | |
GET PATCH DELETE | /setups/:id | |
GET POST | /tyre-sets | |
GET PATCH DELETE | /tyre-sets/:id | |
GET POST | /tyres | |
PATCH DELETE | /tyres/:id | |
GET POST | /tyre-wears | |
PATCH DELETE | /tyre-wears/:id | |
GET POST | /weather | |
PATCH DELETE | /weather/:id | |
GET POST | /board-cards | List (filter ?eventId=&column=) / create |
GET PATCH DELETE | /board-cards/:id | |
GET POST | /issues | List / create issues |
GET PATCH DELETE | /issues/:id | |
POST | /issues/:id/acknowledge | Mark acknowledged |
POST | /issues/:id/resolve | Mark resolved |
Per-event / per-session data
| Method | Path | Purpose |
|---|---|---|
GET PATCH | /event-data | Per-event constants |
GET PATCH | /session-data | Per-session constants |
GET PATCH | /account-options | Account-wide options |
Customisation
| Method | Path | Purpose |
|---|---|---|
GET POST | /definitions | List (filter ?entityType=) / create |
GET PATCH DELETE | /definitions/:id | |
POST | /definitions/:id/validate | { valid, errors[] } |
GET POST | /custom-views | |
GET PATCH DELETE | /custom-views/:id | |
GET POST | /custom-columns | |
GET PATCH DELETE | /custom-columns/:id | |
GET POST | /change-formatters | List (filter ?entityType=) / create |
GET PATCH DELETE | /change-formatters/:id | |
GET POST | /tyre-specifications | |
GET PATCH DELETE | /tyre-specifications/:id |
Workflow / operations
| Method | Path | Purpose |
|---|---|---|
GET POST | /issue-workflows | Issue state-machine definitions |
GET PATCH DELETE | /issue-workflows/:id | |
GET POST | /data-analysis-profiles | KPI profiles |
GET PATCH DELETE | /data-analysis-profiles/:id | |
POST | /data-analysis-profiles/:id/evaluate | Evaluate KPIs against a sample buffer |
POST | /run-plans/calculate | Headless run-plan calculator (same engine as the UI) |
Permissions / API keys / webhooks
| Method | Path | Purpose |
|---|---|---|
GET POST | /permission-profiles | Permission rule profiles |
GET PATCH DELETE | /permission-profiles/:id | |
GET | /memberships | List memberships in the account |
POST | /memberships/:id/permission-profile | Assign a profile to a membership |
GET POST | /api-keys | Account-scoped API keys (returns the secret only on create) |
GET PATCH DELETE | /api-keys/:id | |
GET POST | /webhooks | HMAC-signed webhook subscriptions |
GET PATCH DELETE | /webhooks/:id |
Plugins
| Method | Path | Purpose |
|---|---|---|
GET | /plugins | List installed plugins |
POST | /plugins/upload | Upload manifest + base64 bundle |
POST | /plugins/:id/invoke/math | { fnName, args, ctx? } → { result } |
POST | /plugins/:id/invoke/kpi | { lapId, lap } → { results[] } |
POST | /plugins/:id/run | Legacy combined-runner (retained for back-compat) |
DELETE | /plugins/:id | Uninstall |
Import
| Method | Path | Purpose |
|---|---|---|
GET POST | /import-profiles | Reusable JSON-import scope trees |
GET PATCH DELETE | /import-profiles/:id | |
POST | /import | Apply a JSON payload using a profile |
Attachments
| Method | Path | Purpose |
|---|---|---|
GET | /attachments?entityType=&entityId= | List for an entity |
POST | /attachments/upload | JSON-encoded base64 upload |
GET | /attachments/:id | Get row + presigned download URL |
GET | /attachments/:id/download | Stream the binary |
DELETE | /attachments/:id | Delete row + object |
Response shape
All list endpoints return { items: [...] }. Single-resource
endpoints return the bare object. Don't change this shape without
coordinating with the Flutter client — there's a hard
type-cast on the receiving side.
Errors follow:
{ "error": "human-readable message", "code": "OPTIONAL_CODE" }
Where to read the source
| Route | File |
|---|---|
Each /x | apps/api/src/routes/<x>.ts |
| Auth middleware | apps/api/src/middleware/auth.ts |
| Permission middleware | apps/api/src/middleware/permissions.ts |
| Schema | apps/api/src/db/schema.ts |
What's coming
- OpenAPI / Swagger spec — the routes today are Hono-typed
but not exported as OpenAPI. Hono's
@hono/swagger-uipackage is on the queue. /plugins/:id/sourceroute for the in-browser flutter_js adapter/plugins/:id/math/functionsroute to populate the Plugin Runner's function dropdown