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

Concepts

Human review

How a cascade pauses for a reviewer, what awaiting_review means for your integration, and the endpoints to claim, decide, note and audit reviews.

An IfElse node can route an applicant to human_review_steps instead of passing or failing them outright — a borderline credit score, a record that needs a person's judgement. When that happens the execution stops at status: awaiting_review with needs_human_review: true and review_status: in_review. The nodes listed in the decision's human_review_steps run immediately (interim work such as a hold email or pre-generating an adverse-action draft); then the execution pauses, and neither pass_steps nor fail_steps runs until someone decides.

Reviewers can decide in the Cascades app; the API exposes the same actions so you can build the review queue into your own tooling.

What happens at a decision?

POST /executions/{id}/review_decisions with { "decision": "approved" | "denied", "note": "…" } records the decision and resumes the matching branch:

  • approved resumes down the decision's pass_steps.
  • denied resumes down the decision's fail_steps. An AdverseAction node placed in human_review_steps has already rendered its draft at flag time; the notice is sent when a reviewer sends it from the app, not by the decision itself (see Adverse action).

Test-mode executions resume inline: the response is 200 OK with the final state and resume_enqueued: false. Live-mode executions enqueue the resume and answer 202 Accepted with resume_enqueued: true; poll GET /executions/{id} until status leaves awaiting_review / waiting, or wait for the webhook.

If nobody has claimed the review, the decision claims it for the caller. Errors:

Code When
409 review_not_pending The execution is not waiting for a review
409 review_already_decided Someone already approved or denied it
403 review_assigned_elsewhere The review is claimed by another user
403 live_mode_forbidden Live execution, account without production access

Claiming and releasing

POST /executions/{id}/review_assignment with { "assignee": "me" } claims the review for the user behind your key; { "assignee": null } releases it. The body field is assignee (not action) because Rails reserves that parameter name. Each API client maps to a single user, so cross-user assignment is not a meaningful operation here — teams with several reviewers use one client per reviewer.

Notes and the audit trail

  • POST /executions/{id}/review_notes with { "note": "…" } appends a note_added event (201 Created).
  • GET /executions/{id}/review_events returns the full trail, oldest first: flagged, assigned, unassigned, approved, denied, note_added, re_evaluated, and the adverse-action notice events adverse_action_drafted, adverse_action_sent, adverse_action_skipped and adverse_action_replayed, each with the actor and timestamp. This is what you reconstruct "who decided what and when" from for compliance.

Deciding many at once

POST /executions/review_bulk_actions applies approve, deny or assign_to_me to up to 25 execution ids in one request. It is always asynchronous (202) and returns { applied, enqueued, skipped }, where skipped lists a reason per id that could not be processed: not_awaiting_review, review_not_pending, assigned_elsewhere, live_mode_forbidden, already_assigned, or not_found. Ids belonging to another tenant are reported as not_found so existence is never leaked.

Finding what needs review

GET /executions?filter[needs_human_review]=true&filter[review_status]=in_review is your queue. Each row carries assigned_to_user_id so you can show who holds it.

Was this page helpful?