[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"docs-storage\u002Fupload\u002Fmultipart-create":3,"docs-tabs-storage\u002Fupload\u002Fmultipart-create":6},{"content":4,"lastmod":5},"## Создать составную загрузку\n\n`POST \u002Fv1\u002Fstorage\u002Fobjects\u002Fmultipart\u002Fcreate`\n\nОткрывает сессию составной загрузки для файлов до 5 ТБ. Возвращает идентификатор объекта, идентификатор сессии и предподписанные URL для загрузки частей. После загрузки всех частей вызовите [`POST \u002Fv1\u002Fstorage\u002Fobjects\u002Fmultipart\u002Fcomplete`](\u002Fdocs\u002Fstorage\u002Fupload\u002Fmultipart-complete), чтобы собрать объект.\n\n## Поля запроса (body)\n\nТело запроса — JSON.\n\n| Параметр | Тип | Обяз. | По умолч. | Описание |\n|----------|-----|:-----:|-----------|---------|\n| `key` | string | да | — | Логический ключ объекта: от 1 до 1024 символов, допустимы `a-z`, `A-Z`, `0-9`, `.`, `_`, `\u002F`, `-`; не начинать с `\u002F` или `.`, не содержать `..` |\n| `contentType` | string | да | — | MIME-тип файла, например `video\u002Fmp4` или `application\u002Fzip` |\n| `totalSize` | number | да | — | Общий размер файла в байтах; положительное целое число; не более 5 ТБ (5 497 558 138 880 байт) |\n| `partSize` | number | нет | `8388608` | Размер одной части в байтах; от 5 МБ (5 242 880) до 5 ГБ (5 368 709 120); последняя часть может быть меньше минимума |\n| `visibility` | string | нет | `PRIVATE` | Видимость объекта: `PRIVATE` или `PUBLIC` |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X POST https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fstorage\u002Fobjects\u002Fmultipart\u002Fcreate \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"key\": \"videos\u002Flecture-01.mp4\",\n    \"contentType\": \"video\u002Fmp4\",\n    \"totalSize\": 209715200\n  }'\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X POST https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fstorage\u002Fobjects\u002Fmultipart\u002Fcreate \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"key\": \"videos\u002Flecture-01.mp4\",\n    \"contentType\": \"video\u002Fmp4\",\n    \"totalSize\": 209715200\n  }'\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst file = fileInput.files[0]\n\n\u002F\u002F Шаг 1 — открыть сессию составной загрузки\nconst createRes = await fetch(\n  'https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fstorage\u002Fobjects\u002Fmultipart\u002Fcreate',\n  {\n    method: 'POST',\n    headers: {\n      'X-Api-Key': 'YOUR_API_KEY',\n      'Content-Type': 'application\u002Fjson',\n    },\n    body: JSON.stringify({\n      key: 'videos\u002Flecture-01.mp4',\n      contentType: file.type,\n      totalSize: file.size,\n    }),\n  }\n)\nconst { objectId, parts } = await createRes.json()\n\n\u002F\u002F Шаг 2 — загрузить части параллельно, сохранить ETag из заголовков ответов\nconst PART_SIZE = 8 * 1024 * 1024\nconst uploadedParts = await Promise.all(\n  parts.map(async ({ partNumber, uploadUrl }) => {\n    const start = (partNumber - 1) * PART_SIZE\n    const end = Math.min(start + PART_SIZE, file.size)\n\n    const putRes = await fetch(uploadUrl, {\n      method: 'PUT',\n      body: file.slice(start, end),\n    })\n    const etag = putRes.headers.get('ETag')\n    return { partNumber, etag }\n  })\n)\n\n\u002F\u002F Шаг 3 — завершить сборку объекта\nconst completeRes = 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({ objectId, parts: uploadedParts }),\n  }\n)\nconst { object } = await completeRes.json()\nconsole.log('Object ID:', object.id)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst file = fileInput.files[0]\n\nconst createRes = await fetch(\n  'https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fstorage\u002Fobjects\u002Fmultipart\u002Fcreate',\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      key: 'videos\u002Flecture-01.mp4',\n      contentType: file.type,\n      totalSize: file.size,\n    }),\n  }\n)\nconst { objectId, parts } = await createRes.json()\n\nconst PART_SIZE = 8 * 1024 * 1024\nconst uploadedParts = await Promise.all(\n  parts.map(async ({ partNumber, uploadUrl }) => {\n    const start = (partNumber - 1) * PART_SIZE\n    const end = Math.min(start + PART_SIZE, file.size)\n\n    const putRes = await fetch(uploadUrl, { method: 'PUT', body: file.slice(start, end) })\n    const etag = putRes.headers.get('ETag')\n    return { partNumber, etag }\n  })\n)\n\nconst completeRes = 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({ objectId, parts: uploadedParts }),\n  }\n)\nconst { object } = await completeRes.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `objectId` | string | Идентификатор объекта в хранилище |\n| `uploadId` | string | Идентификатор сессии составной загрузки |\n| `partCount` | number | Количество частей, рассчитанное из `totalSize` и `partSize` |\n| `parts` | array | Массив описателей частей |\n| `parts[].partNumber` | number | Номер части (начиная с 1) |\n| `parts[].uploadUrl` | string | Предподписанный URL для загрузки части методом `PUT` |\n| `parts[].expiresAt` | string | Срок действия URL (ISO 8601); совпадает со сроком сессии — 24 часа |\n\n## Пример ответа\n\n```json\n{\n  \"objectId\": \"cmpfg012a01aco510mrr6u632\",\n  \"uploadId\": \"00065252B4EA33D1\",\n  \"partCount\": 2,\n  \"parts\": [\n    {\n      \"partNumber\": 1,\n      \"uploadUrl\": \"https:\u002F\u002Fstorage.example.com\u002Fupload?partNumber=1&uploadId=00065252B4EA33D1&...\",\n      \"expiresAt\": \"2026-05-22T12:03:56.398Z\"\n    },\n    {\n      \"partNumber\": 2,\n      \"uploadUrl\": \"https:\u002F\u002Fstorage.example.com\u002Fupload?partNumber=2&uploadId=00065252B4EA33D1&...\",\n      \"expiresAt\": \"2026-05-22T12:03:56.398Z\"\n    }\n  ]\n}\n```\n\n## Пример ответа при ошибке\n\n413 — файл превышает ограничение 5 ТБ:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"STORAGE_OBJECT_TOO_LARGE\",\n    \"message\": \"Object exceeds 5 TB cap\"\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_KEY_REQUIRED` | Не передано поле `key` |\n| 400 | `STORAGE_INVALID_KEY` | Значение `key` нарушает правила формата |\n| 400 | `STORAGE_CONTENT_TYPE_REQUIRED` | Не передано поле `contentType` |\n| 400 | `STORAGE_INVALID_VISIBILITY` | Недопустимое значение `visibility` |\n| 400 | `STORAGE_INVALID_TOTAL_SIZE` | `totalSize` не является положительным целым числом |\n| 400 | `STORAGE_INVALID_PART_SIZE` | `partSize` выходит за пределы допустимого диапазона (5 МБ – 5 ГБ) или не является положительным целым числом |\n| 413 | `STORAGE_OBJECT_TOO_LARGE` | `totalSize` превышает 5 ТБ |\n| 400 | `STORAGE_TOO_MANY_PARTS` | Рассчитанное количество частей превышает 10 000 — увеличьте `partSize` |\n| 402 | `BILLING_INSUFFICIENT` | Недостаточно средств на балансе |\n| 503 | `STORAGE_FEATURE_DISABLED` | Хранилище отключено для портала |\n| 503 | `STORAGE_STS_UNAVAILABLE` | Служба выдачи временных учётных данных недоступна |\n| 502 | `STORAGE_BUCKET_ERROR` | Ошибка при взаимодействии с хранилищем |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Известные особенности\n\n**Предподписанные URL для частей не требуют заголовков авторизации.** Запросы `PUT` на эти URL отправляются напрямую в хранилище без `X-Api-Key` или `Authorization` — все необходимые учётные данные уже подписаны в самом URL.\n\n**Срок действия сессии — 24 часа.** По истечении срока предподписанные URL становятся недействительными, незагруженные части удаляются автоматически. Для досрочного освобождения ресурсов вызовите [`POST \u002Fv1\u002Fstorage\u002Fobjects\u002Fmultipart\u002Fabort`](\u002Fdocs\u002Fstorage\u002Fupload\u002Fmultipart-abort).\n\n**Файлы меньшего размера.** Для файлов до 10 МБ используйте [прямую загрузку](\u002Fdocs\u002Fstorage\u002Fupload\u002Fdirect) (Путь A). Для файлов до 5 ГБ — [предподписанный URL](\u002Fdocs\u002Fstorage\u002Fupload\u002Fpresigned) (Путь B).\n\n## Смотрите также\n\n- [Загрузка](\u002Fdocs\u002Fstorage\u002Fupload)\n- [Завершить составную загрузку](\u002Fdocs\u002Fstorage\u002Fupload\u002Fmultipart-complete)\n- [Отменить составную загрузку](\u002Fdocs\u002Fstorage\u002Fupload\u002Fmultipart-abort)\n- [Прямая загрузка файла](\u002Fdocs\u002Fstorage\u002Fupload\u002Fdirect)\n- [Хранилище](\u002Fdocs\u002Fstorage)\n","2026-07-07",{}]