# Get IGP24 submission batch status

```http
GET /api/public/v1/competitions/{competitionId}/submissions/batch/{batchId}
```

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

Polls the asynchronous verification status of an official IGP24 submission batch. Use the `batchId` returned by [`POST /submissions`](./submit.md#inverse-galois-problem-igp24).

The caller may read batches submitted by their own account and batches belonging to a team they own. An unknown or non-visible batch returns the same `404 BATCH_NOT_FOUND` response.

## Parameters

| Parameter | Location | Type | Required | Description |
| :--- | :--- | :--- | :---: | :--- |
| `competitionId` | path | string | Yes | IGP24 competition ID. Use `igp24`. |
| `batchId` | path | string | Yes | Batch ID returned when the official submission was accepted. |

## Response DTO

```ts
type GetIgp24SubmissionBatchStatusResponse = {
  ok: true;
  data: {
    batchId: string;
    batchStatus: 'queued' | 'complete' | 'failed' | 'empty';
    totalCount: number;
    queuedCount: number;
    verifiedCount: number;
    failedCount: number;
    polynomials: Igp24BatchPolynomial[];
  };
};

type Igp24BatchPolynomial =
  | {
      polynomialIndex: number;
      status: 'queued';
      submittedAt: string;
    }
  | {
      polynomialIndex: number;
      status: 'ok';
      submittedAt: string;
      label: string;
      t: number;
      r: number;
      scoreable: boolean;
      scoringStatus: 'pending' | 'scoreable' | 'not_scoreable' | 'no_score';
      scoringReason?: string;
      noScoreReason?: string | null;
      reason?: string;
      inBaseline: boolean;
      baselineUnlocked: boolean;
      baselineDiscAbs?: string;
      fieldDiscAbs?: string;
      discSource?: 'exact_nfdisc' | 'mixed_disc';
    }
  | {
      polynomialIndex: number;
      status: 'invalid' | 'error';
      submittedAt?: string;
      reason: string;
    };
```

## Response fields

| Field | Type | Description |
| :--- | :--- | :--- |
| `batchId` | string | Polled batch ID. |
| `batchStatus` | `queued` \| `complete` \| `failed` \| `empty` | Aggregate state described below. |
| `totalCount` | integer | Number of original submitted polynomial positions represented in `polynomials[]`. |
| `queuedCount` | integer | Entries whose verification is still queued. |
| `verifiedCount` | integer | Entries whose verification status is `ok`. |
| `failedCount` | integer | Entries whose status is `invalid` or `error`. |
| `polynomials[]` | `Igp24BatchPolynomial[]` | Per-input-position results ordered by zero-based `polynomialIndex`. Duplicate input polynomials still occupy separate original positions. |

### Aggregate status

| Value | Meaning |
| :--- | :--- |
| `queued` | At least one polynomial is still queued. |
| `complete` | Nothing is queued and at least one polynomial verified successfully; failed entries may also be present. |
| `failed` | Nothing is queued and no polynomial verified successfully, but at least one failed. |
| `empty` | The visible batch contains no polynomial entries. |

### Per-polynomial fields

| Field | Type | Status | Description |
| :--- | :--- | :--- | :--- |
| `polynomialIndex` | integer | All | Zero-based position in the original submission request. |
| `status` | `queued` \| `ok` \| `invalid` \| `error` | All | Current verification state. |
| `submittedAt` | string | Usually all | ISO 8601 UTC storage time. Omitted for an input rejected before it entered persistent verification storage. |
| `label` | string | `ok` | Computed transitive group label. |
| `t` | integer | `ok` | Computed transitive group index. |
| `r` | integer | `ok` | Computed real-root count/signature. |
| `scoreable` | boolean | `ok` | Whether the current scoring state makes the result scoreable. |
| `scoringStatus` | string enum | `ok` | One of `pending`, `scoreable`, `not_scoreable`, or `no_score`. |
| `scoringReason` | string | `ok`, optional | Stable reason code explaining the scoring state. |
| `noScoreReason` | string \| null | `ok`, optional | More specific no-score reason for applicable baseline results. |
| `reason` | string | `ok`, optional; failed, required | Human-readable scoring explanation or verification failure reason. |
| `inBaseline` | boolean | `ok` | Whether `(t, r)` belongs to the baseline. |
| `baselineUnlocked` | boolean | `ok` | Whether this result unlocks and improves the applicable baseline. |
| `baselineDiscAbs` | string | `ok`, optional | Absolute baseline discriminant as a decimal string. |
| `fieldDiscAbs` | string | `ok`, optional | Exact absolute number-field discriminant as a decimal string. |
| `discSource` | `exact_nfdisc` \| `mixed_disc` | `ok`, optional | Discriminant source when available. |

## Example

```bash
curl "https://api.sair.foundation/api/public/v1/competitions/igp24/submissions/batch/igp24_batch_4fa85f64f18d4dc59eea4d2ef65db490" \
  -H "Authorization: Bearer $SAIR_API_KEY"
```

```json
{
  "ok": true,
  "data": {
    "batchId": "igp24_batch_4fa85f64f18d4dc59eea4d2ef65db490",
    "batchStatus": "queued",
    "totalCount": 4,
    "queuedCount": 1,
    "verifiedCount": 1,
    "failedCount": 2,
    "polynomials": [
      {
        "polynomialIndex": 0,
        "status": "ok",
        "submittedAt": "2026-05-18T12:34:56Z",
        "label": "24T25000",
        "t": 25000,
        "r": 1,
        "scoreable": true,
        "scoringStatus": "scoreable",
        "inBaseline": false,
        "baselineUnlocked": false,
        "fieldDiscAbs": "12345678901234567890",
        "discSource": "exact_nfdisc"
      },
      {
        "polynomialIndex": 1,
        "status": "queued",
        "submittedAt": "2026-05-18T12:34:56Z"
      },
      {
        "polynomialIndex": 2,
        "status": "invalid",
        "submittedAt": "2026-05-18T12:34:56Z",
        "reason": "not irreducible of degree 24"
      },
      {
        "polynomialIndex": 3,
        "status": "error",
        "submittedAt": "2026-05-18T12:34:56Z",
        "reason": "verification could not be completed"
      }
    ]
  }
}
```

Continue polling while `queuedCount` is greater than zero. Apply backoff and the general rate-limit headers described in [Rate limiting](../../../rate-limiting.md).

## Errors

| HTTP | Code | When |
| :---: | :--- | :--- |
| `400` | `NOT_IGP24` | Batch polling was requested for a non-IGP24 competition. |
| `404` | `NOT_FOUND` | The competition does not exist. |
| `404` | `BATCH_NOT_FOUND` | No batch is visible to the caller for this `batchId`. |

See [Errors](../../../errors.md) for authentication, authorization, and common errors.
