Quickstart — your first API edit
This walkthrough takes you from zero to a verified live change. You'll mint an API key as an organisation admin, make one read and one write request against the API, and watch the change land in the app or the web dashboard in real time.
You need:
- An organisation admin account in RaceRanger.
- The base URL for the environment you're integrating against (see Base URLs).
- A command-line tool that speaks HTTPS (
curl,httpie, Postman, Bruno, etc.). All examples below usecurl.
1. Mint an org-scoped API key
API keys are minted from inside the RaceRanger app — never via the public API. This keeps every key tied to a real admin's user record for audit.
- Open app.raceranger.com and sign in as an organisation admin.
- In the top nav, click Organizations.
- On the left sidebar (your organisation card), click Edit organization.
- In the modal that opens, switch to the API keys tab. If you don't see this tab, your organisation hasn't been opted into API access yet — ask the RaceRanger team to enable it.
- Click + New key.
-
The Create org API key dialog opens. Fill in:
- Name (required) — something descriptive like "Race-day dashboard". You'll see this in the keys list later when rotating or revoking.
- Scopes (required) — tap the filter chips for the scopes the
integration actually needs. Read-only integrations should hold
read:*only;write:*andmanage:webhooksare org-key-only (see the scope table). - Restrict to event IDs (optional) — comma-separated list of event IDs to narrow this key to specific events only. The events must belong to your organisation. Leave empty for "every event in this organisation".
- Expires in (days, max 730) — defaults to 365. Rotate before expiry; revoked keys can't be reactivated.
-
Tap Create.
- An API key created dialog appears with the plaintext key
(
rr_o_…) and its scopes + expiry. Copy it into your secret store immediately — it is displayed once and RaceRanger has no way to recover the plaintext after this dialog closes.
If you lose the plaintext, revoke the key and mint a new one.
For per-event read access (handing one race-day to a partner without
giving them access to anything else), open Edit Event instead and
use its own API keys tab. Anyone who can edit the event can create
these. Event-scoped keys (rr_e_…) are read-only.
2. Smoke-test the key
Set a couple of shell variables to keep the rest of this page tidy:
export RR_BASE="https://raceranger-api-2wm0cky.ew.gateway.dev" # testing
export RR_KEY="rr_o_…paste_your_key_here…"
Confirm the key works by listing the events you can see:
Expected output:
{
"data": [
{
"id": "evt_abc",
"name": "Spring Sprint 2026",
"sport": "triathlon",
"dateFrom": "2026-05-04T07:00:00.000Z",
"isOver": false,
"organizationId": "your-org"
}
]
}
The list holds up to 100 of your organisation's events. Only org-scoped
keys can list events; an event-scoped key reads its one event with
GET /v1/events/{eventId}.
If you get 401 unauthorized, double-check the Authorization: Bearer prefix and the absence of trailing whitespace. If you get 403, the
key's scope set doesn't include read:events — re-mint with the right
scopes. See the authentication reference for the
full scope table.
3. Read a specific event and race
Pick an event id from the response above and a race under it:
export EVENT_ID="evt_abc"
curl -sS "$RR_BASE/v1/events/$EVENT_ID/races" \
-H "Authorization: Bearer $RR_KEY" \
| python3 -m json.tool
Each race in data[] has an id, a name, and a startTime. The
response also carries the event itself, under event. Pick a race to
edit:
4. Edit the race via the API
Every create and update needs an Idempotency-Key header. Pick a
stable client-side identifier — most teams use the user's action UUID
or a hash of the intended change. Re-sending the same key with the
same body within 24 h returns the cached response; sending it with a
different body returns 400. See Idempotency
for the full rules.
This PATCH renames a race:
curl -sS -X PATCH "$RR_BASE/v1/events/$EVENT_ID/races/$RACE_ID" \
-H "Authorization: Bearer $RR_KEY" \
-H "Idempotency-Key: rename-race-$(date +%s)" \
-H "Content-Type: application/json" \
-d '{"name": "Sprint Course — Heat 1"}' \
| python3 -m json.tool
Expected response (200), shortened — the API returns every race field:
{
"data": {
"id": "race_xyz",
"name": "Sprint Course — Heat 1",
"startTime": "2026-05-04T07:00:00.000Z",
"status": "notActive",
"isDraftingAllowed": true,
"gender": "open"
}
}
The change is saved immediately and reaches every connected app and web client in under a second.
Some fields freeze once the race starts
Competition-defining fields — gender, numberSeries,
isDraftingAllowed, penaltyBoxEnabled, stopAndGoEnabled,
bikePenaltyBoxEnabled and bikePenaltyBoxAmount — can only be
changed before the race starts. Once the race is active or has
started (its status is active, running or finished), a PATCH
touching any of them returns 403. Everything else stays editable,
as in the app's race editor: the name, start time, distances,
penalty times and the other race options. Lifecycle (start, stop) is
intentionally not exposed via the API — it lives in the officials'
app.
5. Verify the edit in the app or web
You don't need to refresh anything — the app and the web update live. Open the event you just edited in either surface:
- Mobile app — open RaceRanger on a logged-in device, navigate to the event, then the race list. The renamed race appears immediately.
- Web — open app.raceranger.com, sign in, open the event. The race name reflects the API change the moment the PATCH responded.
If you don't see the change:
- Make sure you're looking at the right organisation. Org-scoped keys can see every event under their organisation, including ones the current signed-in user might not have role access to.
- Check the response of step 4 — if you got
200but the field doesn't match what you sent, double-check field names against the API reference.
6. Tidy up
Whether or not the integration is going to production, two cleanup habits:
- Don't leave broad-scope keys lying around. Revoke unused keys from the same API keys tab where you minted them. A revoked key stops working within about 10 seconds.
- Rotate before expiry. The tab warns you when a key expires within 30 days. Rotate mints a new key with the same scopes and shows it once; the old key keeps working for 30 days. Point your integration at the new key, then revoke the old one.
What you exercised
Going through this once verifies, in order:
- The org-admin minting flow and that the plaintext key is shown exactly once.
- The Bearer-token auth path (header parsing, key lookup, scope check).
- Cross-event tenant isolation via org-key scoping.
- The
Idempotency-Keyround-trip on a write endpoint. - Field validation on a race
PATCH. - A change made through the API showing up live in the app and on the web.
For more advanced flows — bulk athlete import, webhook subscriptions for live race events, secret rotation — see the full reference and the webhooks guide.