Decisions
All paths below are relative to the base URL https://api.agentdepot.org — for example
GET https://api.agentdepot.org/api/orgs/{org_id}/agents/{agent_id}/decisions. Authenticate with an
Authorization: Bearer <token> header. See the
REST API reference for details.
GET /api/orgs/{org_id}/agents/{agent_id}/decisions
Section titled “GET /api/orgs/{org_id}/agents/{agent_id}/decisions”List Agent Decisions
Every decision this agent recorded, across all its chats, newest first.
agent_id accepts the id or the slug, like the other agent routes.
The per-agent view of the same rows the chat’s Decisions tab shows. Newest first because an agent’s history is a feed — what has it been deciding lately — where a single chat is read forwards as a sequence.
Only decisions from chats the caller can open are listed (a private chat’s decisions quote its content). Served whatever the decision log setting says: switching the feature off never hides decisions already recorded.
Filters: review_status (unreviewed | agreed | disputed |
reverted), kind (act | no_act | escalate), and the two
flags deviation / determination. Unknown values are refused rather
than silently matching nothing. The flag pair is FILTER-ONLY and
one-directional: off (the default) applies no filter at all, on narrows to
rows carrying that flag. There is deliberately no “exclude flagged rows”
mode — a deviation is the one a reviewer must not miss, so the UI promotes
it rather than making you filter toward it.
archived (default false) selects which of two disjoint pages this
is: the live queue (excludes archived rows) or the Archived tab (archived
rows only). There is no combined view — see POST .../decisions/archive.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| agent_id | path | string | yes | |
| archived | query | boolean | no | |
| determination | query | boolean | no | |
| deviation | query | boolean | no | |
| kind | query | string | no | |
| limit | query | integer | no | Max rows to return (1-100). Omit to return every row. |
| offset | query | integer | no | Rows to skip — pass the previous response’s next_offset. |
| org_id | path | string (uuid) | yes | |
| review_status | query | string | no |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | AgentDecisionPage |
| 422 | Validation Error | HTTPValidationError |
POST /api/orgs/{org_id}/agents/{agent_id}/decisions/archive
Section titled “POST /api/orgs/{org_id}/agents/{agent_id}/decisions/archive”Archive Decisions
Archive one or many decisions WITHOUT recording a verdict.
Clears them from the Unreviewed queue for the case a verdict cannot
honestly describe — hundreds of routine, unremarkable decisions nobody is
going to individually agree or dispute. Orthogonal to review: an archived
decision keeps whatever review_status it already had.
Body is either {"decision_ids": [...]} (at most
MAX_BULK_DECISION_IDS) or {"filter": {...}} — exactly one, else
422. A filter with every field omitted archives every currently
non-archived decision the caller can see (e.g. “archive everything”);
{"filter": {"review_status": "unreviewed"}} archives only the
unreviewed backlog.
Same authz and scoping as the rest of this page: any org member, and only
rows reachable through a chat the caller could open (private chats
excepted). Archiving an already-archived row is a no-op for it — a repeat
“archive all unreviewed” sweep does not reset archived_at.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| agent_id | path | string | yes | |
| org_id | path | string (uuid) | yes |
Request body (required)
| Field | Type | Required | Description |
|---|---|---|---|
| decision_ids | string (uuid)[] | no | |
| filter | DecisionBulkFilter | no |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | DecisionBulkUpdateResponse |
| 422 | Validation Error | HTTPValidationError |
GET /api/orgs/{org_id}/agents/{agent_id}/decisions/groups
Section titled “GET /api/orgs/{org_id}/agents/{agent_id}/decisions/groups”List Agent Decision Groups
This agent’s decisions grouped by the exact basis they cite,
largest group first — “what rule keeps showing up” — so a reviewer can
archive or agree with a whole group instead of triaging it row by row.
Same visibility, retention and filter vocabulary as
GET /{agent_id}/decisions (review_status, kind, the
deviation / determination flags, archived — all optional,
archived defaulting to false to match that endpoint’s default
view). Paginated the same way; total counts matching GROUPS, not
decisions.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| agent_id | path | string | yes | |
| archived | query | boolean | no | |
| determination | query | boolean | no | |
| deviation | query | boolean | no | |
| kind | query | string | no | |
| limit | query | integer | no | Max rows to return (1-100). Omit to return every row. |
| offset | query | integer | no | Rows to skip — pass the previous response’s next_offset. |
| org_id | path | string (uuid) | yes | |
| review_status | query | string | no |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | Page_DecisionGroupItem_ |
| 422 | Validation Error | HTTPValidationError |
POST /api/orgs/{org_id}/agents/{agent_id}/decisions/review
Section titled “POST /api/orgs/{org_id}/agents/{agent_id}/decisions/review”Bulk Review Decisions
Bulk-apply the agreed verdict — the review-side twin of archive,
for the decisions a reviewer wants to affirmatively wave through in bulk
rather than one at a time.
Same body shape as archive, plus a top-level review_status that
must be "agreed". Only currently UNREVIEWED, non-archived rows are
ever touched — an existing verdict from a prior single or bulk review is
never overwritten, so filter.review_status, if given, must be
"unreviewed" (or omitted; both mean the same thing here).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| agent_id | path | string | yes | |
| org_id | path | string (uuid) | yes |
Request body (required)
| Field | Type | Required | Description |
|---|---|---|---|
| decision_ids | string (uuid)[] | no | |
| filter | DecisionBulkFilter | no | |
| review_status | string | yes |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | DecisionBulkUpdateResponse |
| 422 | Validation Error | HTTPValidationError |
POST /api/orgs/{org_id}/agents/{agent_id}/decisions/unarchive
Section titled “POST /api/orgs/{org_id}/agents/{agent_id}/decisions/unarchive”Unarchive Decisions
The inverse of archive — brings decisions back onto the pages they
would otherwise appear on (the Unreviewed queue, or wherever their
review_status already put them). Same body shape, same scoping.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| agent_id | path | string | yes | |
| org_id | path | string (uuid) | yes |
Request body (required)
| Field | Type | Required | Description |
|---|---|---|---|
| decision_ids | string (uuid)[] | no | |
| filter | DecisionBulkFilter | no |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | DecisionBulkUpdateResponse |
| 422 | Validation Error | HTTPValidationError |
GET /api/orgs/{org_id}/chats/{chat_id}/decisions
Section titled “GET /api/orgs/{org_id}/chats/{chat_id}/decisions”List Chat Decisions
Every decision recorded in this chat, oldest first.
Oldest first because a reviewer reads a run forwards: the order the decisions were taken in is the order they make sense in.
Served whatever the org switch says — see the module docstring.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| chat_id | path | string (uuid) | yes | |
| limit | query | integer | no | |
| org_id | path | string (uuid) | yes |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | DecisionListResponse |
| 422 | Validation Error | HTTPValidationError |
POST /api/orgs/{org_id}/chats/{chat_id}/decisions/{decision_id}/review
Section titled “POST /api/orgs/{org_id}/chats/{chat_id}/decisions/{decision_id}/review”Review Decision
Record a human’s verdict on one decision.
agreed marks the row and nothing else happens in v1 — there is no
fingerprint learning yet, and pretending otherwise would be the more
expensive lie.
disputed stores should_have, which is what an instruction-revision
draft is written from. The draft itself is a separate step so a reviewer can
disagree without immediately being asked to author a rule.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| chat_id | path | string (uuid) | yes | |
| decision_id | path | string (uuid) | yes | |
| org_id | path | string (uuid) | yes |
Request body (required)
| Field | Type | Required | Description |
|---|---|---|---|
| review_note | string | no | |
| review_status | string | yes | |
| should_have | string | no |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | DecisionResponse |
| 422 | Validation Error | HTTPValidationError |
POST /api/orgs/{org_id}/chats/{chat_id}/decisions/{decision_id}/revision-draft
Section titled “POST /api/orgs/{org_id}/chats/{chat_id}/decisions/{decision_id}/revision-draft”Draft Revision From Decision
Append this disagreement to the agent’s instruction DRAFT.
This is the far end of the review loop, and the reason basis exists: a
disagreement lands on a known sentence instead of a vibe.
A draft, never a deploy. Instruction changes are proposals a human
publishes — the same rule update_own_instruction follows — so this writes
into the existing draft (creating one from the active revision if there is
none) and leaves publishing to the agent’s own screen.
Requires the decision to be disputed with a should_have: without the
alternative there is nothing to write, which is why the review endpoint
insists on it.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
| chat_id | path | string (uuid) | yes | |
| decision_id | path | string (uuid) | yes | |
| org_id | path | string (uuid) | yes |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | Successful Response | RevisionDraftResponse |
| 422 | Validation Error | HTTPValidationError |