Skip to content

Run result snapshots

Each time a case completes in a run (case-level mark or per-step mark that leaves the case no longer untested), the API appends a test_results row and companion test_result_step_snapshots rows. Frozen step rows point at that result via snapshot_id.

Use this endpoint to render the read-only attempt panel in clients and integrations.

GET/api/v1/runs/{runUlid}/results/{resultUlid}

Requires viewer+ on the run’s project. Returns 404 when the run or result is outside the caller’s organization.

FieldDescription
resultThe append-only log row (status, executedAt, executedByUlid, executedByApiToken, hasSnapshot, …); see Who executed it
caseSnapshotted case header (titleSnapshot, caseNumber, pre/post conditions, …)
stepsFrozen per-step rows with status, actualResult and actualResultDocument, attachments[], and keyword (the Gherkin keyword, null on a classic step)
resultAttachmentsThe result’s current attachments, each with its stepIndex (null for a result-level file); see Result attachments
parametersThe parameters a CI report sent with the result, [{ name, value }] in the order sent; [] when none
linksThe links a CI report sent with the result, [{ url, name }] in the order sent (name is null when none was sent; url is always an absolute http:/https: URL); [] when none
resultStepsThe steps a CI report sent with the result, flattened to depth-first pre-order: { position, parentPosition, action, status, durationMs, error, expected, data }, where position is the step’s index from 0 and parentPosition its parent’s (null at the top level); [] when none

steps is [] when the case had no steps. parameters, resultSteps and links are returned independently of steps: a result a CI report recorded carries them even when its case has no steps of its own. resultSteps is not steps: steps are the case’s own steps frozen at mark time, resultSteps what the execution reported. Rebuild the tree from parentPosition; a step’s position is the stepIndex its attachments carry.

result.executedByUlid is the member who recorded the result: the signed-in user, or the owner of the personal API token that wrote it. result.executedByApiToken is the API token that wrote it, { ulid, name, app }: app is the CI reporter (junit, playwright, jest, cypress, vitest, cucumber) of an app token and null for a personal API token. It is null for a result recorded in the app, and once the token is deleted. An app token has no user, so a result it reported has executedByUlid: null and names only the token.

Terminal window
curl -sS \
-H "Authorization: Bearer $PROBARA_API_TOKEN" \
"https://app.probara.net/api/v1/runs/$RUN/results/$RESULT"
{
"result": {
"ulid": "01J...",
"runUlid": "01J...",
"caseUlid": "01J...",
"status": "failed",
"durationMs": 120000,
"notes": null,
"executedByUlid": "01J...",
"executedByApiToken": null,
"executedAt": 1700000000000,
"hasSnapshot": true
},
"case": {
"runCaseUlid": "01J...",
"caseNumber": 12,
"titleSnapshot": "Checkout",
"description": null,
"precondition": null,
"postcondition": null,
"priority": "high"
},
"steps": [
{
"ulid": "01J...",
"runCaseStepUlid": "01J...",
"position": 1,
"action": "Pay",
"data": null,
"expected": "Receipt",
"status": "failed",
"actualResult": "HTTP 500",
"attachments": []
}
]
}

GET /api/v1/runs/{runUlid}/results is unchanged except each item now includes hasSnapshot: boolean and executedByApiToken (see Who executed it). History UIs typically filter to hasSnapshot: true for run-wide lists while per-case disclosures may show every row.