#Создать предподписанный URL
POST /v1/storage/objects
Первый шаг загрузки файла от 10 МБ до 5 ГБ — возвращает временный URL, по которому клиент отправляет файл напрямую методом PUT; после отправки вызывается подтверждение загрузки.
#Поля запроса (body)
| Поле | Тип | Обяз. | По умолч. | Описание |
|---|---|---|---|---|
key |
string | да | — | Логический ключ объекта: от 1 до 1024 символов, допустимы a-z, A-Z, 0-9, ., _, /, -; не начинать с / или ., не содержать .. |
contentType |
string | да | — | MIME-тип файла; должен совпасть с заголовком Content-Type при PUT-запросе на uploadUrl |
visibility |
string | нет | PRIVATE |
Видимость объекта: PRIVATE или PUBLIC |
sizeBytes |
number | нет | — | Ожидаемый размер файла в байтах; используется как подсказка при проверке квоты, фактический размер фиксируется на шаге подтверждения |
ttlSeconds |
number | нет | 3600 |
Срок действия предподписанного URL в секундах: от 60 до 86400 |
#Примеры
#curl — личный ключ
# Шаг 1 — получить предподписанный URL
curl -X POST https://vibecode.bitrix24.tech/v1/storage/objects \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"key": "users/42/report.pdf",
"contentType": "application/pdf",
"visibility": "PRIVATE"
}'
# Шаг 2 — отправить файл на полученный uploadUrl
curl -X PUT "https://storage.example.com/upload/..." \
-H "Content-Type: application/pdf" \
--data-binary @report.pdf
#curl — OAuth-приложение
# Шаг 1 — получить предподписанный URL
curl -X POST https://vibecode.bitrix24.tech/v1/storage/objects \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"key": "users/42/report.pdf",
"contentType": "application/pdf",
"visibility": "PRIVATE"
}'
# Шаг 2 — отправить файл на полученный uploadUrl
curl -X PUT "https://storage.example.com/upload/..." \
-H "Content-Type: application/pdf" \
--data-binary @report.pdf
#JavaScript — личный ключ
// Шаг 1 — получить предподписанный URL
const res = await fetch('https://vibecode.bitrix24.tech/v1/storage/objects', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
key: 'users/42/report.pdf',
contentType: 'application/pdf',
visibility: 'PRIVATE',
}),
})
if (!res.ok) {
const { error } = await res.json()
console.error(error.code, error.message)
return
}
const result = await res.json()
// Шаг 2 — отправить файл на предподписанный URL
const put = await fetch(result.uploadUrl, {
method: 'PUT',
headers: { 'Content-Type': 'application/pdf' },
body: file, // File или Blob
})
if (!put.ok) throw new Error(`PUT failed: ${put.status}`)
#JavaScript — OAuth-приложение
// Шаг 1 — получить предподписанный URL
const res = await fetch('https://vibecode.bitrix24.tech/v1/storage/objects', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
key: 'users/42/report.pdf',
contentType: 'application/pdf',
visibility: 'PRIVATE',
}),
})
const result = await res.json()
// Шаг 2 — отправить файл на предподписанный URL
await fetch(result.uploadUrl, {
method: 'PUT',
headers: { 'Content-Type': 'application/pdf' },
body: file, // File или Blob
})
#Поля ответа
| Поле | Тип | Описание |
|---|---|---|
objectId |
string | Идентификатор объекта; передать в `POST /v1/storage/objects/complete` |
uploadUrl |
string | Предподписанный URL для отправки файла методом PUT |
bucket |
string | Служебное название контейнера |
objectKey |
string | Служебный ключ объекта в хранилище |
expiresAt |
string | Срок действия предподписанного URL (ISO 8601) |
#Пример ответа
{
"objectId": "cmpf9b1gp003omr0zkc0qjojn",
"uploadUrl": "https://storage.example.com/upload/portals/example-portal/users/42/report.pdf?X-Amz-Signature=abc123",
"bucket": "example-storage-bucket",
"objectKey": "portals/example-portal/users/42/report.pdf",
"expiresAt": "2026-05-21T09:57:43.675Z"
}
#Пример ответа при ошибке
400 — ttlSeconds вне допустимого диапазона:
{
"success": false,
"error": {
"code": "STORAGE_INVALID_TTL",
"message": "ttlSeconds must be between 60 and 86400"
}
}
#Ошибки
| HTTP | Код | Описание |
|---|---|---|
| 403 | STORAGE_SCOPE_REQUIRED |
API-ключу не хватает скоупа vibe:storage |
| 401 | STORAGE_NO_AUTH_CONTEXT |
Запрос выполнен без авторизации |
| 400 | STORAGE_KEY_REQUIRED |
Не передано поле key |
| 400 | STORAGE_CONTENT_TYPE_REQUIRED |
Не передано поле contentType |
| 400 | STORAGE_INVALID_KEY |
Значение key нарушает правила формата |
| 400 | STORAGE_INVALID_VISIBILITY |
Недопустимое значение visibility |
| 400 | STORAGE_INVALID_SIZE |
Недопустимое значение sizeBytes |
| 400 | STORAGE_INVALID_TTL |
ttlSeconds вне диапазона 60–86400 |
| 402 | BILLING_INSUFFICIENT |
Недостаточно средств на балансе |
| 507 | STORAGE_QUOTA_EXCEEDED |
Исчерпана квота хранилища |
| 503 | STORAGE_FEATURE_DISABLED |
Хранилище отключено для портала |
| 503 | STORAGE_STS_UNAVAILABLE |
Сервис выдачи временных учётных данных недоступен |
| 502 | STORAGE_BUCKET_ERROR |
Ошибка при взаимодействии с хранилищем |
Полный список общих ошибок API — Ошибки.
#Известные особенности
Обязательный второй шаг. После отправки файла на uploadUrl необходимо вызвать подтверждение загрузки с objectId из этого ответа. До подтверждения объект находится в статусе PENDING и недоступен для скачивания.
Срок действия URL. ttlSeconds ограничивает срок действия предподписанного URL загрузки, а не срок хранения готового объекта.