Run cases API
GET /api/v1/runs/{runUlid}/cases returns every case that belongs to an open
or closed test run. Two fields were added as additive, backward-compatible
extensions — existing integrations that ignore unknown keys are unaffected.
List cases in a run
Section titled “List cases in a run”GET /api/v1/runs/{runUlid}/casesRequires viewer+ on the run’s project. Returns 404 when the run is
outside the caller’s organization.
Response shape (per item)
Section titled “Response shape (per item)”Each item in the cases array includes the usual run-case fields plus:
| Field | Type | Description |
|---|---|---|
caseLifecycleStatus | object | null | The source case’s current (live, not snapshotted) lifecycle status. null when the status field is unset or the source case has been deleted. |
customFieldValues[].optionSystemKey | string | null | The option’s own system key (e.g. status_active, status_draft). null for custom (user-defined) options and for non-select field types. |
caseLifecycleStatus object
Section titled “caseLifecycleStatus object”When non-null, the object has the same shape as a CustomFieldValueEntry:
| Field | Type | Description |
|---|---|---|
optionUlid | string | ULID of the selected lifecycle option |
optionName | string | Display name of the option |
optionColor | string | null | Hex color, if any |
optionIcon | string | null | Icon identifier, if any |
optionSystemKey | string | null | System key — status_active, status_draft, status_deprecated, or null for custom options |
Live vs. snapshot
Section titled “Live vs. snapshot”Test case content (title, steps, description) is snapshotted when the
case is added to a run — edits to the source case do not affect any existing
run. caseLifecycleStatus is deliberately not snapshotted: it is resolved
live at query time via a join to the source case, so it always reflects the
case’s current status in the repository. If you need the snapshotted state,
use the priority field (which is part of the snapshot).
Example
Section titled “Example”curl -sS \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ "https://probara.net/api/v1/runs/01J...RUN/cases"{ "cases": [ { "runCaseUlid": "01J...RC", "caseUlid": "01J...CASE", "caseNumber": 7, "titleSnapshot": "Checkout flow", "status": "untested", "caseLifecycleStatus": { "optionUlid": "01J...OPT", "optionName": "Draft", "optionColor": "#F59E0B", "optionIcon": "circle-dashed", "optionSystemKey": "status_draft" }, "customFieldValues": [ { "fieldUlid": "01J...FLD", "fieldName": "Priority", "optionUlid": "01J...PRI", "optionName": "High", "optionColor": "#EF4444", "optionIcon": null, "optionSystemKey": null } ] } ]}When the source case has no lifecycle status set, or the case was deleted:
{ "caseLifecycleStatus": null}When a customFieldValues entry belongs to a system option (lifecycle status
field):
{ "optionSystemKey": "status_active"}When it belongs to a custom option (user-defined):
{ "optionSystemKey": null}Reconcile a run’s case selection
Section titled “Reconcile a run’s case selection”PATCH /api/v1/runs/{runUlid}/casesReconciles a run’s case selection to a supplied desired full
selection, in a single atomic transaction. Unlike POST /runs/{runUlid}/cases
(add-only — appends the given case ULIDs and never removes anything), this
endpoint treats absence from the desired set as a removal. Both endpoints
remain available and unchanged relative to each other.
Requires member+ (the same execute gate as running the tests); viewer
receives 403. Allowed on an open run or a closed, non-aborted run
(completed, or auto-closed once every case had a result); rejects only an
aborted run with 409, mutating nothing.
Request body
Section titled “Request body”{ "caseUlids": ["01J...A", "01J...B", "01J...D"], "caseAssignees": [{ "caseUlid": "01J...D", "assigneeUlid": "01J...USER" }]}| Field | Type | Description |
|---|---|---|
caseUlids | string[] | The full desired selection (source case ULIDs). An empty array is valid — it removes every case from the run. |
caseAssignees | array (optional) | Per-case assignee for the desired selection. A case ULID absent from this array means that case is (or becomes) unassigned — there is no explicit “clear” value. |
Given the current selection and the request above, the server diffs and applies, atomically:
- Adds each case in
caseUlidsnot currently on the run — snapshotting its title and steps fresh,status: "untested", with the supplied assignee (if any) applied inline. - Removes each current case absent from
caseUlids— cascading its step snapshots and result attachments, same as the single-caseDELETE /runs/{runUlid}/cases/{runCaseUlid}endpoint. - Retains each case present in both, unchanged (
titleSnapshot,status,assigneeUlid,elapsedMs). - Reassigns any retained case whose supplied assignee differs from its current one.
The response is the reconciled run summary (RunResponse), the same shape every other run mutation returns — it does not include the run-cases array; call GET /runs/{runUlid}/cases for the refreshed list.
Assignee validation
Section titled “Assignee validation”Each supplied assigneeUlid must resolve to a member of the run’s
organization. A cross-tenant or unknown assignee ULID returns 404 not_found — matching the existing create (POST /projects/{projectId}/runs)
and per-case patch (PATCH /runs/{runUlid}/cases/{runCaseUlid}) behavior for
the same field, not a 422 validation_failed. No case is added, removed, or
reassigned when this happens.
Audit events
Section titled “Audit events”Emits exactly one event per case that actually changed: run.case_added for
each added case, run.case_removed for each removed case, run.case_assigned
for each case whose assignee changed (including a clear, to: null) — see
Audit events API for the shared metadata
shapes. A case unchanged in both membership and assignee emits nothing. A
newly added case’s inline assignee is carried on run.case_added and does
not additionally emit run.case_assigned.
Example
Section titled “Example”curl -sS -X PATCH \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"caseUlids": ["01J...A", "01J...D"]}' \ "https://probara.net/api/v1/runs/01J...RUN/cases"Related
Section titled “Related”- API reference overview — pagination, errors, authentication
- Interactive v1 reference — full schemas
- Test case search API — cross-suite search including
customFieldValues