---
title: "Record a review decision on a run"
method: POST
path: "/api/v1/runs/{id}/review"
tags: ["Runs"]
---

# Record a review decision on a run

`POST /api/v1/runs/{id}/review`

## Request

- Base URL: `https://dungbeetle.dev`
- URL: `https://dungbeetle.dev/api/v1/runs/{id}/review`
- Auth: one of:
  - HTTP basic
  - HTTP bearer

Approve/reject/pend a run. With `promote: true` on an approval, the run's candidate snapshots become new hosted baseline versions. Reviews made with an agent token are attributed to the agent ("<label> (agent, on behalf of <owner>)"). Requires the `reviews:write` scope on agent tokens; `promote: true` additionally requires `baselines:write` (promotion writes to the baseline source of truth), so Triage-scoped tokens can review but not promote.

## Path parameters

- `id` string, required

## Request body

- object
  - `state` 'pending' | 'approved' | 'rejected', required
  - `note` string
  - `promote` boolean: Only honored when `state` is `approved`. Agent tokens must also hold the `baselines:write` scope.

## Response `200`

Review recorded.

- object
  - `review` ReviewEntry, required
    - `id` integer, required
    - `runId` string, required
    - `state` 'pending' | 'approved' | 'rejected', required
    - `reviewer` string, required: The owner's email, or "<label> (agent, on behalf of <owner>)" for agent-token reviews.
    - `note` string, nullable, required
    - `createdAt` string, required
  - `promoted` object[], required
    - `target` string, required
    - `version` integer, required
    - `deduped` boolean, required

## Other responses

- `400`: Invalid body or parameter (`code: validation_error`), or — on screenshot upload — a body that does not hash to the digest (`code: digest_mismatch`).
- `401`: Missing/malformed Authorization header (`code: unauthorized`), bad Basic credentials (`code: invalid_credentials`), or an invalid, expired, or revoked agent token (`code: invalid_agent_token`).
- `403`: Agent token outside its granted scopes (`code: missing_scope`, with a `scope` field naming the required scope) or a route that is not agent-accessible at all (`code: agent_forbidden`). Basic-auth requests never see this.
- `404`: No such resource in this repository (`code: not_found`).
- `413`: Request body exceeds the configured limit (default 25 MiB) (`code: payload_too_large`).
- `429`: Too many failed attempts or uploads from this client (`code: rate_limited`). Honor the `Retry-After` header; successful authenticated requests never count toward the limit.

---

[API](https://skmtc.dev/dungbeetle/apis/dungbeetle-cloud-api.md) · [All operations](https://skmtc.dev/dungbeetle/apis/dungbeetle-cloud-api/llms.txt) · [OpenAPI document](https://skmtc.dev/dungbeetle/apis/dungbeetle-cloud-api/revisions/74778b90420a?raw)
