Review queue
The review queue is where approval requests wait for a person to approve or deny them. These endpoints list the queue, retrieve one request, claim it while you look at it, and record your decision.
List the review queue
Returns the list of approval requests that reached human review: pending, decided by a person, or expired while waiting. Approval requests the pipeline decided automatically are not included. They stay in the audit log and can still be retrieved by id. Requests are returned newest first.
Pass agent_slug to list one agent's requests instead. That list includes the requests the pipeline decided automatically.
Request
Parameters
| Parameter | Type | Description |
|---|---|---|
limit | query · integer | How many requests to return. Defaults to 50, at most 200. |
agent_slug | query · string | Show one agent's requests instead of the queue, including the ones the pipeline decided. |
offset | query · integer | Number of visible matching requests to skip before returning this page. |
q | query · string | Case-insensitive literal substring of the tool or instance name. |
status | query · enum | Return only requests with this outcome. One of pending, approved, denied, expired, cancelled |
scope | query · enum | Which layer of the queue to return, from the caller's standpoint. One of notified, decidable, visible |
Response
Response codes
| Status | Body | Description |
|---|---|---|
200 | object | The requests, newest first |
400 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
401 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
403 | ErrorResponse | You cannot read requests |
Response body200
Example
curl -X GET "$WITHHUMAN_URL/api/v1/requests" \
-H "Authorization: Bearer $WITHHUMAN_API_KEY"{
"requests": [
{
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"organization_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"agent_slug": "support-agent",
"agent_instance_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"agent_name": "support-agent",
"agent_instance_name": "ci-runner-07",
"tool": "issue_refund",
"server": "stripe",
"arguments": {
"amount": 4900,
"reason": "duplicate_charge"
},
"agent_reasoning": "Refunding the duplicate charge for [email protected].",
"context": {
"run_id": "4821",
"framework": "claude-code"
},
"status": "approved",
"deadline_at": "2026-09-09T12:00:00Z",
"created_at": "2026-09-08T12:00:00Z",
"decision": {
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"request_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"organization_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"membership_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"status": "approved",
"note": "OK, but flag this account for review.",
"channel": "web",
"reviewer_display_name": "Chris",
"reviewer_email": "[email protected]",
"authentication": {
"method": "local_password",
"assurance": "strong",
"authenticated_at": "2026-09-08T12:02:11Z",
"session_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"credential_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71"
},
"idempotency_key": "decision-7ab8c8ec",
"decided_at": "2026-09-08T12:02:11Z"
},
"updated_at": "2026-09-08T12:05:00Z",
"claim": {
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"membership_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"display_name": "Chris",
"claimed_at": "2026-09-08T12:01:30Z",
"expires_at": "2026-09-08T12:16:30Z"
},
"presentation": {
"source": "built_in",
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"title": "Edit {{/file_path}}",
"fields": [
{
"path": "/body",
"label": "Body",
"kind": "text",
"language": "python",
"before": "/old_string",
"after": "/new_string",
"item": {},
"role": "primary"
}
]
}
}
]
}Retrieve a request
Returns one approval request. The response includes its current status, its decision once there is one, and any claim a reviewer holds on it. Pass wait to hold the response until the request is decided.
Request
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequired | path · uuid | The request's id. |
wait | query · string | How long to hold the response for a decision, as a duration such as |
Response
Response codes
| Status | Body | Description |
|---|---|---|
200 | ApprovalRequest | The request in its current state |
401 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
403 | ErrorResponse | You cannot read requests |
404 | ErrorResponse | No such request |
Response body200
The slug of the agent that made the request.
The running copy of the agent that made the request.
The agent's name when the request was made.
The instance's name when the request was made.
The tool the agent wants to call, as the server that defines it names it.
The MCP server that defines the tool, as the adapter reported it. Absent for a runtime's built-in tools.
The exact arguments the tool will run with if approved.
The agent's own explanation, if it gave one.
Where the call comes from, as recorded by the adapter.
pending while waiting for a decision, then one of the four final states. cancelled means the requesting instance withdrew it; treat it as a denial.
One of pending, approved, denied, expired, cancelled
When the request expires if nobody has decided: created_at plus the timeout.
Moves on every change a reviewer should notice, escalation progress included, so a client refetches the review when it changes.
A reviewer's claim on a pending request: an advisory marker that they are looking at it. Absent once released, lapsed, or the request is no longer pending.
The presentation a request renders with and where it came from.
Example
curl -X GET "$WITHHUMAN_URL/api/v1/requests/{id}?wait=30s" \
-H "Authorization: Bearer $WITHHUMAN_API_KEY"{
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"organization_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"agent_slug": "support-agent",
"agent_instance_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"agent_name": "support-agent",
"agent_instance_name": "ci-runner-07",
"tool": "issue_refund",
"server": "stripe",
"arguments": {
"amount": 4900,
"reason": "duplicate_charge"
},
"agent_reasoning": "Refunding the duplicate charge for [email protected].",
"context": {
"run_id": "4821",
"framework": "claude-code"
},
"status": "approved",
"deadline_at": "2026-09-09T12:00:00Z",
"created_at": "2026-09-08T12:00:00Z",
"decision": {
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"request_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"organization_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"membership_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"status": "approved",
"note": "OK, but flag this account for review.",
"channel": "web",
"reviewer_display_name": "Chris",
"reviewer_email": "[email protected]",
"authentication": {
"method": "local_password",
"assurance": "strong",
"authenticated_at": "2026-09-08T12:02:11Z",
"session_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"credential_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71"
},
"idempotency_key": "decision-7ab8c8ec",
"decided_at": "2026-09-08T12:02:11Z"
},
"updated_at": "2026-09-08T12:05:00Z",
"claim": {
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"membership_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"display_name": "Chris",
"claimed_at": "2026-09-08T12:01:30Z",
"expires_at": "2026-09-08T12:16:30Z"
},
"presentation": {
"source": "built_in",
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"title": "Edit {{/file_path}}",
"fields": [
{
"path": "/body",
"label": "Body",
"kind": "text",
"language": "python",
"before": "/old_string",
"after": "/new_string",
"item": {},
"role": "primary"
}
]
}
}Claim a request
Marks a pending request as being looked at by you. Other reviewers see who has it, and its notifications pause. A claim is advisory: anyone allowed to decide the request can still decide it.
A claim lapses after the organization's claim timeout, 15 minutes by default. It also lapses at the request's deadline if that comes first. Claiming a request you already hold returns the same claim. You cannot claim a request another reviewer holds. Wait for their claim to lapse, or for them to release it.
Owners and reviewers can claim. If the request was routed to an escalation path, only the people on that path can claim it. Owners can always claim.
Request
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequired | path · uuid | The request's id. |
Response
Response codes
| Status | Body | Description |
|---|---|---|
200 | object | The claim you hold |
401 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
403 | ErrorResponse | You cannot claim this request. Your membership is inactive, you lack permission to decide, or the request was routed to other people |
404 | ErrorResponse | No such request |
409 | ErrorResponse | Another reviewer holds the claim, or the request is no longer pending |
Response body200
Example
curl -X POST "$WITHHUMAN_URL/api/v1/requests/{id}/claim" \
-H "Authorization: Bearer $WITHHUMAN_API_KEY"{
"claim": {
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"membership_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"display_name": "Chris",
"claimed_at": "2026-09-08T12:01:30Z",
"expires_at": "2026-09-08T12:16:30Z"
}
}Release a claim
Releases your claim on a request. Other reviewers then see it as unclaimed. Only the reviewer holding a claim can release it. Other reviewers' claims lapse on their own.
Request
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequired | path · uuid | The request's id. |
Response
Response codes
| Status | Body | Description |
|---|---|---|
204 | The claim is released | |
401 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
403 | ErrorResponse | Another reviewer holds the claim |
404 | ErrorResponse | No live claim on this request |
Example
curl -X DELETE "$WITHHUMAN_URL/api/v1/requests/{id}/claim" \
-H "Authorization: Bearer $WITHHUMAN_API_KEY"Approve or deny a request
Records your decision on a pending request and returns once it is durably stored. The agent waiting on the request sees the decision on its next read.
Every call needs an Idempotency-Key header. Repeating a call with the same key returns the decision already recorded.
Request
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequired | path · uuid | The request's id. |
Idempotency-Keyrequired | header · string | A key of your choosing that identifies this call, so a retry does not act twice. See Idempotency in the API overview. |
Request body
A note for the agent. It is returned with the decision.
Where the decision was made, recorded on the decision, for example web or slack. Defaults to web.
The reviewer's explicit acknowledgement that they are deciding outside the request's routing (break glass). Required, alongside request.decide.unrouted, when routing did not hand them the request; without it such a decision is refused with reason outside_routing_required. Part of the decision's intent under the idempotency key.
Response
Response codes
| Status | Body | Description |
|---|---|---|
200 | DecisionOperation | The recorded decision |
400 | ErrorResponse | The |
401 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
403 | ErrorResponse | You cannot decide this request. Your membership is inactive, you lack permission to decide, the request was routed to other people, or your sign-in is too old or not strong enough. A routing refusal carries RoutingRejectionDetails in error.details, whose reason is not_targeted, break_glass_only, or outside_routing_required. |
404 | ErrorResponse | No such request |
409 | ErrorResponse | The request already has a decision or has expired, or the idempotency key was already used with different parameters |
Response body200
The operation's id. The decision itself has its own.
The request that was decided.
applied once the decision is stored. A 200 response always says applied: the call waits for the outcome, and a rejected decision comes back as an error.
One of pending, applied, rejected
Why the decision was rejected. Set for rejected only.
The rejection in plain text. Set for rejected only.
When the decision was stored.
Example
curl -X POST "$WITHHUMAN_URL/api/v1/requests/{id}/decision" \
-H "Authorization: Bearer $WITHHUMAN_API_KEY" \
-H "Idempotency-Key: 4f1c9a2e-7b3d-4e8f-a1c5-2d6b8e0f9a31" \
-H "Content-Type: application/json" \
-d '{
"status": "approved",
"note": "OK, but flag this account for review.",
"channel": "web",
"outside_routing": true
}'{
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"organization_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"request_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"status": "applied",
"error_code": "string",
"error_message": "string",
"decision": {
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"request_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"organization_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"membership_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"status": "approved",
"note": "OK, but flag this account for review.",
"channel": "web",
"reviewer_display_name": "Chris",
"reviewer_email": "[email protected]",
"authentication": {
"method": "local_password",
"assurance": "strong",
"authenticated_at": "2026-09-08T12:02:11Z",
"session_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"credential_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71"
},
"idempotency_key": "decision-7ab8c8ec",
"decided_at": "2026-09-08T12:02:11Z"
},
"created_at": "2026-09-08T12:02:11Z",
"completed_at": "2026-09-08T12:02:11Z"
}Retrieve a request's routing
Returns who was asked to review a request when it entered human review. If an escalation path took the request, the people on that path were notified, and only they can decide it. If no path applied, every reviewer who can decide was notified, and any of them can decide it. Routing is fixed when the request enters human review. Later changes to pipelines or paths do not move it.
Requests the pipeline decided automatically never entered human review and have no routing.
Request
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequired | path · uuid | The request's id. |
Response
Response codes
| Status | Body | Description |
|---|---|---|
200 | ApprovalRouting | Where the request was routed |
401 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
403 | ErrorResponse | You cannot read requests |
404 | ErrorResponse | No such request, or it never reached human review |
Response body200
escalated when an escalation path took the request. default_queue when no path applied and every reviewer who can decide was asked.
One of escalated, default_queue
How the outcome came about. block_escalation: the pipeline block that asked for a person named the path. pipeline_default: the pipeline's default path took it. no_escalation: the pipeline named no path. path_inactive: the named path had no active revision. evaluation_error: the path could not be resolved. The last three mean no path applied.
One of block_escalation, pipeline_default, no_escalation, path_inactive, evaluation_error
The urgency the request was routed with. Always standard today.
One of standard, interrupt
The path that took the request. Present for escalated only.
The name of the path revision that took the request. Present for escalated only.
The path revision that was active at the time. Present for escalated only.
The pipeline revision that routed the request. Present for escalated only.
The pipeline block that named the path. Present for block_escalation only.
The people and teams the pinned path reaches for this request, in path order: the levels whose request conditions hold for it, plus both branches of any working-hours or urgency test, at every level regardless of timing. Only these people, and added_reviewers, may claim or decide. Empty for default_queue. Empty for escalated means the path reaches nobody for this request and only a break-glass reviewer may decide it.
People added to the request's routing after the snapshot was pinned, oldest first.
The team escalation policy revisions pinned beside the path, one per team the path reaches for this request that had an active policy at routing time. A team absent here is notified all at once when a level reaches it. Empty for default_queue.
The escalation executor's current position. Null before its first tick and for default_queue.
When the request entered human review.
Example
curl -X GET "$WITHHUMAN_URL/api/v1/requests/{id}/routing" \
-H "Authorization: Bearer $WITHHUMAN_API_KEY"{
"outcome": "escalated",
"reason": "block_escalation",
"urgency": "standard",
"escalation_path_key": "oncall",
"escalation_path_name": "On-call engineers",
"escalation_path_revision_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"pipeline_revision_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"block_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"targets": [
{
"type": "user",
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"name": "string"
}
],
"added_reviewers": [
{
"membership_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"display_name": "string",
"added_by_membership_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"added_by_display_name": "string",
"created_at": "2026-09-08T12:02:11Z"
}
],
"team_policies": [
{
"team_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"team_name": "string",
"policy_revision_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"revision": 1
}
],
"escalation": {
"sequence": 1,
"phase": "level",
"urgency": "standard",
"current_node_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"level_ordinal": 1,
"level_count": 1,
"repeat": 1,
"next_escalation_at": "2026-09-08T12:02:11Z",
"updated_at": "2026-09-08T12:02:11Z",
"teams": [
{
"team_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"phase": "level",
"current_node_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"level_ordinal": 1,
"level_count": 1,
"repeat": 1,
"next_escalation_at": "2026-09-08T12:02:11Z"
}
]
},
"created_at": "2026-09-08T12:00:00Z"
}List who a request could be handed to
Active members who hold request.decide and are not yet reviewers of the request. Gated like deciding rather than by membership.read, so a targeted reviewer without the members page can still hand off.
Request
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequired | path · uuid | The request's id. |
Response
Response codes
| Status | Body | Description |
|---|---|---|
200 | object | Candidates sorted by name |
401 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
403 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
404 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
Response body200
Example
curl -X GET "$WITHHUMAN_URL/api/v1/requests/{id}/reviewer-candidates" \
-H "Authorization: Bearer $WITHHUMAN_API_KEY"{
"candidates": [
{
"membership_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"display_name": "string",
"email": "string"
}
]
}Add a reviewer to a pending request
The handoff. Someone the request was routed to (or a holder of request.decide.unrouted) pulls one more active member who may decide into the request's routing. Widening never removes anyone and is audited as request.reviewer_added. Refused when the request is not pending or was never routed (409), when the actor is not targeted (403), or when the member is inactive or cannot decide (400).
Request
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequired | path · uuid | The request's id. |
Request body
Response
Response codes
| Status | Body | Description |
|---|---|---|
200 | ApprovalReview | The request's review after the widening |
400 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
401 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
403 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
404 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
409 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
Response body200
Who was asked to review a request when it entered human review. escalated pins an escalation path revision and the people it reaches for this request; default_queue means any authorized reviewer.
People added to the request's routing after it was pinned, oldest first. The same list the routing carries.
The reading person's own standing on the request. targeted says whether the pinned path reaches them for this request (directly, through a team, or by a later widening). decidable says whether a decision from them would pass the routing rule outright (yes), only with the outside_routing acknowledgement and request.decide.unrouted (break_glass), or not at all (no). reason names the rule in the way; it is absent when decidable is yes or the request is no longer pending. The decision itself still checks membership status, self-approval, and authentication freshness.
Example
curl -X POST "$WITHHUMAN_URL/api/v1/requests/{id}/reviewers" \
-H "Authorization: Bearer $WITHHUMAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"membership_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71"
}'{
"routing": {
"outcome": "escalated",
"reason": "block_escalation",
"urgency": "standard",
"escalation_path_key": "oncall",
"escalation_path_name": "On-call engineers",
"escalation_path_revision_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"pipeline_revision_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"block_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"targets": [
{
"type": "user",
"id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"name": "string"
}
],
"added_reviewers": [
{
"membership_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"display_name": "string",
"added_by_membership_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"added_by_display_name": "string",
"created_at": "2026-09-08T12:02:11Z"
}
],
"team_policies": [
{
"team_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"team_name": "string",
"policy_revision_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"revision": 1
}
],
"escalation": {
"sequence": 1,
"phase": "level",
"urgency": "standard",
"current_node_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"level_ordinal": 1,
"level_count": 1,
"repeat": 1,
"next_escalation_at": "2026-09-08T12:02:11Z",
"updated_at": "2026-09-08T12:02:11Z",
"teams": [
{
"team_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"phase": "level",
"current_node_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"level_ordinal": 1,
"level_count": 1,
"repeat": 1,
"next_escalation_at": "2026-09-08T12:02:11Z"
}
]
},
"created_at": "2026-09-08T12:00:00Z"
},
"added_reviewers": [
{
"membership_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"display_name": "string",
"added_by_membership_id": "7ab8c8ec-7b2d-4fd6-9b52-752f9515eb71",
"added_by_display_name": "string",
"created_at": "2026-09-08T12:02:11Z"
}
],
"viewer": {
"targeted": true,
"decidable": "yes",
"reason": "not_targeted"
}
}Read why a request needs a human and what has happened to it sinceHosted edition
Product read only, gated by request.read alone. The pipeline's conclusion and the block that asked for a human, every judge assessment, the escalation steps, and the claim history, told from the request's own audit events, so a reviewer does not need audit.read to understand why they are being asked. Raw evaluation traces stay in the audit log. Routing, added reviewers, and the reader's standing are the review (GET /api/v1/requests/{id}/review), which every edition serves.
Request
Parameters
| Parameter | Type | Description |
|---|---|---|
idrequired | path · uuid | The request's id. |
Response
Response codes
| Status | Body | Description |
|---|---|---|
200 | RequestTimeline | The request's timeline |
401 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
403 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
404 | ErrorResponse | Error response. A 403 from a permission check carries ForbiddenDetails in error.details. |
Response body200
The completed evaluation as a reviewer reads it. The terminal block is the one whose outcome ended the pipeline; its fields are absent when the pipeline fell through its end or never ran.
What the escalation executor did for the request, oldest first. Empty for a default queue request.
How many audit events the request has in total, for the link into the audit log.
Example
curl -X GET "$WITHHUMAN_URL/api/v1/requests/{id}/timeline" \
-H "Authorization: Bearer $WITHHUMAN_API_KEY"{
"pipeline": {
"outcome": "approve",
"reason_code": "string",
"blocks_evaluated": 1,
"terminal_block_key": "string",
"terminal_block_name": "string",
"terminal_block_type": "always",
"terminal_block_reason": "string",
"endpoint_reason": "string",
"terminal_block_error_code": "string",
"terminal_pipeline": {
"scope": "organization",
"agent_slug": "string",
"revision": 1
},
"completed_at": "2026-09-08T12:02:11Z"
},
"assessments": [
{
"block_key": "string",
"block_name": "string",
"verdict": "approve",
"confidence": "low",
"rationale": "string",
"model_label": "string",
"provider": "string",
"model": "string",
"downgraded_for_confidence": true,
"evaluated_at": "2026-09-08T12:02:11Z"
}
],
"claims": [
{
"kind": "claimed",
"actor_display_name": "string",
"occurred_at": "2026-09-08T12:02:11Z"
}
],
"escalations": [
{
"kind": "level_entered",
"team_id": "string",
"node_id": "string",
"level_ordinal": 1,
"level_count": 1,
"urgency": "standard",
"until": "2026-09-08T12:02:11Z",
"iteration": 1,
"occurred_at": "2026-09-08T12:02:11Z"
}
],
"audit_event_count": 1
}