# Get a Playground problem set

```http
GET /api/public/v1/competitions/mathematics-distillation-challenge-equational-theories-stage2/playground/problem-sets/{problemSetId}
```

**Scope**: `playground.read`.

Returns one page of ordered equational problems from a public Stage 2 practice problem set.

Each problem asks whether Equation 1 implies Equation 2 over all magmas. The `lhs` and `rhs` field names are historical: they identify the complete Equation 1 hypothesis and Equation 2 goal, not the two sides of one equation. The texts are equation syntax rather than Lean source, and both `*` and `◇` are accepted as the magma operation symbol.

Only platform-maintained public problems can appear in this endpoint. Caller-owned [custom problems](./custom-problems.md) remain private and are never returned as problem-set members.

To use a problem in a [Playground Run](./create-playground-run.md), send its `id` in `problemIds`. The `problemSetId` itself is not a valid problem ID. Run creation revalidates each selected problem and stores an input snapshot, so later catalog changes do not alter an existing Run.

## Path parameters

| Parameter | Type | Required | Description |
| :--- | :--- | :---: | :--- |
| `problemSetId` | string | Yes | Problem-set ID returned by [List Playground problem sets](./list-playground-problem-sets.md). |

## Query parameters

Follow the shared [cursor traversal rules](../../../pagination.md). Items are returned in the problem set's configured order, with problem ID as the stable tie-breaker.

| Parameter | Type | Required | Default | Description |
| :--- | :--- | :---: | :--- | :--- |
| `cursor` | string | No | — | Opaque cursor from the previous `nextCursor`. |
| `limit` | integer | No | `25` | Page size from `1` through `100`. |

## Response fields

| Field | Type | Description |
| :--- | :--- | :--- |
| `id` | string | Problem-set ID. |
| `title` | string | Human-readable title. |
| `description` | string \| null | Short catalog description, or `null` when none is configured. |
| `count` | integer | Total number of public problems across all pages of this problem set. |
| `updatedAt` | string | ISO 8601 UTC time of the latest metadata, ordering, or content change. |
| `items` | [ProblemSetProblem](#problem-set-problem-fields)[] | Problems on this page, in configured set order. |
| `nextCursor` | string \| null | Cursor for the next page, or `null` after the final page. |

### Problem-set problem fields

| Field | Type | Description |
| :--- | :--- | :--- |
| `position` | integer | Zero-based position in the current problem-set ordering. |
| `id` | string | Stable problem ID to send in `problemIds`. |
| `lhsName` | string | Display name for Equation 1. |
| `lhsText` | string | Complete Equation 1 hypothesis. |
| `rhsName` | string | Display name for Equation 2. |
| `rhsText` | string | Complete Equation 2 goal. |
| `isCustom` | boolean | Always `false` for a public problem-set member. |

The response does not expose the expected verdict, reference proof, or other evaluation data.

## Example request

```bash
curl "https://api.sair.foundation/api/public/v1/competitions/mathematics-distillation-challenge-equational-theories-stage2/playground/problem-sets/pset_easy?limit=25" \
  -H "Authorization: Bearer $SAIR_API_KEY"
```

## Example response

```json
{
  "ok": true,
  "data": {
    "id": "pset_easy",
    "title": "Easy implications",
    "description": "Introductory equational implication problems.",
    "count": 1,
    "updatedAt": "2026-08-31T07:45:12Z",
    "items": [
      {
        "position": 0,
        "id": "prob_01JSTAGE200000000000000001",
        "lhsName": "Commutativity",
        "lhsText": "x * y = y * x",
        "rhsName": "Reverse commutativity",
        "rhsText": "y * x = x * y",
        "isCustom": false
      }
    ],
    "nextCursor": null
  }
}
```

Problem-set pagination is not a historical snapshot. If `updatedAt` changes while traversing pages, restart without a cursor before treating the collected IDs as one current set. De-duplicate IDs when catalog changes could overlap a traversal.

## Errors

See [Errors](../../../errors.md). An invalid `cursor` or `limit` returns `400 MALFORMED_BODY`. A missing, empty, or unavailable public problem set returns `404 NOT_FOUND`. An unavailable competition also returns `404 NOT_FOUND`.
