Step attachment images
Test case steps can include multiple images (PNG, JPEG, or WebP). Images are processed server-side to WebP (full size, longest edge ≤ 2048px, aspect ratio preserved) plus a thumbnail (longest edge ≤ 320px).
Access matches case step editing: any authenticated organization member who can save steps on the case may stage, commit, and delete attachments. This is not restricted to project owners/admins (unlike project avatars).
- Stage —
POST /api/v1/test-cases/{caseUlid}/step-attachments:stagewithmultipart/form-dataand one or morefileparts. The server writes objects understaging/<orgUlid>/and returns staged refs (no database row yet). - Commit — Include those refs on each step in
POST /api/v1/projects/{projectUlid}/test-cases(create) orPUT /api/v1/test-cases/{caseUlid}/steps(replace). The server copies staging → permanent keys, inserts rows, and deletes staged objects. - Read —
GET /api/v1/test-cases/{caseUlid}/steps(and consolidated case GET) returns each step’sattachments[]with permanent keys. Thumbnails are served atGET /__assets/{thumbKey}(same public asset route as avatars).
Abandoned staged objects expire automatically via an R2 lifecycle rule on the staging/ prefix (~48 hours).
Stage (multipart)
Section titled “Stage (multipart)”curl -sS -X POST \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ -F "file=@screenshot-a.png" \ -F "file=@screenshot-b.png" \ "https://probara.net/api/v1/test-cases/01J...CASE/step-attachments:stage"200 example:
{ "attachments": [ { "ulid": "01J...ATT", "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-a.png" } ]}Limits:
- Up to 10
fileparts per request - 10 MiB per file before processing
- Allowed MIME types:
image/png,image/jpeg,image/webp
422 when too many files, disallowed MIME, or invalid image data. 404 when the case is not in the active organization.
Commit on step save
Section titled “Commit on step save”Each step in the replace payload may include attachments:
{ "steps": [ { "ulid": "01J...STEP", "position": 1, "action": "Open settings", "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-a.png" } ] } ]}Reconciliation by attachment ulid:
| Payload | Server action |
|---|---|
New ULID + staging/<this-org>/ keys | Copy to attachments/<orgUlid>/<projectUlid>/steps/<stepUlid>/<attUlid>.webp, insert row, delete staged objects |
| Existing ULID (already stored) | Retain objects; update position only |
| Row exists but ULID omitted | Delete row, delete permanent objects, decrement org storage counter |
The server does not trust client byteSize, width, or height on commit — it re-measures stored R2 objects. Staging keys must match the requesting organization’s prefix; cross-tenant refs are rejected.
POST /api/v1/projects/{projectUlid}/test-cases accepts the same per-step attachments shape on create.
Delete one attachment
Section titled “Delete one attachment”curl -sS -X DELETE \ -H "Authorization: Bearer $PROBARA_API_TOKEN" \ "https://probara.net/api/v1/test-cases/01J...CASE/step-attachments/01J...ATT"204 on success. 404 when the attachment or case is unknown.
Storage accounting
Section titled “Storage accounting”Committed attachment bytes (full + thumbnail) increment organization_storage_usage for category step_attachment. Staging bytes are not counted. Quota enforcement is not implemented yet; the counter exists for future tiers.
Related
Section titled “Related”- API reference overview — pagination, errors, consolidated PATCH
- Interactive v1 reference — full schemas