## Download document image

`GET /v1/documents/:id/image`

Downloads the image of a generated document through Vibecode: the platform adds Bitrix24 authorization to the request itself. A CRM record document downloads the same way through its own route.

| Document | Route | Scope |
|----------|---------|-------|
| App document | `GET /v1/documents/:id/image` | `documentgenerator` |
| CRM record document | `GET /v1/crm-documents/:id/image` | `crm` |

## Parameters

| Parameter | Type | Required | Description |
|----------|-----|:-----:|---------|
| `id` (path) | number | yes | Document ID, a positive integer. App documents: [`GET /v1/documents`](/docs/entities/documents/list), CRM record documents: [`GET /v1/crm-documents`](/docs/entities/documents/crm-list) |

No request body is sent. The examples below are for an app document. For a CRM record document, replace `documents` with `crm-documents` in the URL.

## Examples

### curl — personal key

```bash
curl --fail-with-body "https://vibecode.bitrix24.com/v1/documents/2001/image" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -o document-2001.jpg
```

### curl — OAuth application

```bash
curl --fail-with-body "https://vibecode.bitrix24.com/v1/documents/2001/image" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -o document-2001.jpg
```

### JavaScript — personal key

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/documents/2001/image', {
  headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})

if (!res.ok) {
  const body = await res.json()
  throw new Error(body.error?.code ?? String(res.status))
}

const blob = await res.blob()
console.log('Image type:', res.headers.get('Content-Type'))
```

### JavaScript — OAuth application

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/documents/2001/image', {
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
  },
})

if (!res.ok) {
  const body = await res.json()
  throw new Error(body.error?.code ?? String(res.status))
}

const blob = await res.blob()
```

## Response fields

On success the HTTP status is `200 OK` and the response body is the bytes of the document image. File details arrive in the headers.

| Header | Example value | Description |
|-----------|-----------------|----------|
| `Content-Type` | `image/jpeg` | Image type returned by Bitrix24. Determine the file format from this header |
| `Content-Disposition` | `attachment; filename="document-2001.png"` | File name for saving: `document-<id>.png` for an app document, `document-<id>` with no extension for a CRM record document. The extension in the name does not match the image format |

## Response example

```http
HTTP/1.1 200 OK
Content-Type: image/jpeg
Content-Disposition: attachment; filename="document-2001.png"
Content-Length: 5899

<binary JPEG content, 5899 bytes>
```

## Error response example

409 — the image is not generated yet:

```json
{
  "success": false,
  "error": {
    "code": "DOCUMENT_NOT_READY",
    "message": "Document file is not ready; retry later."
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|----------|
| 400 | `INVALID_PARAMS` | `id` is not a positive integer. Message: `Document ID must be a positive integer.` |
| 404 | `ENTITY_NOT_FOUND` | No document with this `id`. Message: `Document not found.` |
| 409 | `DOCUMENT_NOT_READY` | The image is not generated yet. Retry the request in a few seconds |
| 502 | `DOWNLOAD_FAILED` | Bitrix24 did not return the file: it responded with an error code, sent JSON instead of the file, pointed to an address outside the Bitrix24 account, or the response could not be read in full. For an app document, also when the file is larger than 10 MiB |
| 422 | `BITRIX_ERROR` | Bitrix24 rejected the request. The reason is in `error.message` |
| 403 | `BITRIX_ACCESS_DENIED` | Bitrix24 denied access to the document. For a CRM record document, also when the record it is attached to does not exist |
| 403 | `SCOPE_DENIED` | The key lacks the route scope: `documentgenerator` for an app document, `crm` for a CRM record document |
| 401 | `MISSING_API_KEY` | The `X-Api-Key` header is missing |
| 401 | `TOKEN_MISSING` | The key has no tokens mapped to it — an OAuth application key was called without a user session |

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

## Known specifics

**A read-only key works.** A download does not count as a write, so a key without write permission gets the file just like a full-access key.

**The image is generated after the document is created or updated.** For the first few seconds after that, the route responds `409 DOCUMENT_NOT_READY`, while the DOCX can already be downloaded.

**The `imageUrlMachine` field points to this route.** In the responses of [`GET /v1/documents/:id`](/docs/entities/documents/get) and [`GET /v1/crm-documents/:id`](/docs/entities/documents/crm-get) the field holds the route URL for the same document. API responses contain no Bitrix24 access secrets.

## See also

- [Download document DOCX](/docs/entities/documents/download)
- [Download document PDF](/docs/entities/documents/pdf)
- [Get document](/docs/entities/documents/get)
- [Get CRM document](/docs/entities/documents/crm-get)
- [Documents](/docs/entities/documents)
