لوكلاء AI: ملف markdown لهذه الصفحة — /docs-content-en/storage/upload.md فهرس التوثيق — /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.

Uploading again under the same key replaces the object content. This also applies to a soft-deleted object when it belongs to the same owner tuple, has COMPLETED status, and has no open multipart session. The row is revived with the same object.id, createdAt, key, physical address, owner tuple, and visibility; deletedAt is cleared, while sizeBytes, sha256, contentType, and contentUpdatedAt are updated to match the new bytes.

This does not restore the deleted content: Path A writes new bytes over the old ones. For a PUBLIC object, a previously issued anonymous URL with the same object.id starts working again and serves the new bytes. To replace or revive an object, omit visibility or pass the stored value — visibility cannot change (STORAGE_VISIBILITY_MISMATCH). Deleted PENDING rows and rows with a multipart session stay occupied and return 409 STORAGE_KEY_DELETED.

Replacement and revival work the same way for an app-bound key and for a personal developer key: uploading again under the same key does not create a second object.

For Path A direct uploads, concurrent requests to the same physical address run one at a time. A request waits for its turn for no more than 60 seconds; if safe write ownership cannot be confirmed, the server returns 409 STORAGE_KEY_CONFLICT before writing to object storage. Retry the entire request. The guarantee also covers a personal key (appId = null). Path C serializes every key, but replaces a live object only for an app-bound key; it accepts a personal key after explicit DELETE. Path B is excluded.

Request fields (body)

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

Parameter Type Required Default Description
Parameterfile Typefile Requiredyes Default— DescriptionBinary 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
Parameterkey Typestring Requiredyes Default— DescriptionLogical object key: 1 to 1024 characters. Allowed characters: a-z, A-Z, 0-9, ., _, /, -. Must not start with / or . and must not contain ..
Parametervisibility Typestring Requiredno DefaultPRIVATE DescriptionObject visibility: PRIVATE or PUBLIC. On a new object an omitted field means PRIVATE. When replacing or reviving an existing object visibility does not change: omit the field or pass the stored value

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
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. Always computed on direct upload
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": "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
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_FILE_REQUIRED DescriptionThe file field was not provided
HTTP400 CodeSTORAGE_KEY_REQUIRED DescriptionThe key field was not provided
HTTP400 CodeSTORAGE_INVALID_KEY DescriptionThe key value violates the format rules
HTTP400 CodeSTORAGE_INVALID_VISIBILITY DescriptionInvalid visibility value
HTTP400 CodeSTORAGE_VISIBILITY_MISMATCH DescriptionReplacing content cannot change object visibility. Omit the field or pass the current value — it is named in the error message
HTTP409 CodeSTORAGE_KEY_DELETED DescriptionThe deleted row is not eligible for Path A revival: it is not a COMPLETED object without a multipart session. An eligible deleted object returns 200 with the same id and visibility instead
HTTP409 CodeSTORAGE_MULTIPART_IN_PROGRESS DescriptionThe object has a multipart upload in progress — complete or abort it
HTTP409 CodeSTORAGE_UPLOAD_PENDING DescriptionA presigned URL was issued for this key and the upload is not confirmed yet
HTTP409 CodeSTORAGE_KEY_OWNED_ELSEWHERE DescriptionThe name is taken by an object of the other ownership kind (app-shared vs per-employee). Another employee does not block the same name
HTTP409 CodeSTORAGE_KEY_CONFLICT DescriptionThe object state changed, or a concurrent direct upload (Path A) did not obtain write ownership within 60 seconds or the concurrency limit. Object storage is untouched until confirmation; retry the entire request. Serialization also covers a personal key (appId = null). Path C serializes every key, but replaces a live object only for an app-bound key; it accepts a personal key after explicit DELETE. Path B is excluded
HTTP400 CodeSTORAGE_MULTIPART_PARSE_FAILED DescriptionFailed to parse the request body as multipart/form-data
HTTP413 CodeSTORAGE_UPLOAD_TOO_LARGE DescriptionThe file exceeds 10 MB — use multipart upload (Path B is temporarily disabled)
HTTP415 CodeSTORAGE_FORBIDDEN_CONTENT_TYPE DescriptionFor PUBLIC objects the types text/html, application/javascript, application/x-javascript, image/svg+xml are forbidden
HTTP402 CodeBILLING_INSUFFICIENT DescriptionInsufficient balance
HTTP507 CodeSTORAGE_QUOTA_EXCEEDED DescriptionThe file size does not fit the remaining portal storage volume cap. The cap is optional, is switched on by the platform, and applies only to portals that have no commercial Bitrix24 plan and never had one. Usage is counted across the whole portal, not per app
HTTP503 CodeSTORAGE_FEATURE_DISABLED DescriptionStorage is disabled for the portal
HTTP502 CodeSTORAGE_BUCKET_ERROR DescriptionError while interacting with storage

Full list of common API errors — Errors.

Known specifics

Files larger than 10 MB. Path B is temporarily disabled and answers 503 STORAGE_PRESIGNED_UPLOAD_DISABLED, so upload anything above 10 MB with 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