Skip to main content
A Case is a single piece of work delivered into a Queue for an Agent to pick up. The CLI lets you inspect Case history, re-process Cases in bulk, manage labels, and view the Agents bound to a Queue. For an overview of the Queue system, see Queue.

Cases (duvo cases)

Inspect a Case’s history

Create Cases

Create one Case with --title, or many at once with --from-file (a JSON file holding a single Case object or an array of up to 100). Pass - to --from-file to read the array from stdin.
On a Queue with a Case schema, send a structured payload instead of free-text data. Use --json-data for one Case, or a json_data object per Case in --from-file. The payload is validated against the Queue’s schema, and data and json_data are mutually exclusive — a request is either all free-text or all structured.
A schema-guarded Queue accepts only structured Cases: it needs a Case schema, and you send json_data validated against it — free-text data is rejected. A Queue without the guard accepts free-text data (and also json_data when it has a schema). Either way, you no longer need to turn the schema guard off to add Cases by hand.

Edit a Case

Update a Case’s title and/or its free-form data. Provide at least one field. Titles can be up to 500 characters.
Editing a Case works whether it is pending, in progress, or already settled. Status, priority, and labels have their own commands.

Bulk-reprocess Cases

Re-process 1–100 Cases on a specific Agent in one call.
Any active Runs for these Cases are interrupted.

Set Case priority

Raise or clear the priority of 1–100 Cases so higher-priority work is picked up first among eligible pending Cases. Priority levels are none (the default), medium, and high. Due postponed Cases are still picked up before priority ordering applies.
You can also set a priority when creating a Case, and filter the list by priority:

Filter by issue severity

When a Case evaluation flags failing rubrics, the Case records the highest severity it hit. Filter on it to triage the worst results first:
Severity narrows within evaluated Cases that found issues, so it composes with a status filter but returns nothing alongside a status that excludes them:
Only critical and medium are selectable. A Case whose failing rubrics are all low severity is recorded as a success — low findings still appear in the Case’s rubric breakdown, but they don’t hold the Case back, so no Case carries a low severity to filter on.

Filter by your own pending approvals

When a Case is waiting on approvers, --awaiting-my-approval narrows the list to the Cases holding a decision that is yours to make:
“Mine” is resolved from the credential you are calling with, never from a name you pass — an API key filters as the user who owns it. A credential with no user behind it is rejected rather than returning an empty list. It narrows within Cases that are blocked on a human, so it composes with --status needs_input and returns nothing alongside a settled status:
Only Cases in Queues that use approvals can match, so this returns nothing for a team that does not have Case approvals in use.
Use creation-time bounds to inspect Cases added during a fixed window:
Use update-time bounds to inspect Cases changed during a fixed window:
For both pairs, the lower bound is inclusive and the upper bound is exclusive. Adjacent windows do not count the same Case twice. Add --count-only when you need the matching total without Case rows. All Case filters still apply.
Setting priority never interrupts a Run or changes a Case’s status — it only affects the order pending Cases are picked up in.

Export Cases as CSV

Download a Queue’s Cases as a CSV file for reporting or spreadsheet review. The export respects the same status, issue-severity, approval, priority, and search filters as duvo cases list, plus the --created-at-from and --updated-at-from date bounds. Export applies lower date bounds only — the --created-at-to and --updated-at-to upper bounds are available on duvo cases list, not on export. Order the rows with --sort-by (created_at, updated_at, or postponed_to; default created_at) and --sort-order (asc or desc; default asc). Each row carries the Case’s id, title, status, priority, labels, lifecycle timestamps, and data.
Without --output, the CSV is printed to stdout so you can pipe it into another tool.

Manage Case labels

Attach or remove labels on a Case for filtering and organization.
--label accepts either key=value (for keyed labels like priority=urgent) or just value on its own (for tag-style labels like urgent).

Manage Case files

Work with the files attached to a Case — the invoice, EDI dump, or scan it was computed from.
Upload declares the file’s type from its extension; pass --mime-type for an extension the CLI doesn’t map. Files are capped at 50 MB, with 25 usable slots per Case. --output accepts a file path or an existing directory (the file keeps its own name inside it).

Queues (duvo queues)

duvo queues stats returns counts keyed by Queue ID, including zeros for Queues with no matching Cases. Queue IDs that don’t belong to your team are silently dropped from the result.

Case-level evaluation rubrics

A Queue’s case-level rubrics are the Pass/Fail questions a whole Case — across every Run that touched it — is judged against when an Agent settles it. Duvo generates them from the connected Agents’ AOPs, and you can manage the set the same way as an Agent’s custom rubrics: each rubric is a short title plus a Pass condition, with at most 12 per Queue version.
Add --json to any command for machine-readable output.
Edits target the Queue’s current version’s rubric set — the one new Cases are judged against; already-judged Cases keep their original verdicts. A Queue gets its first rubric set after its first Agent-processed Case settles, so add and replace fail with a conflict before then. Clearing the whole set isn’t supported — an empty set would be regenerated at the next settlement — so replace requires at least one rubric, and remove refuses to drop the last remaining one.

Aggregations

An aggregation turns a typed Queue’s Case data into a small table of numbers instead of a list of Cases. It is a saved, Cube-style query over the fields the Queue declares — measures (count, sum, average, min, max, percentiles), optional groupings and a time bucket, plus filters — whose result is cached and recomputed on a staleness window, so a dashboard reading it stays cheap.
Aggregations run over a Queue whose Cases carry structured data against a declared schema. A Queue of free-text Cases has nothing to aggregate.
Add --json to any command for machine-readable output.
A definition pins the Queue’s schema version when you create it, so its result always reflects the fields declared then; Cases created against an incompatible later schema are excluded and reported separately. Creating, refreshing, and deleting a definition need a Builder role or above — listing, reading a result, and evaluating are open to any team member.

Queue labels (duvo queue-labels)

Queue labels are reusable label definitions on a Queue. Once defined, a label can be attached to any Case in that Queue.

Scripting examples

Relabel a Case if it had runs created today