For AI agents: markdown of this page — /docs-content-en/disk/uploads.md documentation index — /llms.txt
Upload file content to Drive
POST /v1/disk/uploads
Writes a file to Bitrix24 Drive under a previously reserved operation — creates a new file or a new version of an existing one, as set at reserve time.
The body is flat, with no fields wrapper.
Request fields (body)
| Field | Type | Required | Description |
|---|---|---|---|
FieldoperationId |
Typestring | Requiredyes | DescriptionOperation ID from the POST /v1/disk/uploads/reserve response. A lost ID can be found in GET /v1/disk/uploads |
FieldintentHash |
Typestring | Requiredyes | DescriptionThe intentHash field from the reserve response — 64 lowercase characters |
FieldeffectiveFilename |
Typestring | Requiredyes | DescriptionFile name matching the reserve's intent[6] character for character |
Fieldcontent |
Typestring | Requiredyes | DescriptionFile bytes in base64 per RFC 4648: alphabet A-Z, a-z, 0-9, +, /, padding =, with no line breaks and no data: prefix. At most 26214400 bytes after decoding (25 MiB) |
FieldcontentHash |
Typestring | Requiredyes | DescriptionSHA-256 of the file bytes before base64 encoding — 64 lowercase characters. Matches the reserve's intent[3] |
The body accepts no other fields: an unknown field returns 400 INVALID_PARAMS. The total request body size is at most 35 MiB.
Examples
curl — personal key
curl -X POST https://vibecode.bitrix24.com/v1/disk/uploads \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"operationId": "xykPPgOlNBiKMTlAV3SfBoGJhG6Hi6AX57Ede4rAFoU",
"intentHash": "3e10ae1152a0e4b4e89d3b312bfacafc1f3e0cf22d8a5eae3e231fa8bc274498",
"effectiveFilename": "vibe-disk-docs-check-2.txt",
"content": "VmliZSBEaXNrIGFnZW50IGRvY3MgY2hlY2sgMgo=",
"contentHash": "6be5cdb4cdbf136301c74adf2fd5a380fe5ceda1e998ce4b62f01cf7d20589a5"
}'
curl — OAuth application
curl -X POST https://vibecode.bitrix24.com/v1/disk/uploads \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"operationId": "xykPPgOlNBiKMTlAV3SfBoGJhG6Hi6AX57Ede4rAFoU",
"intentHash": "3e10ae1152a0e4b4e89d3b312bfacafc1f3e0cf22d8a5eae3e231fa8bc274498",
"effectiveFilename": "vibe-disk-docs-check-2.txt",
"content": "VmliZSBEaXNrIGFnZW50IGRvY3MgY2hlY2sgMgo=",
"contentHash": "6be5cdb4cdbf136301c74adf2fd5a380fe5ceda1e998ce4b62f01cf7d20589a5"
}'
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/disk/uploads', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
operationId: 'xykPPgOlNBiKMTlAV3SfBoGJhG6Hi6AX57Ede4rAFoU',
intentHash: '3e10ae1152a0e4b4e89d3b312bfacafc1f3e0cf22d8a5eae3e231fa8bc274498',
effectiveFilename: 'vibe-disk-docs-check-2.txt',
content: 'VmliZSBEaXNrIGFnZW50IGRvY3MgY2hlY2sgMgo=',
contentHash: '6be5cdb4cdbf136301c74adf2fd5a380fe5ceda1e998ce4b62f01cf7d20589a5',
}),
})
const { success, data, error } = await res.json()
if (!success) throw new Error(error.code)
if (data.application === 'unknown') {
// Do not repeat the write: check the folder or file on Drive first
console.warn('Write result unknown:', data.operationId)
} else if (data.application === 'applied') {
console.log('File written:', data.fileId, data.safeLink)
}
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/disk/uploads', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
operationId: 'xykPPgOlNBiKMTlAV3SfBoGJhG6Hi6AX57Ede4rAFoU',
intentHash: '3e10ae1152a0e4b4e89d3b312bfacafc1f3e0cf22d8a5eae3e231fa8bc274498',
effectiveFilename: 'vibe-disk-docs-check-2.txt',
content: 'VmliZSBEaXNrIGFnZW50IGRvY3MgY2hlY2sgMgo=',
contentHash: '6be5cdb4cdbf136301c74adf2fd5a380fe5ceda1e998ce4b62f01cf7d20589a5',
}),
})
const { success, data, error } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
Fieldsuccess |
Typeboolean | Descriptiontrue if the request was processed. Whether the file was written is shown by data.application |
Fielddata.operationId |
Typestring | DescriptionOperation ID |
Fielddata.phase |
Typestring | DescriptionOperation stage: prepared — reserved, submitting — the write has been sent to Bitrix24, settled — finished |
Fielddata.application |
Typestring | DescriptionWrite result: applied — Bitrix24 confirmed the write, not_applied — the write was not sent to Bitrix24, unknown — the write was sent but not confirmed |
Fielddata.verification |
Typestring | DescriptionCheck against the current state of the file: matched — the file matches what was written, superseded — the file has changed since, unavailable — the check was not performed |
Fielddata.fileId |
Typestring | DescriptionFile ID on Drive. Returned with application: "applied". Used as intent[2] in version mode |
Fielddata.contentFileId |
Typestring | DescriptionID of the written content. Returned with application: "applied". The first element of the expected state intent[5] for the next version |
Fielddata.contentGeneration |
Typestring | DescriptionFile content version number. Returned with application: "applied". The second element of intent[5] for the next version |
Fielddata.safeLink |
Typestring | DescriptionHTTPS address of the file in Bitrix24. Returned when Bitrix24 provided it. Access is limited by the employee's permissions in Bitrix24 |
Fielddata.atomicConcurrency |
Typeboolean | DescriptionAlways false: the write is not protected against another user changing the file at the same time |
Fielddata.conflictDetected |
Typeboolean | Descriptiontrue if, in version mode, the current state of the file did not match intent[5] and no write was performed |
Fielddata.outcomeUnknown |
Typeboolean | Descriptiontrue with application: "unknown" |
Response example
File written:
{
"success": true,
"data": {
"operationId": "xykPPgOlNBiKMTlAV3SfBoGJhG6Hi6AX57Ede4rAFoU",
"phase": "settled",
"application": "applied",
"verification": "matched",
"fileId": "10901",
"contentFileId": "39571",
"contentGeneration": "1",
"safeLink": "https://example.bitrix24.com/company/personal/user/1/disk/file/vibe-disk-docs-check-2.txt",
"atomicConcurrency": false,
"conflictDetected": false,
"outcomeUnknown": false
}
}
The write was sent but not confirmed — the folder already had a file with that name:
{
"success": true,
"data": {
"operationId": "zQl-VU0ZeSeCYnH14kibBVeiYRM7iihEu6-QDSTPJFQ",
"phase": "settled",
"application": "unknown",
"verification": "unavailable",
"atomicConcurrency": false,
"conflictDetected": false,
"outcomeUnknown": true
}
}
Error response example
409 — contentHash does not match the SHA-256 of the bytes sent:
{
"success": false,
"error": {
"code": "DISK_OPERATION_CONFLICT",
"message": "Disk request unavailable",
"retrySafe": false
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| HTTP400 | CodeINVALID_PARAMS |
DescriptionThe body failed validation: a required field is missing, intentHash or contentHash is not 64 hexadecimal characters, an invalid file name, an unknown field |
| HTTP401 | CodeMISSING_API_KEY |
DescriptionThe X-Api-Key header is missing |
| HTTP401 | CodeINVALID_API_KEY |
DescriptionThe key is not recognized |
| HTTP401 | CodeTOKEN_MISSING |
DescriptionThe key has no connection to Bitrix24 |
| HTTP401 | CodeDISK_AUTH_UNAVAILABLE |
DescriptionThe Bitrix24 user could not be confirmed: an application key was sent without Authorization: Bearer, the session does not belong to the key's application, or the key is not supported by the Drive agent |
| HTTP401 | CodeDISK_AUTH_UNAVAILABLE |
Descriptionversion mode: the current state of the file could not be read. No write was performed, the operation finished with application: "not_applied" |
| HTTP401 | CodeTOKEN_REFRESH_FAILED |
DescriptionThe portal authorization for the key could not be refreshed. A retry does not help until the key is authorized again |
| HTTP403 | CodeSCOPE_DENIED |
DescriptionThe key has no disk scope |
| HTTP403 | CodeWRITE_BLOCKED_READONLY |
DescriptionThe key is in read-only mode |
| HTTP403 | CodeDISK_ACCESS_DENIED |
DescriptionBitrix24 denied access while checking the user |
| HTTP409 | CodeDISK_OPERATION_CONFLICT |
Descriptioncontent is not base64 per RFC 4648, contentHash does not match the SHA-256 of the bytes, or intentHash, effectiveFilename, the hash or the byte size does not match the reserve |
| HTTP409 | CodeDISK_OPERATION_EXPIRED |
DescriptionThe operationId operation was not found in the key's context or its reservationExpiresAt deadline has passed. Create a new reserve |
| HTTP409 | CodeDISK_VERSION_CONFLICT |
Descriptionversion mode: the current state of the file did not match intent[5]. No write was performed, the operation finished with application: "not_applied" and conflictDetected: true |
| HTTP413 | CodeDISK_UPLOAD_TOO_LARGE |
DescriptionThe content exceeds 26214400 bytes after decoding |
| HTTP413 | CodePAYLOAD_TOO_LARGE |
DescriptionThe request body exceeds 35 MiB |
| HTTP429 | CodeLARGE_BODY_BACKEND_BUSY |
DescriptionThe server is processing many large requests at once. The response carries a Retry-After header with the pause in seconds |
| HTTP502 | CodeDISK_READ_UNAVAILABLE |
DescriptionBitrix24 returned an error that Vibecode did not recognize |
| HTTP503 | CodeQUERY_LIMIT_EXCEEDED |
DescriptionBitrix24 limited the request rate. Retry later |
| HTTP503 | CodeBITRIX_TIMEOUT |
DescriptionBitrix24 did not respond in time |
| HTTP503 | CodeQUEUE_OVERFLOW, QUEUE_TIMEOUT |
DescriptionThe portal call queue is full. The Retry-After header gives the pause before a retry |
| HTTP503 | CodeRATE_LIMITED |
DescriptionThe portal responded with HTTP 429. The Retry-After header gives the pause before a retry |
| HTTP503 | CodeERROR_LOOP_DETECTED |
DescriptionRepeated errors of this key on this method have temporarily stopped calls. The Retry-After header gives the pause |
| HTTP503 | Codeuser_self_deletion_pending |
DescriptionThe key owner requested deletion of their account — Drive calls are stopped |
Full list of common API errors — Errors.
Known specifics
- The write is sent to Bitrix24 once. Vibecode does not retry it on its own, either on a timeout or on a connection failure. If Bitrix24 did not confirm a sent write — refused, did not respond or responded incompletely — the operation finishes with
application: "unknown", and a repeat call with the sameoperationIdreturns that state without a new write. - With
application: "unknown", check Drive before writing again. A new reserve withlineage.kind: "retry"from such an operation is rejected with409 DISK_OUTCOME_UNKNOWN. Find the file viaPOST /v1/disk/searchorPOST /v1/disk/sync/checkand decide whether a new write withlineage.kind: "initial"and a differentintentis needed. createmode does not overwrite a file. If the folder already has a file with the same name, the existing file stays unchanged and the operation finishes withapplication: "unknown". To replace content, useversionmode.- Repeating a finished operation recalculates
verification. Forapplication: "applied", the field is checked against the current file again. - The
intent[5]check inversionmode runs before the write and does not lock the file. A change to the file between the check and the write is not detected. After409 DISK_VERSION_CONFLICT, take the currentcontentFileId,contentGenerationandsizeand reserve a new operation.