## Change a chat avatar

`PUT /v1/chats/:dialogId/avatar`

Sets the chat avatar: an image from the request body or a file that is already on Drive. A body field selects the mode.

## Parameters

| Parameter | Type | Required | Description |
|----------|-----|:-----:|---------|
| `dialogId` (path) | string | yes | Dialog ID: `chatXXX` for a group chat, a numeric user ID for private messages, `me` — the current user's personal dialog. A CRM entity chat is found via [Find a CRM entity chat](/docs/chats/discovery/find) |

The endpoint takes no query parameters: any parameter in the query string is refused with `400 INVALID_PARAMS`.

## Request fields (body)

| Field | Type | Required | Description |
|------|-----|:-----:|---------|
| `avatar` | string | no | A PNG, JPEG, GIF or WebP image in base64, with sides of at most 5000 pixels. The string must not contain spaces or line breaks. A `data:image/<type>;base64,` prefix is allowed and is stripped. The whole request body is limited to 1 MiB, which is about 750 KiB of the source file |
| `avatarId` | number | no | The `fileId` of a file on Drive — the `data.fileId` field of the [Get file](/docs/entities/files/get) response, not `data.id` |

Send exactly one of the two fields. A body with neither, with both, or with other fields is refused with `400 INVALID_PARAMS`.

## Examples

The examples set the avatar from a local file `logo.png`.

### curl — personal key

```bash
{ printf '{"avatar":"'; base64 < logo.png | tr -d '\r\n'; printf '"}'; } | \
curl -X PUT https://vibecode.bitrix24.com/v1/chats/chat2741/avatar \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @-
```

### curl — OAuth application

```bash
{ printf '{"avatar":"'; base64 < logo.png | tr -d '\r\n'; printf '"}'; } | \
curl -X PUT https://vibecode.bitrix24.com/v1/chats/chat2741/avatar \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  --data-binary @-
```

### JavaScript — personal key

```javascript
import { readFileSync } from 'node:fs'

const avatar = readFileSync('logo.png').toString('base64')

const res = await fetch('https://vibecode.bitrix24.com/v1/chats/chat2741/avatar', {
  method: 'PUT',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ avatar }),
})

const { data } = await res.json()
console.log('Image ID:', data.avatarId)
```

### JavaScript — OAuth application

```javascript
import { readFileSync } from 'node:fs'

const avatar = readFileSync('logo.png').toString('base64')

const res = await fetch('https://vibecode.bitrix24.com/v1/chats/chat2741/avatar', {
  method: 'PUT',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ avatar }),
})

const { data } = await res.json()
console.log('Image ID:', data.avatarId)
```

For a file on Drive, the request body is `{"avatarId": 830}`, with the same headers.

## Response fields

| Field | Type | Description |
|------|-----|---------|
| `success` | boolean | Always `true` on success |
| `data.avatarId` | number | Only in the `avatar` mode: the ID of the image Bitrix24 saved as the avatar |
| `data.result` | boolean | Only in the `avatarId` mode: `true` — the avatar is set |

## Response example

An image from the request body, the `avatar` field:

```json
{
  "success": true,
  "data": {
    "avatarId": 828
  }
}
```

A file on Drive, the `avatarId` field:

```json
{
  "success": true,
  "data": {
    "result": true
  }
}
```

## Error response example

422 — `avatarId` carries the Drive file's `id` instead of its `fileId`:

```json
{
  "success": false,
  "error": {
    "code": "BITRIX_ERROR",
    "message": "Wrong file type",
    "b24Code": "WRONG_PARAMETER"
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|---------|
| 400 | `INVALID_PARAMS` | Neither `avatar` nor `avatarId` is sent, or both are, `avatar` is not base64 or not a PNG, JPEG, GIF or WebP image, an image side exceeds 5000 pixels, `avatarId` is not a positive integer, the body has another field, the body is not a JSON object, or the query string has a parameter. Checked before the Bitrix24 call |
| 413 | `PAYLOAD_TOO_LARGE` | The request body exceeds 1 MiB |
| 403 | `BITRIX_ACCESS_DENIED` | Bitrix24 refused: the user is not a chat member, or the `ui` permission does not let them change the avatar |
| 422 | `BITRIX_ERROR` | Bitrix24 returned an error; the portal code is in `error.b24Code`. `WRONG_PARAMETER` with the text `Wrong file type` means `avatarId` is not the `fileId` of a Drive file: the file's `data.id` was sent, or no file has that `fileId`. If the chat does not exist, the code is `CHAT_NOT_FOUND` |
| 403 | `SCOPE_DENIED` | The API key lacks the `im` scope |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | The key is read-only — changing the avatar counts as a write |
| 401 | `TOKEN_MISSING` | The API key has no configured Bitrix24 tokens |
| 502 | `ME_ALIAS_RESOLUTION_FAILED` | `dialogId=me` — the current user's ID could not be resolved |
| 502 | `BITRIX_UNAVAILABLE` | Bitrix24 is unavailable or returned a server error |

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

## Known specifics

**The image is checked before the write.** Bitrix24 would accept a string that does not read as an image and report success, but it would remove the chat avatar. So the format and size are checked before the Bitrix24 call: a failed check returns `400 INVALID_PARAMS`, and the previous avatar stays.

**A system message about the avatar change.** Changing the avatar in either mode posts a system message to the chat saying that the user changed the chat icon.

**Current avatar.** The current avatar comes in the `avatar` field of the [Dialog details](/docs/chats/discovery/get) response. An empty string means the chat has no avatar.

## See also

- [Change a chat color](/docs/chats/management/color)
- [Change a chat description](/docs/chats/management/description)
- [Configure chat permissions](/docs/chats/management/permissions)
- [Get file](/docs/entities/files/get)
- [Upload file](/docs/entities/files/upload)
