[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"docs-storage\u002Fupload\u002Fmultipart-complete":3,"docs-tabs-storage\u002Fupload\u002Fmultipart-complete":6},{"content":4,"lastmod":5},"## Завершить составную загрузку\n\n`POST \u002Fv1\u002Fstorage\u002Fobjects\u002Fmultipart\u002Fcomplete`\n\nФинализирует сессию составной загрузки: собирает загруженные части в единый объект хранилища и переводит его в статус `COMPLETED`. Возвращает готовый объект.\n\n## Поля запроса (body)\n\nТело запроса — JSON.\n\n| Параметр | Тип | Обяз. | По умолч. | Описание |\n|----------|-----|:-----:|-----------|---------|\n| `objectId` | string | да | — | Идентификатор объекта, полученный из ответа `\u002Fmultipart\u002Fcreate` |\n| `parts` | array | да | — | Непустой массив описателей частей с номерами и ETag |\n| `parts[].partNumber` | number | да | — | Номер части (целое от 1 до 10 000); должен совпадать с номерами из ответа `\u002Fmultipart\u002Fcreate`; дубликаты не допускаются |\n| `parts[].etag` | string | да | — | Значение заголовка `ETag` из ответа на `PUT`-запрос части; принимается со скобками (`\"abc...\"`) и без |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X POST https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fstorage\u002Fobjects\u002Fmultipart\u002Fcomplete \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"objectId\": \"cmpfg012a01aco510mrr6u632\",\n    \"parts\": [\n      { \"partNumber\": 1, \"etag\": \"b315b942673d13dbdd2d866e92b0ec13\" },\n      { \"partNumber\": 2, \"etag\": \"a1b2c3d4e5f678901234567890abcdef\" }\n    ]\n  }'\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X POST https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fstorage\u002Fobjects\u002Fmultipart\u002Fcomplete \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"objectId\": \"cmpfg012a01aco510mrr6u632\",\n    \"parts\": [\n      { \"partNumber\": 1, \"etag\": \"b315b942673d13dbdd2d866e92b0ec13\" },\n      { \"partNumber\": 2, \"etag\": \"a1b2c3d4e5f678901234567890abcdef\" }\n    ]\n  }'\n```\n\n### JavaScript — личный ключ\n\n```javascript\n\u002F\u002F uploadedParts — массив { partNumber, etag }, собранный на шаге PUT-загрузки частей\nconst res = await fetch(\n  'https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fstorage\u002Fobjects\u002Fmultipart\u002Fcomplete',\n  {\n    method: 'POST',\n    headers: {\n      'X-Api-Key': 'YOUR_API_KEY',\n      'Content-Type': 'application\u002Fjson',\n    },\n    body: JSON.stringify({\n      objectId: 'cmpfg012a01aco510mrr6u632',\n      parts: uploadedParts,\n    }),\n  }\n)\nconst { object } = await res.json()\nconsole.log('Object ID:', object.id)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch(\n  'https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fstorage\u002Fobjects\u002Fmultipart\u002Fcomplete',\n  {\n    method: 'POST',\n    headers: {\n      'X-Api-Key': 'YOUR_APP_KEY',\n      'Authorization': 'Bearer USER_SESSION_TOKEN',\n      'Content-Type': 'application\u002Fjson',\n    },\n    body: JSON.stringify({\n      objectId: 'cmpfg012a01aco510mrr6u632',\n      parts: uploadedParts,\n    }),\n  }\n)\nconst { object } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `object.id` | string | Идентификатор объекта |\n| `object.key` | string | Логический ключ объекта |\n| `object.contentType` | string | MIME-тип файла |\n| `object.sizeBytes` | string | Размер файла в байтах (строка) |\n| `object.sha256` | string | SHA-256 хеш файла или `null` |\n| `object.visibility` | string | Видимость: `PRIVATE` или `PUBLIC` |\n| `object.uploadStatus` | string | Статус загрузки: `COMPLETED` |\n| `object.createdAt` | string | Дата создания (ISO 8601) |\n| `object.deletedAt` | string | Дата удаления или `null` |\n\n## Пример ответа\n\n```json\n{\n  \"object\": {\n    \"id\": \"cmpfg012a01aco510mrr6u632\",\n    \"key\": \"videos\u002Flecture-01.mp4\",\n    \"contentType\": \"video\u002Fmp4\",\n    \"sizeBytes\": \"209715200\",\n    \"sha256\": null,\n    \"visibility\": \"PRIVATE\",\n    \"uploadStatus\": \"COMPLETED\",\n    \"createdAt\": \"2026-05-21T12:03:56.387Z\",\n    \"deletedAt\": null\n  }\n}\n```\n\n## Пример ответа при ошибке\n\n400 — передано неверное количество частей:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"STORAGE_INVALID_PARTS\",\n    \"message\": \"Expected 2 parts, got 1\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 403 | `STORAGE_SCOPE_REQUIRED` | API-ключу не хватает скоупа `vibe:storage` |\n| 401 | `STORAGE_NO_AUTH_CONTEXT` | Запрос выполнен без авторизации |\n| 400 | `STORAGE_INVALID_PATH` | Идентификатор вызывающего содержит недопустимые символы пути |\n| 400 | `STORAGE_OBJECT_ID_REQUIRED` | Не передано поле `objectId` |\n| 400 | `STORAGE_PARTS_REQUIRED` | Поле `parts` отсутствует или является пустым массивом |\n| 400 | `STORAGE_INVALID_PART` | Элемент массива `parts` содержит недопустимый `partNumber` (не целое в диапазоне 1–10 000, дубликат) или пустой `etag` |\n| 404 | `STORAGE_OBJECT_NOT_FOUND` | Объект с указанным `objectId` не найден или сессия составной загрузки уже завершена |\n| 400 | `STORAGE_INVALID_PARTS` | Количество частей не совпадает с `partCount` из `\u002Fcreate`, либо хранилище отклонило сборку из-за неверных ETag |\n| 503 | `STORAGE_FEATURE_DISABLED` | Хранилище отключено для портала |\n| 503 | `STORAGE_STS_UNAVAILABLE` | Служба выдачи временных учётных данных недоступна |\n| 502 | `STORAGE_BUCKET_ERROR` | Ошибка при взаимодействии с хранилищем |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Смотрите также\n\n- [Загрузка](\u002Fdocs\u002Fstorage\u002Fupload)\n- [Создать составную загрузку](\u002Fdocs\u002Fstorage\u002Fupload\u002Fmultipart-create)\n- [Отменить составную загрузку](\u002Fdocs\u002Fstorage\u002Fupload\u002Fmultipart-abort)\n- [Хранилище](\u002Fdocs\u002Fstorage)\n","2026-07-07",{}]