# Event results

# Event results

An event's series (multi-race) results — the four lists a club's public "results" tab shows: the main
scoring results, overall standings, rating-group standings, and special-category standings.

## Headers

| Header | Required | Value |
|---|---|---|
| `Authorization` | yes | `Bearer <access_token>` |

## Path parameters

| Param | Type | Note |
|---|---|---|
| `eventId` | UUID | `404 EVENT_NOT_FOUND` if unknown / another club's / not published |

#### Request

```bash
curl -s https://sail-club-server.cloud.run/api/v1/events/1143117a-9c2b-4e7a-8f1d-2b6a9c4e7f10/results \
  -H "Authorization: Bearer $TOKEN"
```

```javascript
const res = await fetch(`https://sail-club-server.cloud.run/api/v1/events/${eventId}/results`, {
  headers: { Authorization: `Bearer ${token}` },
});
const results = await res.json();
```

```python
res = requests.get(
    f"https://sail-club-server.cloud.run/api/v1/events/{event_id}/results",
    headers={"Authorization": f"Bearer {token}"},
    timeout=10,
)
results = res.json()
```

```csharp
var res = await client.GetAsync($"/api/v1/events/{eventId}/results");
res.EnsureSuccessStatusCode();
var results = await res.Content.ReadFromJsonAsync<PublicApiEventResultsDto>();
```

```php
<?php
$ch = curl_init("https://sail-club-server.cloud.run/api/v1/events/$eventId/results");
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer $token"]]);
$results = json_decode(curl_exec($ch), true);
```

#### Response

```json
{
  "results": [
    {
      "id": "4c5d8e3f-2a1b-40c9-8d8e-7f6c5d4e3f2a",
      "eventId": "1143117a-9c2b-4e7a-8f1d-2b6a9c4e7f10",
      "divisionId": "d1c0e9f8-a7b6-4c5d-8e3f-2a1b0c9d8e7f",
      "divisionName": "ORC A",
      "overallGroupId": "b6a9c4e7-f10a-41c0-8d2b-7e4a6f8c1d2e",
      "overallGroupName": "ORC",
      "rank": 1,
      "sailNumber": "TUR 501",
      "boatName": "Poyraz",
      "skipper": "A. Demir",
      "owner": "A. Demir",
      "modelClass": "First 40.7",
      "score": 4,
      "points": [
        { "raceNo": 1, "score": 1, "isDiscarded": false },
        { "raceNo": 2, "score": 3, "isDiscarded": false }
      ]
    }
  ],
  "overall": [
    { "id": "4c5d8e3f-2a1b-40c9-8d8e-7f6c5d4e3f2a", "overallGroupId": "b6a9c4e7-f10a-41c0-8d2b-7e4a6f8c1d2e",
      "overallGroupName": "ORC", "rank": 1, "sailNumber": "TUR 501", "boatName": "Poyraz",
      "skipper": "A. Demir", "score": 4,
      "points": [ { "raceNo": 1, "score": 1, "isDiscarded": false }, { "raceNo": 2, "score": 3, "isDiscarded": false } ] }
  ],
  "ratingGroups": [
    { "id": "4c5d8e3f-2a1b-40c9-8d8e-7f6c5d4e3f2a", "ratingGroup": "IRC 1", "rank": 1, "sailNumber": "TUR 501",
      "boatName": "Poyraz", "owner": "A. Demir", "score": 4,
      "points": [ { "raceNo": 1, "score": 1, "isDiscarded": false }, { "raceNo": 2, "score": 3, "isDiscarded": false } ] }
  ],
  "specialCategories": [
    { "id": "9d8e7f6c-5d4e-43f2-8a1b-0c9d8e7f6c5d", "specialCategoryId": "8e7f6c5d-4e3f-42a1-8b0c-9d8e7f6c5d4e",
      "categoryName": "Best Corinthian", "rank": 1, "sailNumber": "TUR 501", "boatName": "Poyraz",
      "skipper": "A. Demir", "totalScore": 4,
      "points": [ { "raceNo": 1, "score": 1, "isDiscarded": false }, { "raceNo": 2, "score": 3, "isDiscarded": false } ] }
  ]
}
```

`200` — same caching headers as every data endpoint; see [Caching & freshness](/docs/caching).

## Response fields

Full field tables: [Data models → Event results](/docs/data-models#event-results). Each of the four lists
uses the same `points[]` shape (one entry per race, `isDiscarded` marking a dropped race under the event's
discard rule); a list is `[]` (not omitted) if the event has no data for it — e.g. `specialCategories: []`
when the event defines none.

## Errors

| HTTP | Code |
|---|---|
| 404 | [`EVENT_NOT_FOUND`](/docs/errors#EVENT_NOT_FOUND) |
| 401 | [`API_TOKEN_MISSING`](/docs/errors#API_TOKEN_MISSING) / [`API_TOKEN_INVALID`](/docs/errors#API_TOKEN_INVALID) |
| 403 | [`API_SCOPE_MISSING`](/docs/errors#API_SCOPE_MISSING) / [`API_IP_NOT_ALLOWED`](/docs/errors#API_IP_NOT_ALLOWED) |
| 429 | [`RATE_LIMIT_EXCEEDED`](/docs/errors#RATE_LIMIT_EXCEEDED) |
| 503 | [`API_UNAVAILABLE`](/docs/errors#API_UNAVAILABLE) |

## Caching

One entry per `eventId`. During a live regatta this changes as races are scored (bounded by the cache
window, up to an hour — see [Caching & freshness](/docs/caching)); once an event is finished and awards are
published it effectively stops changing.

```prompt
Implement getEventResults(eventId) for the Sail Club API.

GET https://sail-club-server.cloud.run/api/v1/events/{eventId}/results
Authorization: Bearer <access_token>

Success 200: { results: [...], overall: [...], ratingGroups: [...], specialCategories: [...] } — four lists,
  each entry has rank, sailNumber, boatName, skipper/owner, a score/totalScore, and points: [{ raceNo, score,
  isDiscarded, ... }]. Any list may be an empty array. Fetch GET /api/v1/openapi.json for the exact schema —
  do not invent fields not listed there.
404 EVENT_NOT_FOUND: unknown/other club's/unpublished event — not retryable.
401/403/429/503: same handling as every other call — see the full-integration prompt on /docs/overview.

Build a typed client function plus a small formatter that renders the "overall" list as a standings table:
rank, boat name, sail number, skipper, score, with discarded races shown struck through / annotated.

Adapt to your actual stack — the endpoint, path param and response shape above are language-neutral.
```
