Skip to main content

Reviews

A ReviewItem is one trace held for human review under EU AI Act Article 14 oversight. The Policy Engine routes flagged decisions into the review queue (HTTP 202); a reviewer with the admin or owner role approves or rejects, and the verdict is recorded back on the source DecisionTrace. Tested against API version v1. JWT auth on every endpoint plus workspace-access validation.

The endpoint URL is /api/v1/review-queue (the resource is named "Review Queue" in product). This page documents the same resource under the shorter "Reviews" name on the sidebar; the URLs themselves are unchanged.

The ReviewItem object

FieldTypeRequiredDescription
_id / idstringyesMongoDB ObjectId
traceIdstringyesThe DecisionTrace this review is for
agentIdstringnoThe Agent document reference; populated to { name } on list
agentIdStrstringnoFallback string identifier when agentId is absent
actionstringyesThe proposed agent action (e.g., initiate_refund)
confidencenumberyesThe Confidence Engine score at trace time
priorityenumnocritical, high, medium (default), low
statusenumnopending (default), approved, rejected
workflowStepnumbernoCurrent step in the review workflow; default 1
assignedTostringnoUser ObjectId of the reviewer
escalatedAtstring (ISO 8601)noSet when escalation fires
escalatedTostringnoUser ObjectId the item was escalated to
escalationReasonstringnoFree-text rationale
slaDeadlinestring (ISO 8601)noHard deadline used by the Multi-Clock Hub when applicable
contextobjectnoThe matching trace context, PII-scrubbed on output
payloadobjectnoThe trace payload, PII-scrubbed on output
decisionenumnoapprove or reject; set on resolution
reasonstringnoReviewer-provided rationale, max 1,000 chars
notesstringnoReviewer-provided free-form notes, max 2,000 chars
organizationId / workspaceIdstringyesTenancy scope; chains never mix across tenants
createdAt / updatedAtstring (ISO 8601)noStandard timestamps

Endpoints

GET    /api/v1/review-queue
POST /api/v1/review-queue/:id/decision
POST /api/v1/review-queue/bulk-decision
PATCH /api/v1/review-queue/:id/assign
POST /api/v1/review-queue/:id/escalate

GET, assign, and escalate are available to any authenticated member of the workspace. decision and bulk-decision require the admin or owner role.

List the queue

GET /api/v1/review-queue
Query parameterDescription
statusFilter to pending / approved / rejected; absent returns every status

Workspace scope comes from the x-workspace-id header (resolved by validateWorkspaceAccess). Sort order is most-recent-first (createdAt DESC). The server hard-caps at 500 items; consumers should respect the truncated flag on the response and refine the filter rather than paging through.

curl — pending items only
curl "https://api.adjudon.com/api/v1/review-queue?status=pending" \
-H "Authorization: Bearer $ADJUDON_API_KEY"
Python
import os, requests
r = requests.get(
"https://api.adjudon.com/api/v1/review-queue",
params={"status": "pending"},
headers={"Authorization": f"Bearer {os.environ['ADJUDON_API_KEY']}"},
)
data = r.json()["data"]

Response (200 OK):

{
"success": true,
"data": [/* ReviewItem[] (PII-scrubbed) */],
"count": 42,
"total": 42,
"limit": 500,
"truncated": false
}

payload and context are PII-scrubbed before transport (email, IBAN, credit-card, SSN, phone). Errors: 401, 403 (workspace access), 500 INTERNAL_ERROR.

Make a decision

POST /api/v1/review-queue/:id/decision
Body fieldRequiredDescription
decisionyesapprove or reject
reasonnoReviewer rationale, max 1,000 characters
notesnoFree-form notes, max 2,000 characters
curl — approve
curl -X POST https://api.adjudon.com/api/v1/review-queue/65b1f2c4/decision \
-H "Authorization: Bearer $ADJUDON_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "decision": "approve", "reason": "Risk acceptable per Q3 policy" }'

The decision is final — once an item is approved or rejected, the same endpoint returns 400 INVALID_OPERATION. To revisit a finished review, escalate or open a new trace.

Errors: 400 VALIDATION_ERROR, 400 INVALID_OPERATION (already decided), 401, 403 (role), 404 NOT_FOUND, 500.

Bulk decision

POST /api/v1/review-queue/bulk-decision
Body fieldRequiredDescription
idsyesArray of ReviewItem ObjectIds; 1 to 100 items
decisionyesapprove or reject (applied to all)
reasonnoShared rationale, max 1,000 characters

The bulk endpoint applies the same verdict to every still-pending item in the array. Items that have already been decided are silently skipped; if no pending items match the supplied ids the server returns 404 NOT_FOUND.

curl
curl -X POST https://api.adjudon.com/api/v1/review-queue/bulk-decision \
-H "Authorization: Bearer $ADJUDON_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"ids": ["65b1f2c4", "65b1f2c5", "65b1f2c6"],
"decision": "approve",
"reason": "End-of-quarter cleanup"
}'

Errors: 400 VALIDATION_ERROR (empty ids, >100 ids, invalid decision), 401, 403, 404, 500.

Assign a reviewer

PATCH /api/v1/review-queue/:id/assign
Body fieldRequiredDescription
assignedTonoUser ObjectId; omit to clear the assignment

Errors: 400 VALIDATION_ERROR, 401, 404, 500.

Escalate an item

POST /api/v1/review-queue/:id/escalate
Body fieldRequiredDescription
reasonnoFree-text rationale, max 1,000 characters
escalateTonoUser ObjectId; if omitted, the workspace's escalation policy decides

Sets escalatedAt, escalatedTo, and escalationReason on the item. The item stays pending — escalation moves the reviewer, not the verdict. Errors: 400, 401, 404, 500.

Common gotchas

  • URL is /review-queue, not /reviews. The page is named "Reviews" on the sidebar but the live endpoint is mounted at /api/v1/review-queue. Cross-links inside the docs use the page slug /api-reference/reviews; the API call uses /review-queue.
  • Decisions are final. A second decision on the same item returns 400 INVALID_OPERATION. The audit log retains the original verdict regardless.
  • Idempotency. The Idempotency-Key middleware is wired only on POST /traces; POST /decision and POST /bulk-decision are mutating but do not auto-receive idempotency keys today. A retried decision on the same id is harmless because the second attempt fails with INVALID_OPERATION; a retried bulk-decision with overlapping ids is the same.
  • Hard cap of 500. The list endpoint returns at most 500 items per request and signals truncation via the truncated flag. Filter by status to keep the working set well below the cap.

See also