لوكلاء AI: ملف markdown لهذه الصفحة — /docs-content-en/entities/files/version-upload.md فهرس التوثيق — /llms.txt
مقالات التوثيق متاحة حاليًا باللغة الإنجليزية فقط.
Upload a new file version
POST /v1/files/:id/versions
Replaces the content of a file on Bitrix24 Drive and saves it in the version history. The new content is passed as Base64 in the JSON request body, and the file name does not change.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
Parameterid (path) |
Typenumber | Requiredyes | DescriptionFile ID. Get it: GET /v1/files?folderId=X |
Request fields (body)
| Field | Type | Required | Description |
|---|---|---|---|
Fieldcontent |
Typestring | Requiredyes | DescriptionNew file content in Base64: the standard alphabet, = padding at the end, no spaces or line breaks. An empty string is not accepted. The whole request body is limited to 70 MiB: Base64 inflates data by a third, so one request fits a file of about 50 MiB |
FieldexpectedContentGeneration |
Typenumber | Requiredno | DescriptionExpected value of the file's globalContentVersion, a non-negative integer. If the file has a different value, the upload does not run and 409 DISK_VERSION_CONFLICT is returned. Current value: GET /v1/files/:id |
Examples
curl — personal key
curl -X POST "https://vibecode.bitrix24.com/v1/files/205/versions" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"content":"UmVwb3J0IHYy","expectedContentGeneration":3}'
curl — OAuth application
curl -X POST "https://vibecode.bitrix24.com/v1/files/205/versions" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{"content":"UmVwb3J0IHYy","expectedContentGeneration":3}'
JavaScript — personal key
const content = btoa('Report v2')
const res = await fetch('https://vibecode.bitrix24.com/v1/files/205/versions', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({ content, expectedContentGeneration: 3 }),
})
const { data, meta } = await res.json()
if (meta.joinedIntoPreviousVersion) {
console.log('The latest version was overwritten; the history did not grow')
}
JavaScript — OAuth application
const content = btoa('Report v2')
const res = await fetch('https://vibecode.bitrix24.com/v1/files/205/versions', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({ content, expectedContentGeneration: 3 }),
})
const { data, meta } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
Fieldsuccess |
Typeboolean | DescriptionAlways true on success |
Fielddata |
Typeobject | DescriptionThe file after the upload — the same fields as in the GET /v1/files/:id response |
Fielddata.globalContentVersion |
Typenumber | DescriptionFile version counter. Grows by one after the upload |
Fielddata.size |
Typenumber | DescriptionSize of the new content in bytes |
Fieldmeta.joinedIntoPreviousVersion |
Typeboolean|null | Descriptiontrue — the upload overwrote the latest version, and the history did not grow. false — a new version appeared in the history. null — the file history could not be read, so no comparison was made |
Fieldmeta.inTrash |
Typeboolean | Descriptiontrue — the file is in the trash, and its content was replaced anyway |
Response example
{
"success": true,
"data": {
"id": 205,
"name": "report.txt",
"code": null,
"storageId": 1,
"type": "file",
"folderId": 27,
"deletedType": 0,
"globalContentVersion": 4,
"fileId": 369,
"size": 9,
"createdAt": "2026-10-15T17:09:58.000Z",
"updatedAt": "2026-10-15T17:09:59.000Z",
"deletedAt": null,
"createdBy": 1,
"updatedBy": 1,
"deletedBy": null,
"downloadUrl": "https://vibecode.bitrix24.com/v1/files/205/download",
"detailUrl": "https://example.bitrix24.com/company/personal/user/1/disk/file/report.txt"
},
"meta": {
"joinedIntoPreviousVersion": true,
"inTrash": false
}
}
Error response example
409 — expectedContentGeneration did not match the file's globalContentVersion:
{
"success": false,
"error": {
"code": "DISK_VERSION_CONFLICT",
"message": "The content generation changed. Read the file before uploading."
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| HTTP409 | CodeDISK_VERSION_CONFLICT |
DescriptionexpectedContentGeneration did not match the file's globalContentVersion. The content is not changed |
| HTTP400 | CodeINVALID_PARAMS |
Descriptioncontent is empty or not in standard Base64 |
| HTTP400 | CodeINVALID_PARAMS |
DescriptionexpectedContentGeneration is not a non-negative integer |
| HTTP400 | CodeINVALID_ID |
Descriptionid is not a positive integer |
| HTTP401 | CodeMISSING_API_KEY |
DescriptionThe X-Api-Key header is missing |
| HTTP401 | CodeTOKEN_MISSING |
DescriptionAccess tokens for the Bitrix24 portal are unavailable |
| HTTP403 | CodeSCOPE_DENIED |
DescriptionThe key lacks the disk scope |
| HTTP403 | CodeWRITE_BLOCKED_READONLY_KEY |
DescriptionThe key is in read-only mode. The address of the page where the mode is changed is in error.details.switchUrl |
| HTTP404 | CodeENTITY_NOT_FOUND |
DescriptionThere is no file with this id, or it is not available to the key |
| HTTP413 | CodePAYLOAD_TOO_LARGE |
DescriptionThe request body is larger than 70 MiB |
| HTTP422 | CodeDISK_FILE_NOT_SAVED |
DescriptionBitrix24 refused the write without an error code — the refusal text is in error.message |
| HTTP422 | CodeDISK_FILE_NOT_SAVED |
DescriptionBitrix24 did not confirm the upload. Read the file before retrying |
| HTTP429 | CodeLARGE_BODY_BACKEND_BUSY |
DescriptionThe platform is processing other large requests. Retry after error.retryAfter seconds |
| HTTP502 | CodeDISK_OUTCOME_UNKNOWN |
DescriptionThe outcome of the write is unknown, and the platform did not retry the request. Before retrying, read the file with GET /v1/files/:id and compare globalContentVersion with the previous value: if it grew, the upload went through |
Full list of common API errors — Errors.
Known specifics
- An upload within five minutes of a file change overwrites the latest version. If the same user changed the file less than five minutes ago, counting from
updatedAt, the new content replaces the latest version instead of adding a new one. The previous content of that version disappears from the history, andmeta.joinedIntoPreviousVersionistrue. Any change to the file by this user starts the countdown, including creation and renaming. To keep the current content as a separate version, upload the new content when at least five minutes have passed since the file'supdatedAt. expectedContentGenerationis checked before the write, not during it. The platform reads the file, compares the value, and only then uploads the content. This check does not detect a write by another client between the comparison and the upload.- The file name does not change. The content is saved under the file's current name, with the same extension. To rename the file, use
PATCH /v1/files/:id.