# Check a Playground answer

```http
POST /api/public/v1/competitions/modular-arithmetic-challenge/playground/check
Content-Type: application/json
```

**Scope**: `playground.write`.

Checks one candidate answer against a deterministic practice case returned by [Generate Playground sample cases](./generate-playground-sample.md). The response is immediate and always reveals the expected answer for a valid case, whether the candidate is correct or not.

This is a stateless practice operation. It does not save attempts, change a Playground Run or formal submission, affect official scores, or consume Playground credits. It requires neither competition enrollment nor a Competition Team and is independent of the formal-submission window. The same `caseId` and `answer` can be retried safely without an idempotency key; normal API [rate limits](../../../rate-limiting.md) still apply.

The endpoint is available for a publicly visible active or closed competition only while `capabilities.playground` is `true`. A draft or disabled Playground returns `404 NOT_FOUND`.

## Answer format

A canonical answer is an ASCII base-10 representation of a non-negative integer:

- `"0"` is canonical.
- A positive value starts with `1` through `9` and is followed only by ASCII digits `0` through `9`.
- Leading or trailing whitespace, a leading zero, `+`, `-`, decimal points, exponent notation, separators, and non-ASCII numerals are not canonical.

Non-canonical input is still a successful check: the endpoint returns `200` with `canonical: false`, `correct: false`, and the expected answer. The service does not trim or rewrite the submitted `answer` before checking it.

## Request fields

| Field    | Type   | Required | Description |
| :------- | :----- | :------: | :---------- |
| `caseId` | string | Yes      | Opaque case ID returned by the sample endpoint. Pass it unchanged; maximum 200 UTF-8 bytes. |
| `answer` | string | Yes      | Candidate answer, compared exactly as supplied. Maximum 2,467 UTF-8 bytes, which covers the largest T0 result. |

## Example request

```bash
curl -X POST \
  "https://api.sair.foundation/api/public/v1/competitions/modular-arithmetic-challenge/playground/check" \
  -H "Authorization: Bearer $SAIR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "caseId": "mc1:8eaf7b045445ab5fd23e6b0f8d3f0f86:1:0",
    "answer": "0"
  }'
```

## Response fields

| Field       | Type    | Always present | Description |
| :---------- | :------ | :------------: | :---------- |
| `caseId`    | string  | Yes            | The checked case ID, returned unchanged. |
| `tierId`    | integer | Yes            | Tier encoded by the valid case ID. |
| `correct`   | boolean | Yes            | `true` only when `answer` is canonical and exactly equals `expected`. |
| `canonical` | boolean | Yes            | Whether `answer` exactly matches `0` or `[1-9][0-9]*` using ASCII digits. |
| `expected`  | string  | Yes            | Canonical expected answer. It is always returned for a valid case. |

## Example response

```json
{
  "ok": true,
  "data": {
    "caseId": "mc1:8eaf7b045445ab5fd23e6b0f8d3f0f86:1:0",
    "tierId": 1,
    "correct": true,
    "canonical": true,
    "expected": "0"
  }
}
```

## Errors

| Status | Code | When |
| :----: | :--- | :--- |
| `400` | `MALFORMED_BODY` | The JSON body, content type, top-level request shape, or field type is invalid. |
| `404` | `NOT_FOUND` | The competition does not exist, is a draft, or does not currently expose the Modular Arithmetic Playground. |
| `422` | `INVALID_CASE` | `caseId` is malformed, over 200 bytes, uses an unsupported case version, or is invalid for the current practice generator. |
| `422` | `INVALID_ANSWER` | `answer` exceeds 2,467 UTF-8 bytes. Non-canonical values within the limit return a successful check instead. |

See [Errors](../../../errors.md) for authentication, scope, rate-limit, and standard error-envelope behavior.
