Sign in to run requests with your own sandbox key. Sign in

Guides

Handle human review

Build a review queue on the API — find paused executions, claim them, approve or deny with a note, act in bulk, and reconcile with the audit trail.

When a cascade routes an applicant to human review, the execution stops at awaiting_review and waits. This guide builds the loop your reviewers need: a queue, a claim, a decision with a note, and the trail to prove it. The concepts are in Human review.

  1. Find what is waiting

    Executions that need a person are needs_human_review: true with review_status: in_review. Filter for them, newest first:

    cURL
    curl "https://cascades.crscreditapi.com/api/v1/executions" \
      -H "Authorization: Bearer {{API_KEY}}"

    Add filter[workflow_id] to build one queue per cascade, and use assigned_to_user_id to show who holds each item. Poll this list, or maintain it from execution.* webhooks plus a status check.

  2. Claim the review

    Claim before you show the case to a reviewer so two people never decide the same execution:

    cURL
    curl -X POST "https://cascades.crscreditapi.com/api/v1/executions/1842/review_assignment" \
      -H "Authorization: Bearer {{API_KEY}}" \
      -H "Content-Type: application/json" \
      -d '{
        "assignee": "me"
      }'

    { "assignee": "me" } claims for the user behind the key; { "assignee": null } releases. A review held by someone else answers 403 review_assigned_elsewhere on decision. Each API client maps to one user, so give each reviewer their own client if you need per-person attribution.

  3. Show the reviewer the evidence

    GET /executions/{id} with executions:read:full returns step_outputs — the report fields and the conditions that sent the applicant to review — and GET /executions/{id}/report_artifacts lists the report PDFs. That is what a reviewer reads before deciding.

  4. Record notes as you go

    Notes become note_added events in the audit trail; they are not editable afterwards:

    cURL
    curl -X POST "https://cascades.crscreditapi.com/api/v1/executions/1842/review_notes" \
      -H "Authorization: Bearer {{API_KEY}}" \
      -H "Content-Type: application/json" \
      -d '{
        "note": "Pulled credit report manually; matches OFAC cleanly."
      }'
  5. Approve or deny

    cURL
    curl -X POST "https://cascades.crscreditapi.com/api/v1/executions/1842/review_decisions" \
      -H "Authorization: Bearer {{API_KEY}}" \
      -H "Content-Type: application/json" \
      -d '{
        "decision": "approved",
        "note": "Manual review confirmed; OFAC clean."
      }'
    • approved resumes down the decision's pass_steps.
    • denied resumes down the decision's fail_steps. If an adverse-action node lives in human_review_steps, its draft was already prepared when the execution was flagged; auto_send does not apply to that placement — a person sends the notice from the app.

    In test mode the branch runs inline and you get 200 with the final state. In live mode you get 202 with resume_enqueued: true; poll until status leaves awaiting_review, or wait for execution.completed. A second decision on the same review is 409 review_already_decided.

  6. Reconcile with the audit trail

    cURL
    curl "https://cascades.crscreditapi.com/api/v1/executions/1842/review_events" \
      -H "Authorization: Bearer {{API_KEY}}"

    Events arrive oldest first: flagged (when the cascade paused), assigned / unassigned, note_added, approved or denied, and re_evaluated if the run was replayed. When an adverse-action node parks a notice draft for review, the trail adds adverse_action_drafted, then adverse_action_sent or adverse_action_skipped; adverse_action_replayed marks a sent notice that was resent from the app. Each carries actor_user_id and created_at. Store the trail with your own case record; it is the record of who decided what and when.

Deciding in bulk

For end-of-day sweeps, POST /executions/review_bulk_actions applies approve, deny or assign_to_me to up to 25 ids and reports what it could not do:

cURL
curl -X POST "https://cascades.crscreditapi.com/api/v1/executions/review_bulk_actions" \
  -H "Authorization: Bearer {{API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
    "execution_ids": [
      1842,
      1843,
      1844,
      1845,
      1846
    ],
    "bulk_action": "approve",
    "note": "Manual review batch 2026-09-09 — OFAC and credit clean."
  }'
JSON
{
  "data": {
    "object": "bulk_review_result",
    "applied": 4,
    "enqueued": 4,
    "skipped": [
      { "id": 1846, "reason": "assigned_elsewhere" }
    ]
  },
  "meta": { "request_id": "…" }
}

Bulk decisions are always asynchronous, even in test mode. Ids from another tenant come back as not_found.

Was this page helpful?