## Image analysis

Models with image support accept graphics through the `content` array with a `type: "image_url"` element. The image address is either a `data:` URI with base64 data or an `https` link. In the [`GET /v1/models`](/docs/ai/models/list) catalog such models carry the `capabilities.vision: true` flag.

Images are processed for free by `bitrix/bitrixgpt-5.5` and `bitrix/bitrixgpt-5.5-thinking`. Through your own provider key (BYOK), the Anthropic Claude models are available: `anthropic/claude-opus-4-6`, `anthropic/claude-sonnet-4-6`, `anthropic/claude-haiku-4-5-20251001`. For them the platform automatically converts the `image_url` element to the Anthropic format — nothing needs to change on the client side.

## Request example

```bash
curl -X POST https://vibecode.bitrix24.com/v1/chat/completions \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "bitrix/bitrixgpt-5.5",
    "messages": [
      {
        "role": "user",
        "content": [
          {"type": "text", "text": "Describe what is in the image"},
          {"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,/9j/4AAQSkZJRg..."}}
        ]
      }
    ],
    "max_tokens": 500
  }'
```

## Limits

| Parameter | Value |
|----------|----------|
| MIME types | `image/png`, `image/jpeg`, `image/gif`, `image/webp` |
| Maximum per image, decoded size | 20 MiB |
| Maximum `image_url.url` in a request | 30 MiB — allowing for base64 encoding, that is 22 MiB of payload |
| `url` format | `data:<mime>[;parameter=value]*;base64,<data>` or `https://<host>/<path>`. Parameters between the type and `;base64` (for example `data:image/jpeg;name=photo.jpg;base64,…`) are accepted and discarded |
| `http://` links | not accepted, only `https` or `data:` |
| Maximum `content` elements per message | 64 |
| Maximum request body per endpoint | 30 MiB |

**MiB** is a mebibyte, a binary unit per the IEC 80000-13 standard: `1 MiB = 2²⁰ = 1 048 576 bytes ≈ 1.05 MB`. Limits are checked as `N × 1024 × 1024`, so the error message also states the size in `MiB` — for example, `decoded size 21.3 MiB exceeds limit 20 MiB`.

## Content check

Before the request is sent to the model, the content of every `image_url` element passed as a `data:` URI is inspected by its actual bytes rather than its declared MIME type. If the content is not an image — for example an HTML page or an error response encoded in base64 and declared as `image/png` — the element is not dropped but **replaced in place** with the text placeholder `[image unavailable: <reason>]`. The remaining images are processed normally and the request succeeds.

The content check applies to `data:` URIs only. A candidate passed as an `https://` link is forwarded to the model as is, without fetching or inspecting its bytes — validate such links on your side.

Positions are preserved: the length of the `content` array does not change, so any candidate numbering on your side stays correct.

The substitution is visible in the response:

- the `X-Image-Parts-Rejected` header carries the number of replaced elements — this is the single signal available in every response mode; for streaming responses it arrives with the start of the stream;
- in a regular (non-streaming) response the `warnings` field additionally carries an entry with code `IMAGE_CONTENT_REJECTED` and the substitution details. A streaming response has no `warnings` field — rely on the header.

## Errors

| HTTP | Code | Description |
|------|-----|---------|
| 400 | `invalid_image_payload` | A structural request error: the `url` field is missing, the string is neither a URL nor a data URI, a formless data URI (no `;base64,`), an unsupported scheme, or `http://` in production. The message contains the `content` element index and the specific reason |

Content errors (not an image, corrupted base64, unsupported MIME type, over 20 MiB) **no longer fail the request** — such an element is replaced with a placeholder (see "Content check").

For the full list of common API errors, see [Errors](/docs/errors).

## Known specifics

**The `content` array is only needed for images.** For text requests pass `content` as a string. An array with a single `text` element also works but is redundant.

**Size is checked after decoding.** The 20 MiB limit applies to the image itself, not to the base64 string. The string is roughly a third longer, so the request body is limited to 30 MiB.

## See also

- [Create a chat completion](./completions.md)
- [List of models](/docs/ai/models/list)
- [Your own keys (BYOK)](/docs/ai/credentials)
