Skip to main content

Overview

When a workflow reaches a block with config.review and the predicate fires, the run pauses and creates a review. Address the review by its opaque id, such as rev_...; workflow context like run_id, block_id, step_id, and iteration_key is metadata for filtering and grounding. Reviews hold gate metadata and the terminal decision. Review versions hold immutable output snapshots and are managed separately through reviews.versions.*.

Review Shape

FieldWhat it holds
idOpaque review id.
run_idRun that is paused for review.
block_idWorkflow block that produced the reviewed output.
step_idExact execution step under review.
decisionTerminal verdict, or null while awaiting review.
triggered_byReview predicate that opened the gate.
Review queue items return the same Review shape. Fetch the version history for a given review with reviews.versions.list(review_id=...) — the runtime-created seed is the version whose parent_id is null.

Version Shape

FieldWhat it holds
idContent-addressed version id.
review_idReview this version belongs to.
parent_idParent version id. null appears only on runtime-created seed versions in read responses.
snapshotComplete reviewed output payload for this version.
noteOptional reviewer note.
created_atWhen the version was created.
Versions are peers. There is no head pointer. Use created_at for display ordering, and approve or reject the exact version_id you inspected.

The Review Loop

1. Find the work

queue = client.workflows.reviews.list(
    workflow_id="wf_abc123",
    decision_status="pending",
)

for item in queue.data:
    print(item.id, item.run_id, item.block_id)

2. Inspect the output

item = queue.data[0]
review = client.workflows.reviews.get(item.id)
versions = client.workflows.reviews.versions.list(review_id=review.id)
seed_version = next(v for v in versions.data if v.parent_id is None)

print(review.run_id, review.step_id)
print(seed_version.snapshot)
Use run_id and step_id to inspect the source step and document before deciding.

3. Correct if needed

Create a new version (a complete replacement snapshot) with the reviewed version as parent_id, then approve the returned id. Public clients must provide parent_id when creating correction versions. Versions are a flat CRUD resource at POST /v1/workflows/reviews/versions; the parent id lives in the body, not the URL.
version = client.workflows.reviews.versions.create(
    review_id=review.id,
    parent_id=seed_version.id,
    snapshot={"total_amount": 325, "vendor_name": "Acme Corp"},
    note="Corrected total.",
)

version_id = version.id
Snapshot validation is block-specific:
Block typeSnapshot shape
extractRaw extracted JSON object.
classifier{ "category": "booking_confirmation" } only.
split{ "documents": [{ "name": "invoice", "pages": [1, 2] }] }.
for_each{ "partitions": [{ "key": "INV-001", "pages": [1, 2] }] }.
For split and for-each snapshots, pages must be positive integers, sorted, and unique within each item. The API does not support partial patches.

4. Decide

client.workflows.reviews.approve(review.id, version_id=version_id)

client.workflows.reviews.reject(
    review.id,
    version_id=seed_version.id,
    reason="Source document is illegible; cannot verify totals.",
)
resume_status="resumed" means the workflow accepted the signal. resume_status="pending" means the decision is durable and a backend reconciler will retry the resume.

API Reference

EndpointSDK method
List Reviewsreviews.list(...)
Get Reviewreviews.get(id)
Approve Reviewreviews.approve(...)
Reject Reviewreviews.reject(...)
Create Versionreviews.versions.create(...)
Get Versionreviews.versions.get(id)
List Versionsreviews.versions.list(...)