---
title: "Get a run's gate waiver"
method: GET
path: "/projects/{projectId}/eval-runs/{runId}/gate-waivers"
tags: ["Eval runs"]
---

# Get a run's gate waiver

`GET /projects/{projectId}/eval-runs/{runId}/gate-waivers`

The waiver in force over this run, or `null`. Available to anyone who can VIEW the run, not only to those who can grant one — a waiver its readers cannot see is not a visible waiver.

A client gating on this run does not need this endpoint: `GET /eval-runs/{runId}` already carries `gateWaiver`, so a gate can fold one in without a second round trip.

## Path parameters

- `projectId` string, required
- `runId` string, required

## Response `200`

The active waiver, or null.

- GateWaiverRead — The waiver in force over a run, or `null` when there is none.
  - `waiver` GateWaiver, required — An audited, time-boxed override of an eval run's release gate. A waiver never changes the run's own `result` — the run keeps its verdict and every surface that honors the waiver says so out loud, which is what makes "no silent waiver" checkable rather than promised.
    - `id` string, required
    - `suiteId` string, required
    - `runId` string, nullable, required — The run this waiver covers. Suite-wide waivers are not honored.
    - `reason` string, required — Why the gate was overridden, as the granter wrote it. Stored UNREDACTED and readable by anyone who can see the suite, for as long as the suite exists — never put secrets, tokens, or customer data in it.
    - `expiresAt` integer, required — Epoch ms. Always in the future when granted, and capped at 30 days out — there is no permanent waiver.
    - `createdAt` integer, required
    - `createdBy` string, required
    - `createdByEmail` string, nullable, required — `null`, never absent, when it cannot be resolved — a deleted user must not make a waiver look authorless.
    - `revokedAt` integer, nullable, required
    - `revokedBy` string, nullable, required
    - `active` boolean, required — Whether it is in force right now — neither revoked nor expired. Computed at read time; a client that must not honor a lapsed waiver should re-derive it from `expiresAt` rather than trust it.
    - `policySnapshot` object, nullable, required — WHAT was overridden, captured at waive time so a later edit to the suite cannot rewrite the record. `null` for a run decided by the v2 verdict policy, whose identity is recorded on the audit event instead — this shape cannot hold it, and filling it in would be a false record rather than an incomplete one.
      - `minimumPassRate` number, required

## Other responses

- `401` — Missing, invalid, revoked, or orphaned key (`UNAUTHORIZED`) — or the **target MCP server** needs an OAuth grant (`OAUTH_REQUIRED`), which is a property of the server, not your key.
- `403` — Key is valid but not allowed to do this.
- `404` — Unknown project, server, or resource.
- `429` — Per-key rate limit exceeded (60 requests/minute sustained, bursts up to 10). Honor `Retry-After` and back off with jitter.
- `500` — Something failed on MCPJam's side.

## Changes

- **2026-08-25** `172afb703db1` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/mcpjam/apis/mcpjam-api/changes/projects/:projectId/eval-runs/:runId/gate-waivers/get.md)

---

[API](https://skmtc.dev/mcpjam/apis/mcpjam-api.md) · [All operations](https://skmtc.dev/mcpjam/apis/mcpjam-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/mcpjam/mcpjam-api/revisions/3d62c6919d8d/schema)
