Race results
#Race results
Full results for one race — the same page a club's public "race results" tab shows.
#Headers
| Header | Required | Value |
|---|---|---|
Authorization |
yes | Bearer <access_token> |
#Path parameters
| Param | Type | Note |
|---|---|---|
raceId |
UUID | from List races; unknown, non-UUID, or another club's ⇒ 404 RACE_NOT_FOUND |
#Request
curl -s https://sail-club-server.cloud.run/api/v1/races/9a1c0d2b-7e4a-46f8-9c1d-2e3f9a1c0d2b/results \
-H "Authorization: Bearer $TOKEN"const res = await fetch(`https://sail-club-server.cloud.run/api/v1/races/${raceId}/results`, {
headers: { Authorization: `Bearer ${token}` },
});
const results = await res.json();res = requests.get(
f"https://sail-club-server.cloud.run/api/v1/races/{race_id}/results",
headers={"Authorization": f"Bearer {token}"},
timeout=10,
)
results = res.json()var res = await client.GetAsync($"/api/v1/races/{raceId}/results");
res.EnsureSuccessStatusCode();
var page = await res.Content.ReadFromJsonAsync<PublicRaceResultPageDto>();<?php
$ch = curl_init("https://sail-club-server.cloud.run/api/v1/races/$raceId/results");
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer $token"]]);
$results = json_decode(curl_exec($ch), true);#Response
{
"id": "9a1c0d2b-7e4a-46f8-9c1d-2e3f9a1c0d2b",
"name": "Race 1",
"eventId": "1143117a-9c2b-4e7a-8f1d-2b6a9c4e7f10",
"eventName": "Cup Regatta 2026",
"scheduledDate": "2026-10-11T10:00:00Z",
"isOfficial": true,
"courseDistanceNm": 12.4,
"resultsUpdatedAtUtc": "2026-10-11T12:41:09Z",
"results": [
{
"id": "e3f9a1c0-d2b7-4e4a-96f8-c1d2e3f9a1c0",
"rank": 1,
"sailNumber": "TUR 501",
"boatName": "Poyraz",
"teamName": null,
"skipper": "A. Demir",
"owner": "A. Demir",
"className": "ORC",
"divisionId": "d1c0e9f8-a7b6-4c5d-8e3f-2a1b0c9d8e7f",
"divisionName": "ORC A",
"modelClass": "First 40.7",
"status": "Finished",
"startTimeUtc": "2026-10-11T10:00:00Z",
"finishTimeUtc": "2026-10-11T12:14:33Z",
"elapsedTime": "02:14:33",
"correctedTime": "02:01:47",
"listOrderNo": 1,
"raiting": 0.912,
"raitingLabel": "0.912",
"points": 1,
"penaltyPoints": null,
"timePenaltySeconds": null
}
]
}200 — same caching headers as every data endpoint; see Caching & freshness.
#Response fields
Full field table: Data models → Race results. status values include
Finished, DNF, DNS, OCS, RET, DSQ — see Data models for
what each means.
#Errors
| HTTP | Code |
|---|---|
| 404 | RACE_NOT_FOUND |
| 401 | API_TOKEN_MISSING / API_TOKEN_INVALID |
| 403 | API_SCOPE_MISSING / API_IP_NOT_ALLOWED |
| 429 | RATE_LIMIT_EXCEEDED |
| 503 | API_UNAVAILABLE |
#Caching
One entry per raceId. A race stops changing once its jury window closes, at which point you can safely
stop revalidating it altogether.
Prompt for AI agents ready to paste into an agent
Implement getRaceResults(raceId) for the Sail Club API.
GET https://sail-club-server.cloud.run/api/v1/races/{raceId}/results
Authorization: Bearer <access_token>
Success 200: { id, name, eventId, eventName, scheduledDate, results: [ { id, rank, sailNumber, boatName,
skipper, owner, divisionName, status ("Finished"|"DNF"|"DNS"|"OCS"|"RET"|"DSQ"|...), startTimeUtc,
finishTimeUtc, elapsedTime, correctedTime, points, penaltyPoints, timePenaltySeconds, ... } ], ... } —
fetch GET /api/v1/openapi.json for the exact schema.
404 RACE_NOT_FOUND: unknown/malformed/another club's race id — not retryable.
401/403/429/503: same handling as every other call — see the full-integration prompt on /docs/overview.
Requirements: a typed client function, and a small render/format helper that turns one result row into a
human-readable line, e.g. "1. Poyraz (TUR 501) — 02:01:47 corrected — 1 pt", treating a non-Finished status
(DNF/DNS/OCS/RET/DSQ) as its own label instead of a time.
Adapt to your actual stack — the endpoint, path param and response shape above are language-neutral.