Run result attachments
While executing a test run, a member can record an actual result per step (free text) plus optional image attachments (PNG, JPEG, or WebP). The flow mirrors step attachments: images are processed server-side to WebP (full size, longest edge ≤ 2048px, aspect ratio preserved) plus a thumbnail (longest edge ≤ 320px), then staged-and-committed.
Access requires member+ on an open run. All write operations (stage, commit, delete) are rejected with 409 on a closed run; reads are still allowed (the panel is read-only).
- Stage —
POST /api/v1/runs/{runUlid}/cases/{runCaseUlid}/steps/{stepUlid}/result-attachments:stagewithmultipart/form-dataand one or morefileparts. Writes tostaging/<orgUlid>/and returns staged refs (no DB row yet). - Commit —
PATCH /api/v1/runs/{runUlid}/cases/{runCaseUlid}/steps/{stepUlid}/resultwithactualResulttext and the staged refs inattachments[]. The server copies staged → permanent keys (attachments/<orgUlid>/<projectUlid>/run-steps/<runCaseStepUlid>/<attUlid>.webp), inserts rows, deletes staged objects, and persists the text. - Read —
GET /api/v1/runs/{runUlid}/cases/{runCaseUlid}returns each step’sactualResultandattachments[](ordered byposition). Thumbnails are served atGET /__assets/{thumbKey}.
Abandoned staged objects expire automatically via the R2 lifecycle rule (~48 h).
Stage (multipart)
Section titled “Stage (multipart)”curl -sS -X POST \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ -F "file=@screenshot.png" \ "https://probara.net/api/v1/runs/$RUN/cases/$RC/steps/$ST/result-attachments:stage"200 response shape is identical to step attachments (StagedRunResultAttachmentRef).
Commit (PATCH result)
Section titled “Commit (PATCH result)”{ "actualResult": "Saw HTTP 500 instead of the dashboard", "attachments": [ { "ulid": "01J...ATT", "position": 0, "objectKey": "staging/01J...ORG/01J...UPLOAD.webp", "thumbKey": "staging/01J...ORG/01J...UPLOAD_thumb.webp", "mime": "image/webp", "byteSize": 8420, "width": 1200, "height": 800, "originalFilename": "screenshot.png" } ]}Reconciliation works exactly like step attachments — new ulids are promoted, existing ulids are retained (only position may update), and any committed ulid omitted from the payload is deleted (rows + permanent R2 + storage counter).
The server does not trust client byteSize, width, or height on commit — it re-measures stored R2 objects. Staged refs whose key prefix does not match the requesting organization are rejected (cross-tenant guard).
actualResult: null clears the text; omitting it leaves the existing value unchanged. Omitting attachments leaves the committed set untouched.
Delete one attachment
Section titled “Delete one attachment”curl -sS -X DELETE \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ "https://probara.net/api/v1/runs/$RUN/cases/$RC/steps/$ST/result-attachments/$ATT"204 on success. 404 when the attachment is unknown or cross-org. 409 when the run is closed.
Run-case operations
Section titled “Run-case operations”The redesigned execution board also adds two case-level operations:
POST /api/v1/runs/{runUlid}/cases/{runCaseUlid}/retry— resets the case (and its frozen step snapshots) tountestedand recomputes the run aggregate. Emitsrun.case_retried.DELETE /api/v1/runs/{runUlid}/cases/{runCaseUlid}— removes the case (cascades steps + result attachments) and recomputes the run aggregate. Emitsrun.case_removed.
Both require member+ on an open run and respond 409 when the run is closed.
Storage accounting
Section titled “Storage accounting”Committed run-result attachment bytes (full + thumbnail) increment organization_storage_usage for category run_result_attachment. Staging bytes are not counted. The counter is the basis for future pricing tiers.
Related
Section titled “Related”- Step attachments — case-authoring counterpart
- Interactive v1 reference — full schemas