## Upload file

`POST /v1/files/upload`

Uploads a file to the Bitrix24 Drive. The contents are passed as Base64 in the JSON request body. To upload, you must specify a folder (`folderId`) or a storage (`storageId`).

## Request fields

| Field | Type | Required | Description |
|------|-----|:-----:|---------|
| `filename` | string | yes | File name with extension, for example `report.pdf` |
| `content` | string | yes | File contents in Base64 |
| `folderId` | number | conditional | Destination folder ID. Folder list: `GET /v1/folders`. Required if `storageId` is not specified |
| `storageId` | number | conditional | Storage ID (upload to root). Storage list: `GET /v1/storages`. Required if `folderId` is not specified |

You must specify one of the two parameters: `folderId` or `storageId`.

## Examples

### curl — personal key

```bash
curl -X POST \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"folderId":27,"filename":"report.txt","content":"SGVsbG8gV29ybGQ="}' \
  https://vibecode.bitrix24.com/v1/files/upload
```

### curl — OAuth app

```bash
curl -X POST \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"folderId":27,"filename":"report.txt","content":"SGVsbG8gV29ybGQ="}' \
  https://vibecode.bitrix24.com/v1/files/upload
```

### JavaScript — personal key

```javascript
const content = Buffer.from('Hello World').toString('base64')

const res = await fetch('https://vibecode.bitrix24.com/v1/files/upload', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    folderId: 27,
    filename: 'report.txt',
    content,
  }),
})
const body = await res.json()
console.log(body.data.id, body.data.downloadUrl)
```

### JavaScript — OAuth app

```javascript
const content = Buffer.from('Hello World').toString('base64')

const res = await fetch('https://vibecode.bitrix24.com/v1/files/upload', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    folderId: 27,
    filename: 'report.txt',
    content,
  }),
})
const body = await res.json()
console.log(body.data.id, body.data.downloadUrl)
```

### Upload to storage root

If you need to upload a file to the storage root rather than to a folder, pass `storageId` instead of `folderId`. The storage ID is available in the `id` field from `GET /v1/storages`, and the root folder is in the `rootFolderId` field.

```bash
curl -X POST \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"storageId":1,"filename":"backup.txt","content":"SGVsbG8gV29ybGQ="}' \
  https://vibecode.bitrix24.com/v1/files/upload
```

## Response fields

| Field | Type | Description |
|------|-----|---------|
| `success` | boolean | Always `true` on success |
| `data.id` | number | ID of the created file |
| `data.name` | string | File name |
| `data.code` | string \| null | Symbolic file code |
| `data.storageId` | number | ID of the storage where the file resides |
| `data.type` | string | Object type — always `"file"` |
| `data.folderId` | number | ID of the folder where the file resides |
| `data.deletedType` | number | Deletion type: `0` — not deleted |
| `data.globalContentVersion` | number | File content version |
| `data.fileId` | number | File ID in the internal Bitrix24 storage |
| `data.size` | number | File size in bytes |
| `data.createdBy` | number | ID of the user who created the file. List: `GET /v1/users` |
| `data.updatedBy` | number | ID of the user who last changed the file |
| `data.deletedBy` | number \| null | ID of the user who deleted the file, or `null` if the file is not deleted |
| `data.createdAt` | string | Creation date and time (ISO 8601) |
| `data.updatedAt` | string | Date and time of the last change (ISO 8601) |
| `data.deletedAt` | string \| null | Deletion date and time, or `null` if the file is not deleted |
| `data.downloadUrl` | string | File download URL |
| `data.detailUrl` | string | URL of the file card in Bitrix24 |

## Response example

On a successful upload, the response is HTTP status `201 Created`.

```json
{
  "success": true,
  "data": {
    "id": 9251,
    "name": "report.txt",
    "code": null,
    "storageId": 1,
    "type": "file",
    "folderId": 27,
    "deletedType": 0,
    "globalContentVersion": 1,
    "fileId": 34867,
    "size": 11,
    "createdBy": 1,
    "updatedBy": 1,
    "deletedBy": null,
    "createdAt": "2026-05-06T09:32:39.000Z",
    "updatedAt": "2026-05-06T09:32:39.000Z",
    "deletedAt": null,
    "downloadUrl": "https://example.bitrix24.com/disk/downloadFile/...",
    "detailUrl": "https://example.bitrix24.com/company/personal/user/1/disk/file/report.txt"
  }
}
```

## Error response example

400 — `filename` and `content` not specified:

```json
{
  "success": false,
  "error": {
    "code": "MISSING_PARAMS",
    "message": "filename and content (base64) are required."
  }
}
```


## Errors

| HTTP | Code | Description |
|------|-----|---------|
| 400 | `MISSING_PARAMS` | `filename` and `content` not provided, or neither `folderId` nor `storageId` specified |
| 401 | `MISSING_API_KEY` | The `X-Api-Key` header was not provided |
| 401 | `INVALID_API_KEY` | Invalid or expired API key |
| 401 | `TOKEN_MISSING` | Access tokens for the Bitrix24 portal are unavailable |
| 403 | `SCOPE_DENIED` | The key lacks the `disk` scope |
| 404 | `ENTITY_NOT_FOUND` | Folder or storage with the given ID not found |
| 422 | `BITRIX_ERROR` | Bitrix24 returned an error while uploading the file |
| 429 | `RATE_LIMITED` | Request limit exceeded |

Full list of common API errors — [Error codes](/docs/errors).

## Known specifics

**Contents are passed as Base64.** The file is encoded in Base64 and passed as a string in the `content` field. Passing a file via `multipart/form-data` is not supported.

**Maximum size.** The request body limit for this route is 70 MB. Since Base64 increases the size by about a third, that corresponds to a source file of roughly 50 MB — a call recording, typical attachments. Bitrix24 additionally enforces its own Disk file-size cap: exceeding it returns `422 BITRIX_ERROR`. Files in the hundreds of MB are not meant to be uploaded through this endpoint.

## See also

- [Files](/docs/entities/files)
- [Folders](/docs/entities/folders)
- [Storages](/docs/entities/storages)
- [Delete file](/docs/entities/files/delete)
