For AI agents: markdown of this page — /docs-content-en/storage/upload.md documentation index — /llms.txt

Upload

Three file upload paths into storage: a direct form for small files, a presigned PUT for browser uploads, and multipart upload for large files.

Scope: vibe:storage | Base URL: https://vibecode.bitrix24.com/v1 | Authorization: API key (X-Api-Key)

Direct file upload

POST /v1/storage/objects/upload

Uploads a file up to 10 MB in a single multipart/form-data request — the server accepts the file and returns the resulting storage object.

Request fields (body)

The request body must be in multipart/form-data format.

Parameter Type Required Default Description
file file yes Binary file no larger than 10 MB. The MIME type is determined from the Content-Type header of the form part. If the header is absent, application/octet-stream is used
key string yes Logical object key: 1 to 1024 characters. Allowed characters: a-z, A-Z, 0-9, ., _, /, -. Must not start with / or . and must not contain ..
visibility string no PRIVATE Object visibility: PRIVATE or PUBLIC

Examples

curl — personal key

Terminal
curl -X POST https://vibecode.bitrix24.com/v1/storage/objects/upload \
  -H "X-Api-Key: YOUR_API_KEY" \
  -F "file=@avatar.png;type=image/png" \
  -F "key=users/42/avatar.png" \
  -F "visibility=PRIVATE"

curl — OAuth application

Terminal
curl -X POST https://vibecode.bitrix24.com/v1/storage/objects/upload \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -F "file=@avatar.png;type=image/png" \
  -F "key=users/42/avatar.png" \
  -F "visibility=PRIVATE"

JavaScript — personal key

javascript
const formData = new FormData()
formData.append('file', fileInput.files[0])
formData.append('key', 'users/42/avatar.png')
formData.append('visibility', 'PRIVATE')

const res = await fetch('https://vibecode.bitrix24.com/v1/storage/objects/upload', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
  },
  body: formData,
})

if (!res.ok) {
  const { error } = await res.json()
  console.error(error.code, error.message)
  return
}
const { object } = await res.json()
console.log('Object ID:', object.id)

JavaScript — OAuth application

javascript
const formData = new FormData()
formData.append('file', fileInput.files[0])
formData.append('key', 'users/42/avatar.png')
formData.append('visibility', 'PRIVATE')

const res = await fetch('https://vibecode.bitrix24.com/v1/storage/objects/upload', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
  },
  body: formData,
})

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. Always computed on direct upload
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

JSON
{
  "object": {
    "id": "cmpf9b1gp003omr0zkc0qjojn",
    "key": "users/42/avatar.png",
    "contentType": "image/png",
    "sizeBytes": "20480",
    "sha256": "10068f1908d45621f11b50a1d23ddc0720a669c15f45a43d883604e7793537cd",
    "visibility": "PRIVATE",
    "uploadStatus": "COMPLETED",
    "createdAt": "2026-05-21T08:56:32.809Z",
    "deletedAt": null
  }
}

Error response example

415 — the request passed a MIME type that is not allowed for PUBLIC objects because of cross-site scripting risks:

JSON
{
  "success": false,
  "error": {
    "code": "STORAGE_FORBIDDEN_CONTENT_TYPE",
    "message": "Content-Type text/html is not allowed for PUBLIC objects (XSS-prone)"
  }
}

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_FILE_REQUIRED The file field was not provided
400 STORAGE_KEY_REQUIRED The key field was not provided
400 STORAGE_INVALID_KEY The key value violates the format rules
400 STORAGE_INVALID_VISIBILITY Invalid visibility value
400 STORAGE_MULTIPART_PARSE_FAILED Failed to parse the request body as multipart/form-data
413 STORAGE_UPLOAD_TOO_LARGE The file exceeds 10 MB — use a presigned URL
415 STORAGE_FORBIDDEN_CONTENT_TYPE For PUBLIC objects the types text/html, application/javascript, application/x-javascript, image/svg+xml are forbidden
402 BILLING_INSUFFICIENT Insufficient balance
503 STORAGE_FEATURE_DISABLED Storage is disabled for the portal
502 STORAGE_BUCKET_ERROR Error while interacting with storage

Full list of common API errors — Errors.

Known specifics

Files larger than 10 MB. For files from 10 MB to 5 GB use a presigned URL (Path B). For files larger than 5 GB — multipart upload (Path C).

Type check for PUBLIC objects. The check runs against the declared Content-Type of the form part before the file is written — if it fails, the request is rejected without accessing storage.

See also