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. On replacement, the new bytes and metadata are published under the existing objectId; reads return the old content only until publication actually happens. A successful response confirms the new version. Retrying complete with the same parts finishes the operation when the provider response was already journalled: the server finalizes the published result locally without asking the provider to assemble it again. If complete returns 502 STORAGE_BUCKET_ERROR, publication may have happened without a journalled response: the session is retained and requires operator reconciliation, and a blind retry does not confirm the current version. Until an operator releases it, the object cannot be deleted and owner-data erasure remains pending. Returns the ready object when the result is confirmed.

Request fields (body)

The request body is JSON.

Parameter Type Required Default Description
ParameterobjectId Typestring Requiredyes Default— DescriptionObject identifier obtained from the /multipart/create response
Parameterparts Typearray Requiredyes Default— DescriptionNon-empty array of part descriptors with numbers and ETags
Parameterparts[].partNumber Typenumber Requiredyes Default— DescriptionPart number (integer from 1 to 10,000); must match the numbers from the /multipart/create response; duplicates are not allowed
Parameterparts[].etag Typestring Requiredyes Default— DescriptionValue of the ETag header from the response to the part's PUT request; accepted with quotes ("abc...") and without

Examples

curl — personal key

Terminal
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

Terminal
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

javascript
// 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

javascript
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
Fieldobject.id Typestring DescriptionObject identifier
Fieldobject.key Typestring DescriptionLogical object key
Fieldobject.contentType Typestring DescriptionFile MIME type
Fieldobject.sizeBytes Typestring DescriptionFile size in bytes (string)
Fieldobject.sha256 Typestring DescriptionFile SHA-256 hash or null
Fieldobject.visibility Typestring DescriptionVisibility: PRIVATE or PUBLIC
Fieldobject.uploadStatus Typestring DescriptionUpload status: COMPLETED
Fieldobject.createdAt Typestring DescriptionCreation date (ISO 8601)
Fieldobject.deletedAt Typestring DescriptionDeletion date or null
Fieldobject.contentUpdatedAt Typestring (ISO 8601) DescriptionWhen the content last became current: a replacement, or the first completion of the upload. Service updates do not move it. null for objects last written before this field existed

Response example

JSON
{
  "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:

JSON
{
  "success": false,
  "error": {
    "code": "STORAGE_INVALID_PARTS",
    "message": "Expected 2 parts, got 1"
  }
}

Errors

HTTP Code Description
HTTP403 CodeSTORAGE_SCOPE_REQUIRED DescriptionThe API key lacks the vibe:storage scope
HTTP401 CodeSTORAGE_NO_AUTH_CONTEXT DescriptionThe request was made without authorization
HTTP400 CodeSTORAGE_INVALID_PATH DescriptionThe caller identifier contains invalid path characters
HTTP400 CodeSTORAGE_OBJECT_ID_REQUIRED DescriptionThe objectId field was not provided
HTTP400 CodeSTORAGE_PARTS_REQUIRED DescriptionThe parts field is missing or is an empty array
HTTP400 CodeSTORAGE_INVALID_PART DescriptionAn element of the parts array contains an invalid partNumber (not an integer in the range 1–10,000, a duplicate) or an empty etag
HTTP404 CodeSTORAGE_OBJECT_NOT_FOUND DescriptionThe object with the given objectId was not found or the multipart upload session is already finalized
HTTP409 CodeSTORAGE_KEY_CONFLICT DescriptionRetryable conflict: a concurrent write owns the address, or finalization state is changing. Retry complete with the same parts: if the provider response was already journalled, the server finishes the operation locally
HTTP400 CodeSTORAGE_INVALID_PARTS DescriptionThe number of parts does not match partCount from /create, or storage rejected the assembly due to invalid ETags
HTTP503 CodeSTORAGE_FEATURE_DISABLED DescriptionStorage is disabled for the portal
HTTP503 CodeSTORAGE_STS_UNAVAILABLE DescriptionThe temporary credentials issuance service is unavailable
HTTP502 CodeSTORAGE_BUCKET_ERROR DescriptionProvider publication may have completed, but its response was not journalled. The session is retained and requires operator reconciliation; until an operator releases it, the object cannot be deleted and owner-data erasure remains pending. Do not treat a blind retry as proof of success

Full list of common API errors — Errors.

See also