For AI agents: markdown of this page — /docs-content-en/disk/uploads-reserve.md documentation index — /llms.txt
Reserve a file upload to Drive
POST /v1/disk/uploads/reserve
Registers an upcoming file upload to Bitrix24 Drive. This is the first step of a write: the file content is sent in the next call, by operation ID.
The body is flat, with no fields wrapper.
Request fields (body)
| Field | Type | Required | Description |
|---|---|---|---|
FieldreserveRequestId |
Typestring | Requiredyes | DescriptionYour reserve request ID, 1 to 512 characters. A repeat with the same value and the same body returns the operation already created |
Fieldintent |
Typearray | Requiredyes | DescriptionUpload intent — an array of exactly eight elements in the order of the rows below. An extra, missing or reordered element returns 400 INVALID_PARAMS |
Fieldintent[0] |
Typenumber | Requiredyes | DescriptionFormat version, always 1 |
Fieldintent[1] |
Typestring | Requiredyes | DescriptionMode: create — a new file in a folder, version — a new version of an existing file |
Fieldintent[2] |
Typestring | Requiredyes | DescriptionWith create — the ID of the folder the file goes into. List: GET /v1/folders, the storage root folder is the rootFolderId field in GET /v1/storages/:id. With version — the file ID: objectId from POST /v1/disk/search or fileId from the response of a previous upload. A decimal number as a string, without leading zeros |
Fieldintent[3] |
Typestring | Requiredyes | DescriptionSHA-256 of the file's source bytes — 64 lowercase characters |
Fieldintent[4] |
Typestring | Requiredyes | DescriptionFile size in bytes, a decimal number as a string. At most 26214400 (25 MiB) |
Fieldintent[5] |
Typenull | array | Requiredyes | DescriptionWith create — null. With version — the expected current state of the file: an array of three strings [contentFileId, contentGeneration, size]. Values come from the file card in POST /v1/disk/search or from the response of a previous upload |
Fieldintent[6] |
Typestring | Requiredyes | DescriptionFile name on Drive. Not empty and not whitespace-only, with no control characters and none of < > : " | ? * \ / |
Fieldintent[7] |
Typestring | Requiredyes | DescriptionWrite policy: createFail for create mode, versionPreflightNoCAS for version mode. Any other mode and policy pair returns 400 INVALID_PARAMS |
Fieldlineage |
Typeobject | Requiredyes | DescriptionLink between the operation and previous ones |
Fieldlineage.kind |
Typestring | Requiredyes | Descriptioninitial — the first upload with this intent. successor — the next file version after a successful operation: the previous operation is in the application: "applied" state, the new intent is in version mode, and intent[2] equals the fileId of the previous operation. retry — a repeat of the same intent after an operation that ended with application: "not_applied" |
Fieldlineage.priorOperationId |
Typestring | Requiredno | DescriptionRequired with kind: "successor" and kind: "retry". The operationId of the previous operation. List of operations: GET /v1/disk/uploads. Not sent with kind: "initial" |
The body accepts no other fields: an unknown field returns 400 INVALID_PARAMS.
Examples
curl — personal key
curl -X POST https://vibecode.bitrix24.com/v1/disk/uploads/reserve \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"reserveRequestId": "docs-check-reserve-2",
"intent": [1, "create", "1", "6be5cdb4cdbf136301c74adf2fd5a380fe5ceda1e998ce4b62f01cf7d20589a5", "29", null, "vibe-disk-docs-check-2.txt", "createFail"],
"lineage": { "kind": "initial" }
}'
curl — OAuth application
curl -X POST https://vibecode.bitrix24.com/v1/disk/uploads/reserve \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"reserveRequestId": "docs-check-reserve-2",
"intent": [1, "create", "1", "6be5cdb4cdbf136301c74adf2fd5a380fe5ceda1e998ce4b62f01cf7d20589a5", "29", null, "vibe-disk-docs-check-2.txt", "createFail"],
"lineage": { "kind": "initial" }
}'
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/disk/uploads/reserve', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
reserveRequestId: 'docs-check-reserve-2',
intent: [1, 'create', '1', '6be5cdb4cdbf136301c74adf2fd5a380fe5ceda1e998ce4b62f01cf7d20589a5', '29', null, 'vibe-disk-docs-check-2.txt', 'createFail'],
lineage: { kind: 'initial' },
}),
})
const { success, data, error } = await res.json()
if (!success) throw new Error(error.code)
// Store operationId and intentHash before uploading the content
console.log(data.operationId, data.intentHash)
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/disk/uploads/reserve', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
reserveRequestId: 'docs-check-reserve-2',
intent: [1, 'create', '1', '6be5cdb4cdbf136301c74adf2fd5a380fe5ceda1e998ce4b62f01cf7d20589a5', '29', null, 'vibe-disk-docs-check-2.txt', 'createFail'],
lineage: { kind: 'initial' },
}),
})
const { success, data, error } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
Fieldsuccess |
Typeboolean | Descriptiontrue on a successful reserve |
Fielddata.operationId |
Typestring | DescriptionOperation ID. Passed to POST /v1/disk/uploads and GET /v1/disk/uploads/:operationId |
Fielddata.phase |
Typestring | DescriptionOperation stage: prepared — reserved, submitting — the write has been sent to Bitrix24, settled — finished |
Fielddata.application |
Typestring | DescriptionWrite result: applied — the file is written, not_applied — no write was performed, unknown — the result is unknown |
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.intentHash |
Typestring | DescriptionSHA-256 of intent serialized as compact JSON in UTF-8. Passed to POST /v1/disk/uploads |
Fielddata.reservationExpiresAt |
Typestring | DescriptionDate and time in ISO 8601 until which the operation accepts content. Set to 30 days after the operation is created |
Fielddata.recovered |
Typeboolean | Descriptiontrue — an operation created earlier was returned, false — a new one was created |
Response example
New reserve:
{
"success": true,
"data": {
"operationId": "xykPPgOlNBiKMTlAV3SfBoGJhG6Hi6AX57Ede4rAFoU",
"phase": "prepared",
"application": "not_applied",
"verification": "unavailable",
"intentHash": "3e10ae1152a0e4b4e89d3b312bfacafc1f3e0cf22d8a5eae3e231fa8bc274498",
"reservationExpiresAt": "2026-11-22T10:10:36.591Z",
"recovered": false
}
}
A repeat of the same request after the file is uploaded returns the same operation in its current state:
{
"success": true,
"data": {
"operationId": "xykPPgOlNBiKMTlAV3SfBoGJhG6Hi6AX57Ede4rAFoU",
"phase": "settled",
"application": "applied",
"verification": "matched",
"intentHash": "3e10ae1152a0e4b4e89d3b312bfacafc1f3e0cf22d8a5eae3e231fa8bc274498",
"reservationExpiresAt": "2026-11-22T10:10:36.591Z",
"recovered": true
}
}
Error response example
409 — the same reserveRequestId arrived with a different intent:
{
"success": false,
"error": {
"code": "DISK_OPERATION_CONFLICT",
"message": "Disk request unavailable",
"retrySafe": false
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| HTTP400 | CodeINVALID_PARAMS |
DescriptionThe body failed validation: wrong intent composition, invalid file name, lineage without priorOperationId for successor or retry, 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 | 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 |
DescriptionreserveRequestId was already used with a different intent or lineage. Or the priorOperationId operation already has a continuation with a different intent or a different lineage.kind |
| HTTP409 | CodeDISK_PRIOR_REQUIRED |
DescriptionThe priorOperationId operation was not found or has not finished yet, or the lineage.kind condition is not met: for successor — the previous record is not applied, the mode of the new intent is not version, or intent[2] does not equal its fileId; for retry — the previous record is not not_applied or its intent differs |
| HTTP409 | CodeDISK_OUTCOME_UNKNOWN |
DescriptionThe result of the priorOperationId operation is unknown: application equals unknown. Continuations and retries from it are not accepted |
| HTTP409 | CodeDISK_GENERATION_STALE |
DescriptionThe key's connection to Bitrix24 changed during the request. Repeat the reserve |
| HTTP413 | CodeDISK_UPLOAD_TOO_LARGE |
DescriptionThe intent[4] size exceeds 26214400 bytes |
| 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
- A reserve sends no bytes and does not access the folder or file. Folder existence, write permissions and name availability are checked only when the content is uploaded in
POST /v1/disk/uploads. - The same
intentwithlineage.kind: "initial"yields one operation. A newreserveRequestIdwith the sameintentreturns the existing operation withrecovered: true, including a finished one. - An operation has one continuation. Only one
successororretrycontinuation is accepted from a previous operation. A second request with the sameintentandlineage.kindreturns the continuation already created. - Operations are bound to the key's context. Reserve, upload and operation reads work within one Bitrix24 account, one Bitrix24 user and one authorization source: the personal key's inbound webhook or the OAuth application. An operation is not visible from another context.