# Get remaining pairs

```http
GET /api/public/v1/competitions/igp24/remaining-pairs
```

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

Returns the frozen official set of canonical valid `(24Tt, r)` pairs with no credited non-baseline participant team. Each item is the flattened equivalent of one value in [`remainingSignatures`](./get-label-progress.md#label-progress).

This endpoint never includes post-event validation discoveries. A returned pair is officially uncovered; it is not necessarily mathematically unknown or still undiscovered after the official deadline. It exposes no team identities, submissions, or polynomial coefficients.

## Query parameters

| Parameter | Type | Required | Description |
| :--- | :--- | :---: | :--- |
| `limit` | integer | No | Default `100`; minimum `1`, maximum `5000`. |
| `cursor` | string | No | Opaque cursor returned as `nextCursor` by the previous page. |

Items are ordered by ascending `t`, then ascending `r`. Unlike label progress, this endpoint paginates individual pairs, so a page boundary can split the remaining signatures of one label. Pass each non-null `nextCursor` back unchanged until it becomes `null`; do not decode or construct cursors.

## Response fields

| Field | Type | Description |
| :--- | :--- | :--- |
| `generatedAt` | string | ISO 8601 UTC time when this response page was generated. It is not a dataset version or discovery timestamp. |
| `items[]` | [Remaining pair](#remaining-pair)[] | Page of officially uncovered canonical pairs, ordered by ascending `t`, then `r`. Empty while `meta.published` is `false`. |
| `nextCursor` | string \| null | Cursor for the next page, or `null` when this traversal is complete. |
| `meta.published` | boolean | Whether the frozen official progress projection is published. |
| `meta.publishedAt` | string \| null | ISO 8601 UTC publication time, or `null` while unpublished. |

While official progress is unpublished, the endpoint still returns `200 OK` with `items: []`, `nextCursor: null`, `meta.published: false`, and `meta.publishedAt: null`.

### Remaining pair

| Field | Type | Description |
| :--- | :--- | :--- |
| `label` | string | Canonical transitive-group label `24Tt`, derived from `t`. |
| `t` | integer | Numeric transitive-group position in the range `1` through `25000`. |
| `r` | integer | Canonical valid signature for this `t`, with no officially credited non-baseline participant team. |

## Example request

```bash
curl "https://api.sair.foundation/api/public/v1/competitions/igp24/remaining-pairs?limit=2" \
  -H "Authorization: Bearer $SAIR_API_KEY"
```

## Example response

The generated time, returned pairs, cursor, and publication time below illustrate the response shape. Use the values returned by the endpoint, and treat `nextCursor` as opaque.

```json
{
  "ok": true,
  "data": {
    "generatedAt": "2026-07-13T10:30:00Z",
    "items": [
      {
        "label": "24T100",
        "t": 100,
        "r": 2
      },
      {
        "label": "24T100",
        "t": 100,
        "r": 6
      }
    ],
    "nextCursor": "WzEwMCw2XQ==",
    "meta": {
      "published": true,
      "publishedAt": "2026-06-18T02:50:30Z"
    }
  }
}
```

The frozen official set does not change when post-event validation accepts new discoveries. `generatedAt` is evaluated independently for each response page and can differ during one traversal without indicating that the official records changed.

Use [Get label progress](./get-label-progress.md) when a client needs the same official coverage grouped by label, including discovered signatures, team counts, and scoring discriminants.

## Errors

| HTTP | Code | When |
| :---: | :--- | :--- |
| `400` | `MALFORMED_BODY` | `limit` is malformed or outside `1` through `5000`, or the cursor cannot be decoded. |
| `404` | `NOT_FOUND` | IGP24 does not exist or is not publicly visible. |
| `503` | `IGP24_SERVICE_UNAVAILABLE` | The frozen official progress service is temporarily unavailable. |

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