# Get leaderboard

```http
GET /api/public/v1/competitions/mathematics-distillation-challenge-equational-theories-stage2/leaderboard
```

**Scope**: `competition.read`.

Returns one cursor-paginated official Stage 2 ranking for a required `(track, modelId)` pair. Stage 2 has no combined overall ranking: Solo and Marathon results are separate, and each declared model has its own ranking.

Higher scores rank first. Before publication, the endpoint returns an empty page and does not reveal provisional evaluation results.

## Query parameters

| Parameter | Type | Required | Default | Description |
| :-------- | :--- | :------: | :------ | :---------- |
| `track` | string | Yes | — | Exact track ID from the competition detail catalog. |
| `modelId` | string | Yes | — | Exact model ID from the competition detail catalog. |
| `cursor` | string | No | — | Opaque cursor returned by the previous page for the same pair. |
| `limit` | integer | No | `25` | Page size from `1` through `100`. |

`track` and `modelId` are case-sensitive. Fetch the live values from [Get competition detail](./get-competition-detail.md); do not derive them from display labels.

Published leaderboard cursors are bound to the official evaluation batch and pair used for the first page. If a newer batch is published during traversal, an existing cursor continues through its original snapshot. Do not decode, construct, or reuse a cursor with another pair.

## Response fields

### Data

| Field | Type | Description |
| :---- | :--- | :---------- |
| `items` | [Leaderboard entry](#leaderboard-entry)[] | Current page in official rank order. Empty while results are unpublished. |
| `nextCursor` | string \| null | Opaque cursor for the next page, or `null` when traversal is complete. |
| `meta.track` | string | Track selected by the request. |
| `meta.modelId` | string | Model selected by the request. |
| `meta.published` | boolean | Whether official results for this leaderboard are public. |
| `meta.publishedAt` | string \| null | ISO 8601 UTC publication time, or `null` before publication. |
| `meta.batch` | [Official evaluation batch](#official-evaluation-batch) \| null | Immutable evaluation snapshot behind the ranking, or `null` before publication. |

### Leaderboard entry

| Field | Type | Description |
| :---- | :--- | :---------- |
| `rank` | integer | One-based competition rank. Equal scores share a rank, so the next rank may skip a number. |
| `teamId` | string | Opaque Competition Team ID. |
| `teamNumber` | string \| null | Assigned public team number, when available. |
| `teamName` | string | Public team display name. |
| `score` | number | Official accuracy from `0` through `1`, equal to `acceptedProblems / totalProblems`. |
| `acceptedProblems` | integer | Number of official problems with an accepted Lean certificate. |
| `totalProblems` | integer | Number of problems in the published evaluation batch. |
| `evaluatedSolverSha256` | string | Lowercase SHA-256 digest of the exact solver snapshot evaluated for this pair. |
| `teamDetails` | [TeamMemberDetails](../../competitions.md#leaderboard-team-details-and-privacy) \| null | Current consent-controlled, server-redacted member projection, or `null`. |

The server supplies the ranking. Clients must preserve item order and must not calculate a different rank from rounded display values. Ranking fields and `evaluatedSolverSha256` come from the immutable batch; `teamName` and `teamDetails` are current public projections and may change without changing rank.

### Official evaluation batch

| Field | Type | Description |
| :---- | :--- | :---------- |
| `id` | string | Opaque final-evaluation batch ID. |
| `finishedAt` | string | ISO 8601 UTC time when the batch reached its terminal evaluated state. |
| `cohortSha256` | string | SHA-256 digest of the sealed participation cohort. |
| `problemManifestSha256` | string | SHA-256 digest of the sealed official problem manifest. |
| `environmentSha256` | string | SHA-256 digest of the sealed runtime and model configuration. |
| `problemCount` | integer | Number of equally weighted official problems. |
| `scoringVersion` | string | Version of the scoring and ranking contract. |

## Example request

```bash
curl "https://api.sair.foundation/api/public/v1/competitions/mathematics-distillation-challenge-equational-theories-stage2/leaderboard?track=solo&modelId=openai-gpt-oss-120b&limit=25" \
  -H "Authorization: Bearer $SAIR_API_KEY"
```

## Example response

```json
{
  "ok": true,
  "data": {
    "items": [
      {
        "rank": 1,
        "teamId": "teamv2_19ac4fb862d64502ae7837852e18fb4a",
        "teamNumber": "MDC2-T00003",
        "teamName": "Lean Explorers",
        "score": 0.9625,
        "acceptedProblems": 385,
        "totalProblems": 400,
        "evaluatedSolverSha256": "7890abcdef1234567890abcdef1234567890abcdef1234567890abcdef123456",
        "teamDetails": {
          "members": [
            {
              "name": "Alice Example",
              "avatarUrl": "https://id.sair.foundation/avatars/alice.png",
              "email": "alice@example.com"
            }
          ]
        }
      }
    ],
    "nextCursor": null,
    "meta": {
      "track": "solo",
      "modelId": "openai-gpt-oss-120b",
      "published": true,
      "publishedAt": "2026-10-01T00:00:00Z",
      "batch": {
        "id": "s2eval_01JSTAGE2FINAL000000000001",
        "finishedAt": "2026-09-30T22:15:00Z",
        "cohortSha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
        "problemManifestSha256": "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789",
        "environmentSha256": "fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210",
        "problemCount": 400,
        "scoringVersion": "mdc-stage2-score-v1"
      }
    }
  }
}
```

## Unpublished response

For a valid catalog pair whose official results are not yet published:

```json
{
  "ok": true,
  "data": {
    "items": [],
    "nextCursor": null,
    "meta": {
      "track": "solo",
      "modelId": "openai-gpt-oss-120b",
      "published": false,
      "publishedAt": null,
      "batch": null
    }
  }
}
```

No provisional score, team, cohort, or batch information is exposed before publication. Replacing a formal solver after the published batch was sealed does not change that batch's ranking; a later published batch may evaluate the newer snapshot.

## Errors

| HTTP | Code | When |
| :---: | :--- | :--- |
| `400` | `MALFORMED_BODY` | A required query parameter is missing, `cursor` is malformed, or `limit` is outside `1` through `100`. |
| `404` | `NOT_FOUND` | The competition is not publicly visible. |
| `422` | `RESOURCE_FIELD_INVALID` | `track` or `modelId` is not an exact current catalog value. |

Follow the shared [cursor traversal rules](../../../pagination.md). No total team count is returned. Shared authentication, scope, and rate-limit errors are documented in [Errors](../../../errors.md).
