# Get competition detail

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

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

Returns Stage 2 competition metadata and the live contract for formal solver submissions. Read it before constructing a request so the client does not hard-code capabilities, tracks, models, dates, or limits.

This response describes competition-wide configuration. It does not indicate whether the current caller may submit; use [Get my participation](./get-my-participation.md) for enrollment, team role, and `canSubmit`.

## Example request

```bash
curl "https://api.sair.foundation/api/public/v1/competitions/mathematics-distillation-challenge-equational-theories-stage2" \
  -H "Authorization: Bearer $SAIR_API_KEY"
```

## Example response

The text, publication state, timestamps, limits, tracks, and models below illustrate the response shape. Use the values returned by the live endpoint.

```json
{
  "ok": true,
  "data": {
    "id": "mathematics-distillation-challenge-equational-theories-stage2",
    "title": "Mathematics Distillation Challenge: Equational Theories - Stage 2",
    "description": "Submit a solver that generates Lean proofs for one competition track.",
    "capabilities": {
      "playground": true,
      "contributorNetwork": true,
      "leaderboard": false
    },
    "leaderboardPublished": false,
    "leaderboardTeamDetailsEnabled": false,
    "submissionSpec": {
      "kind": "solver-participation",
      "schema": {
        "type": "object",
        "required": ["track", "modelId", "solverCode"],
        "properties": {
          "track": {
            "type": "string",
            "enum": ["solo", "marathon"]
          },
          "modelId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "enum": ["openai-gpt-oss-120b", "google-gemma-4-31b-it"]
          },
          "solverCode": {
            "type": "string",
            "minLength": 1
          }
        },
        "additionalProperties": false
      },
      "metaSchema": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string",
            "maxLength": 5000
          },
          "contributorNetworkItemId": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "permission": {
        "teamRole": "owner"
      },
      "window": {
        "opensAt": "2026-04-01T00:00:00Z",
        "closesAt": "2026-09-30T23:59:59Z"
      },
      "limits": {
        "maxBytes": 500000,
        "maxEntries": 1
      },
      "catalog": {
        "tracks": [
          {
            "id": "solo",
            "label": "Solo"
          },
          {
            "id": "marathon",
            "label": "Marathon"
          }
        ],
        "models": [
          {
            "id": "openai-gpt-oss-120b",
            "name": "OpenAI GPT-OSS 120B"
          },
          {
            "id": "google-gemma-4-31b-it",
            "name": "Google Gemma 4 31B"
          }
        ]
      }
    }
  }
}
```

## Response fields

| Field | Type | Description |
| :--- | :--- | :--- |
| `id` | string | Stable competition ID used in competition-scoped routes. |
| `title` | string | Display title. |
| `description` | string \| null | Competition description, when configured. |
| `capabilities.playground` | boolean | Whether the competition exposes its Playground workflow. |
| `capabilities.contributorNetwork` | boolean | Whether the competition supports Contributor Network solver items. |
| `capabilities.leaderboard` | boolean | Whether leaderboard results are currently published. |
| `leaderboardPublished` | boolean | Explicit leaderboard publication state. It currently matches `capabilities.leaderboard`. |
| `leaderboardTeamDetailsEnabled` | boolean | Whether a published leaderboard may include the [`teamDetails` projection](../../competitions.md#leaderboard-team-details-and-privacy). |
| `submissionSpec` | object | Live contract for formal Stage 2 submissions. |

### Submission specification

| Field | Description |
| :--- | :--- |
| `kind` | Submission discriminator. Stage 2 returns `solver-participation`. |
| `schema` | JSON Schema for the request's `payload`. Its `track` and `modelId` enums match the current catalog. Unknown payload fields are rejected. |
| `metaSchema` | JSON Schema for optional `meta`. `contributorNetworkItemId`, when supplied, must identify an active solver-template item from this competition. It records attribution and does not require the same track or model. |
| `permission.teamRole` | Required team role. `owner` means only the active team owner may create or replace a formal track/model entry. |
| `window.opensAt` | Formal-submission opening time as an ISO 8601 UTC string, or `null` when no opening time is configured. |
| `window.closesAt` | Formal-submission deadline as an ISO 8601 UTC string, or `null` when no deadline is configured. |
| `limits.maxBytes` | Maximum UTF-8 byte length of `payload.solverCode`; JSON envelope bytes do not reduce this allowance. |
| `limits.maxEntries` | Maximum number of current entries for each unique `(track, modelId)` selection. Stage 2 returns `1` and replaces that pair in place. |
| `catalog.tracks` | Tracks currently accepted for new or replacement submissions. |
| `catalog.models` | Models currently accepted for new or replacement submissions. |

### Catalog entries

| Field | Type | Description |
| :--- | :--- | :--- |
| `catalog.tracks[].id` | string | Case-sensitive track value to send as `payload.track`. |
| `catalog.tracks[].label` | string | Display label for the track. |
| `catalog.models[].id` | string | Case-sensitive model value to send as `payload.modelId`. |
| `catalog.models[].name` | string | Display name for the model. |

The schema enums and catalog describe the same response-time snapshot. A model or track can change after this read, so the write revalidates both values. An existing formal entry remains readable if its model is later removed from the catalog, but that model cannot be used for a new replacement.

Do not infer caller eligibility from the catalog or window alone. Verified email, enrollment, active team membership, owner role, and current competition state are also enforced; [Get my participation](./get-my-participation.md) resolves those checks into `canSubmit` and `submitBlockedReason`.

See [Submit solver](./submit-solver.md) for the request and response fields.

## Errors

| HTTP | Code | When |
| :---: | :--- | :--- |
| `404` | `NOT_FOUND` | The competition does not exist or is not publicly visible. |

See [Errors](../../../errors.md) for shared authentication, scope, and rate-limit errors.
