|
2744 | 2744 | "put": { |
2745 | 2745 | "operationId": "updateFileContent", |
2746 | 2746 | "summary": "Replace File Content", |
2747 | | - "description": "Replace the complete contents of an existing file from UTF-8 or base64 input.\n\nOAuth scope: `api:write`.", |
| 2747 | + "description": "Replace the complete contents of an existing file from UTF-8 or base64 input. A stale `expectedRevision`, or a write that raced this one, returns `409`; re-read before retrying.\n\nOAuth scope: `api:write`.", |
2748 | 2748 | "x-sim-operation": "files.update_content", |
2749 | 2749 | "x-oauth-scope": "api:write", |
2750 | 2750 | "tags": ["Files"], |
|
2791 | 2791 | "content": { |
2792 | 2792 | "application/json": { |
2793 | 2793 | "schema": { |
2794 | | - "$ref": "#/components/schemas/V2FileResponse" |
| 2794 | + "$ref": "#/components/schemas/V2WrittenFileResponse" |
2795 | 2795 | } |
2796 | 2796 | } |
2797 | 2797 | } |
|
2808 | 2808 | "404": { |
2809 | 2809 | "$ref": "#/components/responses/NotFound" |
2810 | 2810 | }, |
| 2811 | + "409": { |
| 2812 | + "$ref": "#/components/responses/Conflict" |
| 2813 | + }, |
2811 | 2814 | "413": { |
2812 | 2815 | "$ref": "#/components/responses/PayloadTooLarge" |
2813 | 2816 | }, |
|
4988 | 4991 | "description": "Workspace that owns the file." |
4989 | 4992 | }, |
4990 | 4993 | "expectedCurrentVersion": { |
4991 | | - "description": "Revert only while this is still the current version; otherwise the request fails with `409`. Omit to revert whatever is current. Collaborative edits and repeated workflow writes that fold into the current version keep its number.", |
| 4994 | + "description": "Revert only while this is still the current version; otherwise the request fails with `409`. Omit to revert whatever is current. Collaborative edits and repeated workflow writes that fold into the current version keep its number, so prefer `expectedRevision` to guard content.", |
4992 | 4995 | "type": "integer", |
4993 | 4996 | "minimum": 1, |
4994 | 4997 | "maximum": 2147483647 |
| 4998 | + }, |
| 4999 | + "expectedRevision": { |
| 5000 | + "description": "Revert only while the file still holds the content this revision names, as returned by Get File Metadata or an earlier write; otherwise the request fails with `409`. Unlike a version number, it also catches edits that folded into the current version.", |
| 5001 | + "type": "string", |
| 5002 | + "minLength": 1 |
4995 | 5003 | } |
4996 | 5004 | }, |
4997 | 5005 | "required": ["workspaceId"], |
|
5315 | 5323 | ], |
5316 | 5324 | "description": "Current public-share state, or null when the file has never been shared." |
5317 | 5325 | }, |
| 5326 | + "revision": { |
| 5327 | + "description": "Opaque token for the file's current content. Send it back as `expectedRevision` so a write or revert is refused when the content moved on. Absent for a file with no recorded content version.", |
| 5328 | + "type": "string" |
| 5329 | + }, |
5318 | 5330 | "currentVersion": { |
5319 | 5331 | "type": "integer", |
5320 | 5332 | "minimum": 1, |
|
5368 | 5380 | "updatedAt": "2026-01-15T10:30:00Z", |
5369 | 5381 | "deletedAt": null, |
5370 | 5382 | "share": null, |
5371 | | - "currentVersion": 1 |
| 5383 | + "currentVersion": 1, |
| 5384 | + "revision": "d2ZfVjFTdEdYUjh6NWpkSGk2Qm15VDkxOjIwMjYtMDEtMTVUMTA6MzA6MDAuMDAwWg" |
5372 | 5385 | } |
5373 | 5386 | }, |
5374 | 5387 | { |
|
5382 | 5395 | "folderPath": "/Engineering", |
5383 | 5396 | "uploadedByEmail": "jane@example.com", |
5384 | 5397 | "uploadedAt": "2026-01-15T10:30:00Z", |
5385 | | - "updatedAt": "2026-01-15T10:30:00Z", |
| 5398 | + "updatedAt": "2026-01-16T09:12:00Z", |
5386 | 5399 | "deletedAt": null, |
5387 | 5400 | "share": { |
5388 | 5401 | "id": "shr_8Hf3kL9wQ2mNpXr6Tz1Vb", |
|
5395 | 5408 | "hasPassword": false, |
5396 | 5409 | "allowedEmails": [] |
5397 | 5410 | }, |
5398 | | - "currentVersion": 3 |
| 5411 | + "currentVersion": 3, |
| 5412 | + "revision": "d2ZfVjFTdEdYUjh6NWpkSGk2Qm15VDkxOjIwMjYtMDEtMTZUMDk6MTI6MDAuMDAwWg" |
5399 | 5413 | } |
5400 | 5414 | } |
5401 | 5415 | ] |
|
5799 | 5813 | "minimum": 0, |
5800 | 5814 | "maximum": 9007199254740991, |
5801 | 5815 | "description": "Lines the file holds after the edit." |
| 5816 | + }, |
| 5817 | + "revision": { |
| 5818 | + "description": "Opaque token for the content this write produced. Send it back as `expectedRevision` on the next write. Absent for a file with no recorded content version.", |
| 5819 | + "type": "string" |
5802 | 5820 | } |
5803 | 5821 | }, |
5804 | 5822 | "required": ["file", "lineCount"], |
|
5965 | 5983 | } |
5966 | 5984 | ], |
5967 | 5985 | "description": "One exact or anchor-based edit: search_replace, replace_between, insert_after, or delete_between." |
| 5986 | + }, |
| 5987 | + "expectedRevision": { |
| 5988 | + "description": "Revision from Get File Metadata or an earlier write; the request is refused with `409` when the content moved on.", |
| 5989 | + "type": "string", |
| 5990 | + "minLength": 1 |
5968 | 5991 | } |
5969 | 5992 | }, |
5970 | 5993 | "required": ["workspaceId", "edit"], |
|
6121 | 6144 | } |
6122 | 6145 | ] |
6123 | 6146 | }, |
| 6147 | + "V2WrittenFile": { |
| 6148 | + "type": "object", |
| 6149 | + "properties": { |
| 6150 | + "id": { |
| 6151 | + "type": "string", |
| 6152 | + "description": "Unique file identifier.", |
| 6153 | + "examples": ["wf_V1StGXR8z5jdHi6BmyT91"] |
| 6154 | + }, |
| 6155 | + "webUrl": { |
| 6156 | + "type": "string", |
| 6157 | + "format": "uri", |
| 6158 | + "description": "Canonical absolute URL for opening this resource in the Sim web application." |
| 6159 | + }, |
| 6160 | + "name": { |
| 6161 | + "type": "string", |
| 6162 | + "description": "Original file name.", |
| 6163 | + "examples": ["data.csv"] |
| 6164 | + }, |
| 6165 | + "size": { |
| 6166 | + "type": "number", |
| 6167 | + "minimum": 0, |
| 6168 | + "description": "Size in bytes of the stored file. For a generated document (docx, pptx, pdf, xlsx) this is the generation source, not the rendered document, so it does not predict how many bytes downloading the file returns.", |
| 6169 | + "examples": [1024] |
| 6170 | + }, |
| 6171 | + "type": { |
| 6172 | + "type": "string", |
| 6173 | + "description": "MIME type of the stored file. For a generated document (docx, pptx, pdf, xlsx) this is the generation source type, not the rendered document type a download serves.", |
| 6174 | + "examples": ["text/csv"] |
| 6175 | + }, |
| 6176 | + "key": { |
| 6177 | + "type": "string", |
| 6178 | + "description": "Storage key for the file.", |
| 6179 | + "examples": ["workspace/example/data.csv"] |
| 6180 | + }, |
| 6181 | + "folderPath": { |
| 6182 | + "type": "string", |
| 6183 | + "title": "Folder path", |
| 6184 | + "description": "Canonical containing-folder path. `/` is the workspace root.", |
| 6185 | + "maxLength": 4096 |
| 6186 | + }, |
| 6187 | + "uploadedByEmail": { |
| 6188 | + "type": "string", |
| 6189 | + "format": "email", |
| 6190 | + "pattern": "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$", |
| 6191 | + "description": "Current email address of the uploader.", |
| 6192 | + "examples": ["jane@example.com"] |
| 6193 | + }, |
| 6194 | + "uploadedAt": { |
| 6195 | + "type": "string", |
| 6196 | + "description": "ISO 8601 timestamp when the file was uploaded.", |
| 6197 | + "format": "date-time", |
| 6198 | + "examples": ["2026-01-15T10:30:00Z"] |
| 6199 | + }, |
| 6200 | + "updatedAt": { |
| 6201 | + "type": "string", |
| 6202 | + "description": "ISO 8601 timestamp of the last content or metadata write.", |
| 6203 | + "format": "date-time", |
| 6204 | + "examples": ["2026-01-15T10:30:00Z"] |
| 6205 | + }, |
| 6206 | + "deletedAt": { |
| 6207 | + "anyOf": [ |
| 6208 | + { |
| 6209 | + "type": "string" |
| 6210 | + }, |
| 6211 | + { |
| 6212 | + "type": "null" |
| 6213 | + } |
| 6214 | + ], |
| 6215 | + "description": "ISO 8601 timestamp when the file was archived by deleting it, or null while the file is active. Only an archived-scope file list returns files with a non-null value.", |
| 6216 | + "format": "date-time", |
| 6217 | + "examples": ["2026-01-16T09:00:00Z"] |
| 6218 | + }, |
| 6219 | + "revision": { |
| 6220 | + "description": "Opaque token for the content this write produced. Send it back as `expectedRevision` on the next write. Absent for a file with no recorded content version.", |
| 6221 | + "type": "string" |
| 6222 | + } |
| 6223 | + }, |
| 6224 | + "required": [ |
| 6225 | + "id", |
| 6226 | + "webUrl", |
| 6227 | + "name", |
| 6228 | + "size", |
| 6229 | + "type", |
| 6230 | + "key", |
| 6231 | + "folderPath", |
| 6232 | + "uploadedByEmail", |
| 6233 | + "uploadedAt", |
| 6234 | + "updatedAt", |
| 6235 | + "deletedAt" |
| 6236 | + ], |
| 6237 | + "additionalProperties": false, |
| 6238 | + "title": "Written file", |
| 6239 | + "description": "A workspace file after a content replacement, with the revision it produced." |
| 6240 | + }, |
| 6241 | + "V2WrittenFileResponse": { |
| 6242 | + "type": "object", |
| 6243 | + "properties": { |
| 6244 | + "data": { |
| 6245 | + "description": "Response data.", |
| 6246 | + "$ref": "#/components/schemas/V2WrittenFile" |
| 6247 | + } |
| 6248 | + }, |
| 6249 | + "required": ["data"], |
| 6250 | + "additionalProperties": false, |
| 6251 | + "title": "Written file response", |
| 6252 | + "description": "A workspace file after a content replacement, with the revision the write produced.", |
| 6253 | + "examples": [ |
| 6254 | + { |
| 6255 | + "data": { |
| 6256 | + "id": "wf_V1StGXR8z5jdHi6BmyT91", |
| 6257 | + "webUrl": "https://www.sim.ai/workspace/a91c4b2e-6d3f-4e8a-b5c7-0d9e2f1a8c64/files/wf_V1StGXR8z5jdHi6BmyT91", |
| 6258 | + "name": "data.csv", |
| 6259 | + "size": 1024, |
| 6260 | + "type": "text/csv", |
| 6261 | + "key": "workspace/example/data.csv", |
| 6262 | + "folderPath": "/Engineering", |
| 6263 | + "uploadedByEmail": "jane@example.com", |
| 6264 | + "uploadedAt": "2026-01-15T10:30:00Z", |
| 6265 | + "updatedAt": "2026-01-15T10:30:00Z", |
| 6266 | + "deletedAt": null, |
| 6267 | + "revision": "d2ZfVjFTdEdYUjh6NWpkSGk2Qm15VDkxOjIwMjYtMDEtMTVUMTA6MzA6MDAuMDAwWg" |
| 6268 | + } |
| 6269 | + } |
| 6270 | + ] |
| 6271 | + }, |
6124 | 6272 | "UpdateFileContentRequest": { |
6125 | 6273 | "type": "object", |
6126 | 6274 | "properties": { |
|
6140 | 6288 | "description": "Encoding of the content field.", |
6141 | 6289 | "type": "string", |
6142 | 6290 | "enum": ["utf-8", "base64"] |
| 6291 | + }, |
| 6292 | + "expectedRevision": { |
| 6293 | + "description": "Revision from Get File Metadata or an earlier write; the request is refused with `409` when the content moved on.", |
| 6294 | + "type": "string", |
| 6295 | + "minLength": 1 |
6143 | 6296 | } |
6144 | 6297 | }, |
6145 | 6298 | "required": ["workspaceId", "content"], |
|
0 commit comments