---
title: "Get a single review-hold lifecycle row by id"
method: GET
path: "/safe-house/reviews/{review_id}"
tags: ["Safe House"]
---

# Get a single review-hold lifecycle row by id

`GET /safe-house/reviews/{review_id}`

## Request

- Base URL: `https://api.mnemom.ai/v1`
- URL: `https://api.mnemom.ai/v1/safe-house/reviews/{review_id}`
- Auth: API key in header `X-Mnemom-Agent-Proof`

Agent-scoped (Task A2, canonical-consumer plan): returns **404, never 403**, for a `review_id` belonging to another agent — the lookup is always scoped to the caller's own authenticated identity, so an unowned id and an unknown id are indistinguishable (no existence leak).

## Path parameters

- `review_id` string, required

## Response `200`

The review-hold lifecycle row.

- ReviewLifecycle: A Safe House review-hold lifecycle row, as read by `GET /v1/safe-house/reviews[/{review_id}]` (Task A1/A2, canonical-consumer plan). This is the reconcile/backfill ("pull, truth") leg of the review-hold lifecycle — the same shape delivered live via the `sh.review.*` webhook ("push, latency"). Reflects the already-attested `screen.review` jsonb off `safe_house_decisions`; this API never writes to that table.
  - `review_id` string, required
  - `status` 'pending' | 'allowed' | 'denied' | 'expired', required
  - `surface` 'incoming' | 'tool_call' | 'tool_response', required
  - `verdict` string, required: The reconciled verdict on the ruling `safe_house_decisions` row.
  - `reason` string, nullable, required
  - `reviewer_model` string, nullable, required: Pinned reviewer model, e.g. `claude-opus-4-8`, when the review was adjudicated.
  - `triggered_at` string, date-time, nullable, required
  - `resolved_at` string, date-time, nullable, required
  - `turn_index` integer, nullable, required

## Other responses

- `401`: Authentication required
- `404`: Resource not found
- `429`: Rate-limit exceeded. The global per-IP limiter (100 requests/minute, applied to every `/v1/*` route) rejected this request. Back off until the window resets — `Retry-After` carries the cooldown in seconds and `X-RateLimit-Reset` the absolute reset time.
- `500`: Server error — request was well-formed but the server failed to fulfill it. Typically a downstream dependency (DB / RPC / external API) returned an unexpected error.

---

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