Skip to content

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 use curl.

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.

  1. Open app.raceranger.com and sign in as an organisation admin.
  2. In the top nav, click Organizations.
  3. On the left sidebar (your organisation card), click Edit organization.
  4. 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.
  5. Click + New key.
  6. 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:* and manage:webhooks are 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.
  7. Tap Create.

  8. 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:

curl -sS "$RR_BASE/v1/events" -H "Authorization: Bearer $RR_KEY" \
  | python3 -m json.tool

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:

export RACE_ID="<race id from the response>"

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 200 but 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:

  1. The org-admin minting flow and that the plaintext key is shown exactly once.
  2. The Bearer-token auth path (header parsing, key lookup, scope check).
  3. Cross-event tenant isolation via org-key scoping.
  4. The Idempotency-Key round-trip on a write endpoint.
  5. Field validation on a race PATCH.
  6. 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.