---
title: "Get Eval Run Gate"
method: GET
path: "/api/platform/v1/eval-runs/{id}/gate"
tags: ["observability"]
---

# Get Eval Run Gate

`GET /api/platform/v1/eval-runs/{id}/gate`

## Request

- Base URL: `https://docs.amdahl.ai`
- URL: `https://docs.amdahl.ai/api/platform/v1/eval-runs/{id}/gate`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

Fetch the machine verdict on the copy the caller SUBMITTED: passed, checks_passed/checks_total, score_15 against its threshold, and which failed. Use when wiring an eval into a pipeline as a send/hold decision: gate is the send/hold signal; overall_score and lift follow the rewrite. Pass wait_ms (max 30000) to block until the run settles. gate is null while running or when the run refused (not_applicable_reason says why); a refusal is not a fail.

## Path parameters

- `id` string, required

## Query parameters

- `wait_ms` integer: Optional long-poll budget in ms, hard-capped at 30000. Blocks until the run reaches complete / failed / canceled, then returns the same body an immediate poll would.

## Response `200`

OK

- object
  - `data` object, required
    - `run_id` string, required
    - `eval_slug` string
    - `eval_version` string: The eval version this run was graded at. Gate thresholds are only comparable within one version — see the eval version ledger.
    - `status` 'queued' | 'running' | 'complete' | 'failed' | 'canceled', required: The run status, at the ROOT of the body — unlike GET /eval-runs/{id}, which nests it under `run`. The terminal success value is `complete` — never `completed`.
    - `gate` object, nullable, required: The machine verdict on the copy the caller SUBMITTED. NULL means this run has no submitted-side grade to gate on — still running, refused (see `not_applicable_reason`), or a grader mix that produced none. Never treat null as a fail: `passed: false` is a verdict on the copy and a refusal is emphatically not one.
      - `passed` boolean, nullable, required: Did the submitted copy clear the pass bar.
      - `checks_passed` integer, nullable
      - `checks_total` integer, nullable
      - `denominator` 'all_dimensions' | 'applicable_only' | 'null', nullable: What `checks_total` counted. `applicable_only` (eval 2.33.0 and later, where the workspace has the flag on) means a rubric line this KIND of artifact could not satisfy left BOTH the numerator and the denominator, so the fraction is over the checks the copy could actually have met. `all_dimensions` counts every line, which is what every row before 2.33.0 means. ⚠️ Read this BEFORE pooling `score_15` across runs, and do NOT infer it from `eval_version`: the behaviour is per-workspace, so two runs stamped 2.33.0 can have been divided differently. Null on a run graded before the field existed — read that as `all_dimensions`, which is what it was.
      - `score_15` number, nullable: The submitted side’s 1-5 score, `1 + 4 * checks_passed/checks_total`. Derived from binary per-line verdicts, so it is a fraction rendered on a five-point dial, not a rating.
      - `threshold` number, nullable: The 1-5 bar `passed` was decided against. Null on runs graded before the bar was stamped — the stored bar there belongs to the IMPROVED side and must not be republished beside the submitted fraction.
      - `basis` 'prompt' | 'message' | 'null', nullable: Which submitted artifact the fraction describes.
      - `simulated` boolean, required: True when the graded "submitted" side is a specimen the eval WROTE (a prompt-only run). A pipeline gating sends must know the fraction describes a simulation.
      - `dimensions_failed` string[], required: Rubric dimensions the submitted side failed, by FULL name. Each entry is the line’s whole text rather than a label, so it reads on its own beside `reasoning`. EXCLUDES lines the caller’s declared `artifact_type` marks not applicable, so it can be shorter than `checks_total - checks_passed`, which still counts every line. The report read names the SAME lines by STEM: `report.findings.failed[].dimension` on GET /eval-runs/{id}/report is the clause before the first colon, because there it renders as a bold lead-in to that line’s `reasoning`. Same lines, two renderings, on purpose — a diff between the two strings is expected, not a bug. This field is also UNCAPPED, where `failed[]` cuts at 8 and says so via `truncated`, so on a tenant-authored eval with a long rubric the two can differ in length as well.
      - `reasoning` string, nullable: The judge’s rationale for the submitted side, verbatim; null when the run recorded none. `dimensions_failed` says WHICH lines failed and this says WHY, so a pipeline gating a send can report something a human can act on rather than a bare count.
      - `critique` string, nullable: What would have to change for the submitted side to pass, in the judge’s own words. Null on a FULL run rather than absent: a full run’s critique is written against the improved side, and publishing it beside the submitted fraction would be the same mistake `threshold` is null there to avoid. Read the null as “not measured on this run”, never as “nothing to say”.
    - `not_applicable_reason` string: Present exactly when the run refused to grade, saying why. A refusal is not a fail.
    - `error_message` string: Present only on a failed run.
    - `regrade` object: Present exactly when this run’s evidence pool is pinnable: the parameter set that holds it fixed for the next call, so a held draft’s edit is graded against the same quotes. Absent otherwise, never partial.

## Other responses

- `400`: Invalid input - failed schema validation
- `401`: Authentication required
- `403`: Forbidden - missing scope or role
- `404`: Not found
- `500`: Internal server error

---

[API](https://skmtc.dev/amdahl/apis/amdahl-platform-api.md) · [All operations](https://skmtc.dev/amdahl/apis/amdahl-platform-api/llms.txt) · [OpenAPI document](https://skmtc.dev/amdahl/apis/amdahl-platform-api/revisions/d4eee33e2472?raw)
