Skip to main content
POST
/
v1
/
workflows
/
reviews
/
{run_id}
/
{block_id}
/
decision
from retab import Retab

client = Retab()

overlay = client.workflows.runs.reviews.get("run_abc123", "block_extract")
stamp = overlay.version_stamp

# Plain approve — the latest version flows downstream, the run resumes
result = client.workflows.runs.reviews.approve(
    "run_abc123", "block_extract", version_stamp=stamp,
)
print(result.submission_status)

# Approve with edits — server appends a corrective version, then approves it
result = client.workflows.runs.reviews.approve(
    "run_abc123", "block_extract",
    version_stamp=stamp,
    edited_output={"total_amount": 325, "vendor_name": "Acme Corp"},
)

# Reject — the run is cancelled
client.workflows.runs.reviews.reject(
    "run_abc123", "block_extract",
    version_stamp=stamp,
    reason="Source document is illegible; cannot verify totals.",
)

{
  "submission_status": "accepted",
  "overlay": {
    "_id": "run_abc123:block_extract",
    "workflow_run_id": "run_abc123",
    "block_run_id": "run_abc123:block_extract",
    "block_id": "block_extract",
    "workflow_id": "wf_1",
    "status": "approved",
    "rev": 5,
    "decisions": [
      {
        "decision_id": "dec_7f3a01",
        "verdict": "approved",
        "decided_by": { "kind": "human", "id": "user_42", "display_name": "Dana Rivera" },
        "on_seq": 1,
        "effective_seq": 1,
        "reason": null,
        "decided_at": "2026-05-13T09:10:00.000Z"
      }
    ]
  }
}

Documentation Index

Fetch the complete documentation index at: https://docs.retab.com/llms.txt

Use this file to discover all available pages before exploring further.

Submit a verdict against a review overlay. A decision resolves a gated block run. There are two verdicts:
VerdictEffect
approvedThe effective output (latest version) flows downstream and the run resumes.
rejectedThe run is cancelled. reason is required.
Approve with edits. Pass edited_output to an approve call and the server appends a corrective version and then approves it in one atomic step. The model’s original output is preserved as version 0; the edited payload becomes the new effective version that flows downstream. The request body carries:
FieldNotes
verdictapproved / rejected.
version_stampThe overlay rev you last read. Required — see the conflict note below.
edited_outputOptional, approved only. Appends a corrective version, then approves it.
reasonRequired for rejected.
command_idOptional idempotency key — a retried call with the same command_id is deduplicated.
version_stamp is a compare-and-swap token. Send the value you last read from Get Review. If the overlay has advanced since (another actor edited or decided), the call returns 409 — re-read the overlay and retry with the fresh stamp. A stale stamp raises retab.exceptions.ConflictError in Python and surfaces as an APIError with .status === 409 in JavaScript.
The SDK exposes one method per verdict — approve and reject — both of which post to this endpoint.
from retab import Retab

client = Retab()

overlay = client.workflows.runs.reviews.get("run_abc123", "block_extract")
stamp = overlay.version_stamp

# Plain approve — the latest version flows downstream, the run resumes
result = client.workflows.runs.reviews.approve(
    "run_abc123", "block_extract", version_stamp=stamp,
)
print(result.submission_status)

# Approve with edits — server appends a corrective version, then approves it
result = client.workflows.runs.reviews.approve(
    "run_abc123", "block_extract",
    version_stamp=stamp,
    edited_output={"total_amount": 325, "vendor_name": "Acme Corp"},
)

# Reject — the run is cancelled
client.workflows.runs.reviews.reject(
    "run_abc123", "block_extract",
    version_stamp=stamp,
    reason="Source document is illegible; cannot verify totals.",
)

{
  "submission_status": "accepted",
  "overlay": {
    "_id": "run_abc123:block_extract",
    "workflow_run_id": "run_abc123",
    "block_run_id": "run_abc123:block_extract",
    "block_id": "block_extract",
    "workflow_id": "wf_1",
    "status": "approved",
    "rev": 5,
    "decisions": [
      {
        "decision_id": "dec_7f3a01",
        "verdict": "approved",
        "decided_by": { "kind": "human", "id": "user_42", "display_name": "Dana Rivera" },
        "on_seq": 1,
        "effective_seq": 1,
        "reason": null,
        "decided_at": "2026-05-13T09:10:00.000Z"
      }
    ]
  }
}

Authorizations

Api-Key
string
header
required

Path Parameters

run_id
string
required
block_id
string
required

Body

application/json

Submit a verdict against a gated block run.

approved with edited_output appends a corrective version first, then approves it. rejected cancels the workflow run.

verdict
enum<string>
required

The reviewer's verdict.

Available options:
approved,
rejected
version_stamp
integer
required

CAS token: the overlay rev the client last read. 409 on mismatch — re-read and re-decide, never blindly retry the same stamp.

Required range: x >= 0
edited_output
Edited Output · object

Optional FULL corrected output. Valid only with verdict='approved': the server appends it as a human_edit version, then approves that version.

on_seq
integer | null

The version seq the reviewer ruled on. Defaults to the overlay head.

effective_seq
integer | null

The seq to ship downstream. Valid only with verdict='approved'; defaults to on_seq.

reason
string | null

Required for 'rejected'; ignored for 'approved'.

command_id
string | null

Optional idempotency key — a retried submit with the same command_id is deduplicated instead of double-applied.

Response

Successful Response

The result of a decision submission.

submission_status
enum<string>
required

accepted for a fresh decision; already_received / already_applied for an idempotent retry.

Available options:
accepted,
already_received,
already_applied
overlay
ReviewOverlay · object
required

The overlay after the decision was applied.