## Upload an image to a block

`POST /v1/pages/:pageId/blocks/:blockId/files`

Uploads an image file for a page block and returns its URL. The file is passed in the request body as Base64. Upload by URL is not supported.

## Parameters

| Parameter | Type | Required | Description |
|----------|-----|:-----:|----------|
| `pageId` (path) | number | yes | Page ID. List: [`GET /v1/pages`](/docs/entities/pages/list) |
| `blockId` (path) | number | yes | ID of a block on this page. List: [`GET /v1/pages/:pageId/blocks`](/docs/entities/pages/blocks/list) |
| `scope` (query) | string | no | Site area: `KNOWLEDGE` — knowledge base, `GROUP` — workgroup pages, `MAINPAGE` — main pages. Omit the parameter for pages of all other sites |

## Request fields (body)

| Field | Type | Required | Description |
|------|-----|:-----:|----------|
| `fileName` | string | yes | File name with an extension, for example `pixel.png`. An empty string is not accepted |
| `contentBase64` | string | yes | The image file content in standard Base64: the alphabet with `+` and `/`, length a multiple of 4, no line breaks and no `data:` prefix. A file URL instead of the content is not accepted. The whole JSON body is up to 40 MiB, which is about 30 MiB of the source file |

The body must contain no other fields.

## Examples

### curl — personal key

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/pages/42/blocks/7/files" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "fileName": "pixel.png",
    "contentBase64": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+jRZkAAAAASUVORK5CYII="
  }'
```

### curl — OAuth application

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/pages/42/blocks/7/files" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "fileName": "pixel.png",
    "contentBase64": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+jRZkAAAAASUVORK5CYII="
  }'
```

### JavaScript — personal key

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/pages/42/blocks/7/files', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    fileName: 'pixel.png',
    contentBase64: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+jRZkAAAAASUVORK5CYII=',
  }),
})

const { success, data } = await res.json()
```

### JavaScript — OAuth application

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/pages/42/blocks/7/files', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    fileName: 'pixel.png',
    contentBase64: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+jRZkAAAAASUVORK5CYII=',
  }),
})

const { success, data } = await res.json()
```

## Response fields

| Field | Type | Description |
|------|-----|----------|
| `success` | boolean | `true` on success |
| `data.fileId` | number | ID of the uploaded file |
| `data.url` | string | URL of the uploaded image. Pass it in `src` of an image node |

## Response example

```json
{
  "success": true,
  "data": {
    "fileId": 17,
    "url": "https://cdn.example.com/landing/2e8/pixel.png"
  }
}
```

## Error response example

400 — a file URL was passed instead of the file content:

```json
{
  "success": false,
  "error": {
    "code": "INVALID_PARAMS",
    "message": "fileName and non-empty standard contentBase64 are required; URLs are not accepted"
  }
}
```

## Errors

| HTTP | Code | Marker in the response | Description |
|------|-----|-----------------|----------|
| 400 | `INVALID_PARAMS` | `pageId and blockId must be positive safe integers` | `pageId` or `blockId` is not a positive integer |
| 400 | `INVALID_SCOPE` | `scope must be KNOWLEDGE, GROUP or MAINPAGE` | `scope` is not `KNOWLEDGE`, `GROUP` or `MAINPAGE` |
| 400 | `MISSING_REQUIRED_FIELDS` | `Required fields: fileName, contentBase64` | The body lacks one of the fields. The message lists both fields |
| 400 | `MISSING_REQUIRED_FIELDS` | `A JSON object is required` | The body is not a JSON object |
| 400 | `INVALID_PARAMS` | `Unexpected body field` | The body has a field other than `fileName` and `contentBase64` |
| 400 | `INVALID_PARAMS` | `fileName and non-empty standard contentBase64 are required; URLs are not accepted` | `fileName` is empty or whitespace only, or `contentBase64` is empty, contains a file URL or is not standard Base64: the length is not a multiple of 4 or it has a `data:` prefix |
| 401 | `TOKEN_MISSING` | — | The API key has no Bitrix24 access tokens |
| 403 | `SCOPE_DENIED` | — | The key has no `landing` scope |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | — | The key is read-only. The request is rejected before the Bitrix24 account is called |
| 404 | `ENTITY_NOT_FOUND` | `Page or block not found` | The page does not exist, the block does not exist, or the block belongs to another page |
| 409 | `LANDING_MODULE_NOT_ENABLED` | — | The Sites module is not enabled on the Bitrix24 account |
| 409 | `PORTAL_ADDRESS_CHANGED` | — | The on-premise Bitrix24 moved to a new address, but the key's webhook was issued for the old one. Reissue the key's webhook |
| 413 | `PAYLOAD_TOO_LARGE` | — | The JSON body is larger than 40 MiB |
| 422 | `BITRIX_ERROR` | `b24Code`: `FILE_ERROR` | The file content is not an image. The `error.message` text comes in the Bitrix24 account language |
| 422 | `BITRIX_ERROR` | — | The Bitrix24 account did not return the uploaded image |
| 429 | `LARGE_BODY_BACKEND_BUSY` | — | The server is already processing several large request bodies. Retry the request after the pause given in the `Retry-After` header |

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

## Known specifics

- **The uploaded image does not appear on the page by itself.** To show it in the block, pass `data.url` to an image node via [`PATCH /v1/pages/:pageId/blocks/:blockId/nodes`](/docs/entities/pages/block-nodes) as `{"src": url}`.

## See also

- [Change block text and images](/docs/entities/pages/block-nodes)
- [Change block styles](/docs/entities/pages/block-styles)
- [Change block attributes](/docs/entities/pages/block-attrs)
- [Change a block node tag](/docs/entities/pages/block-tags)
- [Set a block anchor](/docs/entities/pages/block-anchor)
- [Publish a block](/docs/entities/pages/block-publication)
- [Read block content](/docs/entities/pages/block-content)
- [List page blocks](/docs/entities/pages/blocks/list)
- [Pages](/docs/entities/pages)
