For AI agents: markdown of this page — /docs-content-en/storage/upload/multipart-complete.md documentation index — /llms.txt
Complete multipart upload
POST /v1/storage/objects/multipart/complete
Finalizes a multipart upload session: assembles the uploaded parts into a single storage object and moves it to status COMPLETED. Returns the ready object.
Request fields (body)
The request body is JSON.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
objectId |
string | yes | — | Object identifier obtained from the /multipart/create response |
parts |
array | yes | — | Non-empty array of part descriptors with numbers and ETags |
parts[].partNumber |
number | yes | — | Part number (integer from 1 to 10,000); must match the numbers from the /multipart/create response; duplicates are not allowed |
parts[].etag |
string | yes | — | Value of the ETag header from the response to the part's PUT request; accepted with quotes ("abc...") and without |
Examples
curl — personal key
curl -X POST https://vibecode.bitrix24.com/v1/storage/objects/multipart/complete \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"objectId": "cmpfg012a01aco510mrr6u632",
"parts": [
{ "partNumber": 1, "etag": "b315b942673d13dbdd2d866e92b0ec13" },
{ "partNumber": 2, "etag": "a1b2c3d4e5f678901234567890abcdef" }
]
}'
curl — OAuth application
curl -X POST https://vibecode.bitrix24.com/v1/storage/objects/multipart/complete \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"objectId": "cmpfg012a01aco510mrr6u632",
"parts": [
{ "partNumber": 1, "etag": "b315b942673d13dbdd2d866e92b0ec13" },
{ "partNumber": 2, "etag": "a1b2c3d4e5f678901234567890abcdef" }
]
}'
JavaScript — personal key
// uploadedParts — an array of { partNumber, etag } collected at the part-PUT step
const res = await fetch(
'https://vibecode.bitrix24.com/v1/storage/objects/multipart/complete',
{
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
objectId: 'cmpfg012a01aco510mrr6u632',
parts: uploadedParts,
}),
}
)
const { object } = await res.json()
console.log('Object ID:', object.id)
JavaScript — OAuth application
const res = await fetch(
'https://vibecode.bitrix24.com/v1/storage/objects/multipart/complete',
{
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
objectId: 'cmpfg012a01aco510mrr6u632',
parts: uploadedParts,
}),
}
)
const { object } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
object.id |
string | Object identifier |
object.key |
string | Logical object key |
object.contentType |
string | File MIME type |
object.sizeBytes |
string | File size in bytes (string) |
object.sha256 |
string | File SHA-256 hash or null |
object.visibility |
string | Visibility: PRIVATE or PUBLIC |
object.uploadStatus |
string | Upload status: COMPLETED |
object.createdAt |
string | Creation date (ISO 8601) |
object.deletedAt |
string | Deletion date or null |
Response example
{
"object": {
"id": "cmpfg012a01aco510mrr6u632",
"key": "videos/lecture-01.mp4",
"contentType": "video/mp4",
"sizeBytes": "209715200",
"sha256": null,
"visibility": "PRIVATE",
"uploadStatus": "COMPLETED",
"createdAt": "2026-05-21T12:03:56.387Z",
"deletedAt": null
}
}
Error response example
400 — an incorrect number of parts was passed:
{
"success": false,
"error": {
"code": "STORAGE_INVALID_PARTS",
"message": "Expected 2 parts, got 1"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 403 | STORAGE_SCOPE_REQUIRED |
The API key lacks the vibe:storage scope |
| 401 | STORAGE_NO_AUTH_CONTEXT |
The request was made without authorization |
| 400 | STORAGE_INVALID_PATH |
The caller identifier contains invalid path characters |
| 400 | STORAGE_OBJECT_ID_REQUIRED |
The objectId field was not provided |
| 400 | STORAGE_PARTS_REQUIRED |
The parts field is missing or is an empty array |
| 400 | STORAGE_INVALID_PART |
An element of the parts array contains an invalid partNumber (not an integer in the range 1–10,000, a duplicate) or an empty etag |
| 404 | STORAGE_OBJECT_NOT_FOUND |
The object with the given objectId was not found or the multipart upload session is already finalized |
| 400 | STORAGE_INVALID_PARTS |
The number of parts does not match partCount from /create, or storage rejected the assembly due to invalid ETags |
| 503 | STORAGE_FEATURE_DISABLED |
Storage is disabled for the portal |
| 503 | STORAGE_STS_UNAVAILABLE |
The temporary credentials issuance service is unavailable |
| 502 | STORAGE_BUCKET_ERROR |
Error while interacting with storage |
Full list of common API errors — Errors.