# Upload a new revision of a stored document (multipart field file) `POST /documents/{id}/version` **Required scope:** `documents:write` Each revision gets its own ledger record chained to the previous one, so a file worked on repeatedly carries a proof per revision. No workspace and no folder: immut does not re-file a revision, it inherits where the first upload put it. ## Parameters | Name | In | Required | Description | |---|---|---|---| | `id` | path | yes | id of the target record | ## Request body Content type: `multipart/form-data` (required) | Field | Type | Required | Description | |---|---|---|---| | `file` | file | **yes** | multipart file field (required). The new revision of the document. | | `agentClassification` | string | no | OPTIONAL, agent keys only. Same JSON blob as POST /documents, describing THESE bytes. A contract moving draft -> executed is the ordinary case, so send the classification you reached for this revision rather than repeating the last one. If you omit it the revision inherits the LATEST revision's classification (not the root's), so a revision is never blank. That inheritance is a floor against an empty record, not permission to skip the field. Include runId or this revision will not appear in GET /agent/runs/{id}. | ## Responses | Status | Meaning | |---|---| | `201` | Created. The new revision, with its own proof and its own timestamp. | | `400` | BadRequest | | `401` | Unauthorized | | `403` | Forbidden | | `429` | RateLimited | ## Example ```bash curl -X POST "https://backend.immut.io/api/v1/documents//version" \ -H "Authorization: Bearer $IMMUT_API_KEY" \ -F "file=@/path/to/file" \ -F "agentClassification=" ``` ## OpenAPI fragment ```json { "/documents/{id}/version": { "post": { "operationId": "postdocumentsidversion", "summary": "Upload a new revision of a stored document (multipart field file). Each revision gets its own ledger record chained to the previous one, so a file worked on repeatedly carries a proof per revision. No workspace and no folder: immut does not re-file a revision, it inherits where the first upload put it.", "description": "Upload a new revision of a stored document (multipart field file). Each revision gets its own ledger record chained to the previous one, so a file worked on repeatedly carries a proof per revision. No workspace and no folder: immut does not re-file a revision, it inherits where the first upload put it.", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "id of the target record" } ], "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "type": "object", "properties": { "file": { "type": "string", "format": "binary", "description": "multipart file field (required). The new revision of the document." }, "agentClassification": { "type": "string", "description": "OPTIONAL, agent keys only. Same JSON blob as POST /documents, describing THESE bytes. A contract moving draft -> executed is the ordinary case, so send the classification you reached for this revision rather than repeating the last one. If you omit it the revision inherits the LATEST revision's classification (not the root's), so a revision is never blank. That inheritance is a floor against an empty record, not permission to skip the field. Include runId or this revision will not appear in GET /agent/runs/{id}." } }, "required": [ "file" ] } } } }, "responses": { "201": { "description": "Created. The new revision, with its own proof and its own timestamp." }, "400": { "$ref": "#/components/responses/BadRequest" }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, "429": { "$ref": "#/components/responses/RateLimited" } }, "tags": [ "Documents" ], "x-required-scope": "documents:write" } } } ```