Api / Artifacts

POST/v1/conversations/:id/artifacts

Auth: tenant — Status: stable

Create or update an artifact in a conversation's working directory. Path validation, three-tier quotas, and PUT-on-conflict semantics all run here. See Artifacts for the full storage and safety model.

Same path validator as the agent's /write --persist slash command; HTTP and agent paths can't disagree on what's allowed.

Request

Path paramTypeDescription
idintConversation id (must belong to caller's tenant).

Body

FieldTypeRequiredDescription
pathstringyesWill be sanitized — caller may pass user-supplied paths. See Artifacts → Path safety for rules.
contentstringyesUTF-8 string. Binary content should be base64-encoded by the caller.
mime_typestringnoDefaults to application/octet-stream. Free-form; not sniffed.
curl -X POST \
  -H "Authorization: Bearer atr_…" \
  -H "Content-Type: application/json" \
  -d '{"path":"output/report.md","content":"# Report\n...","mime_type":"text/markdown"}' \
  http://arbiter.example.com/v1/conversations/7/artifacts

Response

201 Created — fresh insert

200 OK — overwrite (PUT-on-conflict)

{
  "artifact": {
    "id": 12,
    "tenant_id": 1,
    "conversation_id": 7,
    "path": "output/report.md",
    "sha256": "ad14a...e3",
    "mime_type": "text/markdown",
    "size": 1832,
    "created_at": 1777060001,
    "updated_at": 1777060123
  },
  "tenant_used_bytes": 4231,
  "conversation_used_bytes": 1832,
  "created": false
}

tenant_used_bytes and conversation_used_bytes are post-write totals — clients can show a "you have used X of Y" hint.

PUT-on-conflict math: overwriting a 100 KB file with 200 KB only costs 100 KB against the conversation quota (the existing size is subtracted before the cap check).

Failure modes

StatusWhenBody
400Invalid JSON; path fails sanitiser (rules).{"error": "invalid path: <reason>"}
401Missing / invalid bearer.{"error": "..."}
404Conversation not found / wrong tenant.{"error": "conversation not found"}
409Race: path collision detected mid-INSERT (concurrent writer). Caller should retry as PUT.{"error": "path collision (concurrent write); retry"}
413Quota exceeded (per-file 1 MB / per-conversation 50 MB / per-tenant 500 MB). The body identifies which scope.{"error": "<scope> quota exhausted: ... > ... bytes"}

See also