Artifacts and uploads API
Durable run artifacts, workpiece read/edit/export, agent-proposed revisions, PDF page operations, and user uploads.
The surfaces that produce, edit, and attach a run’s work. The backend owns the immutable bytes and authorization. All routes are org-session scoped. See Artifacts.
Artifacts
| Method | Path | Description | Notes |
|---|---|---|---|
| GET | /api/artifacts |
List artifacts for the org, optionally filtered. | Query run_id, thread_id. Returns {artifacts}. |
| POST | /api/artifacts |
Create an authored artifact. | Body: run_id (required), thread_id, kind (document/spreadsheet/presentation/pdf), name, upload_id, state. 201 created or 200 existing; 409 on upload-claim conflict. |
| GET | /api/artifacts/:id |
Fetch an artifact descriptor. | {artifact}. 404 not found. |
| GET | /api/artifacts/:id/content |
Stream artifact bytes (range-capable). | Query download=1 forces attachment. Honors Range; 200 or 206, 416 on a bad range, 410 when bytes are unavailable. HEAD is also served (headers only). |
| GET | /api/artifacts/:id/preview |
Rendered-PDF preview of an Office binary, inline. | application/pdf, cache-control: private, max-age=300. 404 no preview, 410 unavailable. |
| GET | /api/artifacts/:id/workpiece |
The workpiece descriptor plus canonical (upgraded) state. | {workpiece, state}. 404 when the artifact is not a workpiece. |
| PATCH | /api/artifacts/:id/workpiece |
Update the workpiece state (optimistic concurrency). | Body: expected_revision (non-negative integer, required), state (parsed for the workpiece kind). 409 revision conflict on a stale revision. |
| GET | /api/artifacts/:id/workpiece/export |
Export the workpiece to a downloadable file. | Query format. 409 invalid stored workpiece state when canonicalization fails. |
| POST | /api/artifacts/:id/workpiece/pdf-pages |
Reorder or delete pages of a published PDF workpiece. | Body: expected_revision, operation ({type:"reorder", order:number[]} or {type:"delete", pages:number[]}). 409 when not a published PDF; 422 on an invalid operation. |
| GET | /api/artifacts/:id/proposals |
List agent-proposed workpiece revisions. | Query status=all returns every status; otherwise pending. {proposals}. |
| POST | /api/artifacts/:id/proposals/:proposalId/accept |
Fold a pending proposal into mainline as a new revision. | {workpiece, state, proposal}. 409 proposal already resolved / revision conflict. |
| POST | /api/artifacts/:id/proposals/:proposalId/dismiss |
Drop a pending proposal, recording the dismissal. | {proposal}. 409 proposal already resolved. |
| GET | /api/artifacts/runs/:runId/archive |
Download every published artifact of a run as one ZIP. | Capped at 100 artifacts / 100 MiB. 404 no artifacts to archive, 413 over the size limit, 410 when bytes are unavailable. |
Uploads
User-selected files are durable before a run exists, then claimed at command
acceptance and materialized into the sandbox. Every route requires an
authenticated user (401 otherwise). Limit: 25 MiB per file.
| Method | Path | Description | Notes |
|---|---|---|---|
| POST | /api/uploads |
Upload a file (multipart), scanned and ingested as a draft. | multipart/form-data field file. 201 {upload}. 413 over 25 MiB, 400 on invalid form/name/empty file, 422 on scan rejection. |
| GET | /api/uploads/:id/content |
Stream an upload’s bytes. | Visible org-wide once claimed by a run; a draft stays private to its uploader and 404s once expired. 410 when bytes are unavailable. |
| DELETE | /api/uploads/:id |
Delete a ready, unclaimed upload you own. | 204 on success, 404 if nothing was removed. |