Stagewerk API

Version 1. Read-only JSON. OpenAPI 3.1 document

The Stagewerk API gives an organiser's own systems read access to the data on its public event pages: events, classes, the entry list, the itinerary, bulletins and published results. It is read-only. Everything is JSON over HTTPS under /api/v1.

The examples use two shell variables. STAGEWERK_URL is the address of the Stagewerk site you sign in to, for example https://your-stagewerk-host, and STAGEWERK_KEY is your API key.

Get an API key

Keys belong to an organiser, not to a person. The organiser's owner opens API keys in the console (/t/{organiser}/api-keys), gives the key a name that says what uses it, and creates it. The key is shown once, in a box at the top of the page. Copy it into your secret store straight away: Stagewerk keeps only a hash and cannot show it again. Create one key per integration so you can revoke one without touching the others. The page lists each key with the time it was last used, and Revoke stops a key working immediately.

A key can read that organiser's data and nothing else. It cannot read another organiser, and it cannot change anything.

Authenticate

Send the key as a bearer token on every request.

curl -H "Authorization: Bearer $STAGEWERK_KEY" -H "Accept: application/json" "$STAGEWERK_URL/api/v1/events"

A missing, wrong or revoked key gets 401. Always send Accept: application/json.

Pagination

List endpoints that can grow (events, entries, bulletins) use cursor pagination. A response looks like this:

{
    "data": [ ... ],
    "links": { "first": null, "last": null, "prev": null, "next": "https://.../api/v1/events?cursor=eyJ..." },
    "meta": { "path": "https://.../api/v1/events", "per_page": 50, "next_cursor": "eyJ...", "prev_cursor": null }
}

Ask for a page size with limit (1 to 100, default 50). To get the next page, request links.next, or repeat the request with cursor set to meta.next_cursor. When meta.next_cursor is null you have everything. Treat cursors as opaque strings. Lists that are always short (classes, itinerary) are returned whole.

Sparse fields

Add fields with a comma-separated list of keys to receive only those keys in each object, for example fields=competition_number,driver_name. An unknown key returns 422 and the message lists the keys that exist. The keys of every object are listed in the reference below.

Rate limits

Each key may make 120 requests a minute. Every response carries X-RateLimit-Limit and X-RateLimit-Remaining. Over the limit you get 429 with a Retry-After header holding the seconds to wait. Back off for that long, then continue.

Errors

Errors are JSON with a message. Validation errors (422) also have an errors object keyed by parameter.

Status Meaning
401 The key is missing, wrong or revoked.
403 The key may not read.
404 No such event, or it is not public, or nothing is published yet (results).
422 A query parameter is invalid, for example an unknown field or a limit above 100.
429 Rate limit reached. Wait Retry-After seconds.

Worked example: an entry list

This builds an entry-list page for one event: find the event, read its classes, then read every entry.

  1. List the organiser's events and pick one by its slug.

    curl -s -H "Authorization: Bearer $STAGEWERK_KEY" -H "Accept: application/json" \
      "$STAGEWERK_URL/api/v1/events?fields=name,slug,starts_on,status"
    
    { "data": [ { "name": "Club Rallysprint", "slug": "club-rallysprint", "starts_on": "2027-03-14", "status": "entries_open" } ], "links": { ... }, "meta": { ... } }
    
  2. Read the classes, to show group headings (code and name match class_code and class_name on each entry).

    curl -s -H "Authorization: Bearer $STAGEWERK_KEY" -H "Accept: application/json" \
      "$STAGEWERK_URL/api/v1/events/club-rallysprint/classes?fields=code,name,sort_order"
    
  3. Read the entry list, 100 at a time.

    curl -s -H "Authorization: Bearer $STAGEWERK_KEY" -H "Accept: application/json" \
      "$STAGEWERK_URL/api/v1/events/club-rallysprint/entries?limit=100&fields=competition_number,class_name,driver_name,co_driver_name,vehicle_description"
    
    {
        "data": [
            {
                "competition_number": 7,
                "class_name": "Club Sprint",
                "driver_name": "A. Driver",
                "co_driver_name": null,
                "vehicle_description": "2004 Subaru Impreza"
            }
        ],
        "links": {
            "first": null,
            "last": null,
            "prev": null,
            "next": "https://.../entries?limit=100&cursor=eyJ..."
        },
        "meta": {
            "path": "https://.../entries",
            "per_page": 100,
            "next_cursor": "eyJ...",
            "prev_cursor": null
        }
    }
    
  4. While meta.next_cursor is not null, request the same URL with &cursor=<next_cursor> and append data.

The entry list holds the entries that have a place in the event. It shows names, class, vehicle and state. It never includes email addresses, phone numbers, licence numbers or dates of birth.

TypeScript types

resources/js/api/v1.d.ts in the Stagewerk repository holds TypeScript types generated from the OpenAPI document. Generate your own from /developers/openapi.json with npx openapi-typescript.

Reference

The sections below are generated from the same OpenAPI 3.1 document you can download at /developers/openapi.json.

Changelog

GET/api/v1/events/{event}/bulletins

List the bulletins of an event

Published bulletins the organiser made public, in number order.

Parameters
NameInRequiredDescription
eventpathyesThe event slug
limitquerynoRows per page, 1 to 100. Default 50.
cursorquerynoThe `next_cursor` of the previous page. Opaque; do not build one.
fieldsquerynoComma-separated keys to keep in each returned object, for example `fields=name,slug`.
Keys of each returned object (usable in fields)
KeyType
idinteger
numberinteger or null
titlestring
bodystring
published_atstring or null
published_displaystring or null
replaces_numberinteger or null
eventobject
organiserobject or null

GET/api/v1/events/{event}/entries

List the entry list of an event

The entries that hold a place in the event, in the order they were created (by id); sort by competition_number on your side, since not every entry has a number yet. Names, team, class, vehicle and state only: no contact details, licence numbers or dates of birth. Competitors who asked not to be named on public entry lists are left out (a driver loses the whole entry, a co-driver only their name). Only served once the organiser has published the entry list; until then the response is 404, as on the public Entries tab.

Parameters
NameInRequiredDescription
eventpathyesThe event slug
limitquerynoRows per page, 1 to 100. Default 50.
cursorquerynoThe `next_cursor` of the previous page. Opaque; do not build one.
fieldsquerynoComma-separated keys to keep in each returned object, for example `fields=name,slug`.
Keys of each returned object (usable in fields)
KeyType
idinteger
competition_numberinteger or null
class_codestring
class_namestring
driver_namestring
co_driver_namestring or null
entrant_namestring or null
vehicle_descriptionstring or null
statestring
state_labelstring
photo_urlstring or null

GET/api/v1/events

List events

The events of the organiser that owns the key which are visible on its public site, oldest start first.

Parameters
NameInRequiredDescription
limitquerynoRows per page, 1 to 100. Default 50.
cursorquerynoThe `next_cursor` of the previous page. Opaque; do not build one.
fieldsquerynoComma-separated keys to keep in each returned object, for example `fields=name,slug`.
Keys of each returned object (usable in fields)
KeyType
namestring
slugstring
urlstring
disciplinestring
discipline_labelstring
sanctioning_bodystring
sanctioning_body_labelstring
venue_namestring
venue_addressstring or null
townstring or null
statestring or null
timezonestring
starts_onstring
ends_onstring
permit_numberstring or null
starts_displaystring or null
finishes_displaystring or null
pace_notesstring or null
pace_notes_labelstring or null
scrutineering_notesstring or null
sessionsarray
dates_displaystring
entries_open_localstring or null
entries_open_displaystring or null
entries_close_localstring or null
entries_close_displaystring or null
statusstring
status_labelstring
descriptionstring or null
organiserobject
locationsarray
contactsarray
documentsarray
coverobject or null
courseobject or null
distancesobject or null

GET/api/v1/events/{event}

Get an event

Parameters
NameInRequiredDescription
eventpathyesThe event slug
limitquerynoRows per page, 1 to 100. Default 50.
cursorquerynoThe `next_cursor` of the previous page. Opaque; do not build one.
fieldsquerynoComma-separated keys to keep in each returned object, for example `fields=name,slug`.

GET/api/v1/events/{event}/classes

List the classes of an event

Every class of the event in the organiser's order. Not paginated: an event has a handful of classes.

Parameters
NameInRequiredDescription
eventpathyesThe event slug
limitquerynoRows per page, 1 to 100. Default 50.
cursorquerynoThe `next_cursor` of the previous page. Opaque; do not build one.
fieldsquerynoComma-separated keys to keep in each returned object, for example `fields=name,slug`.
Keys of each returned object (usable in fields)
KeyType
idinteger
event_idinteger
namestring
codestring
categorystring or null
sort_orderinteger
capinteger or null
drivetrainstring
min_capacity_ccinteger or null
max_capacity_ccinteger or null
forced_inductionstring
min_yearinteger or null
max_yearinteger or null
tyre_rulestring or null

GET/api/v1/events/{event}/itinerary

List the itinerary of an event

Stages, liaisons and service points in running order, with the computed time the first car is due at each. Not paginated. The totals are in meta.totals, in metres.

Parameters
NameInRequiredDescription
eventpathyesThe event slug
limitquerynoRows per page, 1 to 100. Default 50.
cursorquerynoThe `next_cursor` of the previous page. Opaque; do not build one.
fieldsquerynoComma-separated keys to keep in each returned object, for example `fields=name,slug`.
Keys of each returned object (usable in fields)
KeyType
idinteger
event_idinteger
positioninteger
kindstring
codestring
namestring
heatinteger or null
leginteger or null
scoredboolean
distance_minteger or null
distance_labelstring
target_secondsinteger or null
target_labelstring
fixed_first_car_atstring or null
fixed_first_car_localstring or null
notesstring or null
first_car_duestring or null
first_car_labelstring

GET/api/v1/events/{event}/results

Get published classifications

The latest published classification of the event, or the one in version (a version number from the versions list). Only what the organiser has published; unpublished figures are never served. 404 until something is published.

Parameters
NameInRequiredDescription
eventpathyesThe event slug
versionquerynoClassification version number. Default: the latest published version.
Keys of each returned object (usable in fields)
KeyType
eventobject
versionobject
is_latestboolean
scopesarray
stagesarray
show_runsboolean
versionsarray
liveobject or null
standingsobject or null
updated_displaystring

GET/api/v1/events/{event}/stage-times/{itineraryItem}

Get the times of one stage

One stage of the itinerary (use the id from the itinerary list), in order of time. Which times are shown, published or live, follows the event's stage-times setting; 404 when the event shows none.

Parameters
NameInRequiredDescription
eventpathyesThe event slug
itineraryItempathyesThe itinerary item ID
versionquerynoClassification version number. Default: the latest published version.
Keys of each returned object (usable in fields)
KeyType
eventobject
stagearray
rowsarray
previousobject or null
nextobject or null
stagesarray
sourceobject
has_resultsboolean
liveobject or null
updated_displaystring