## Create a CRM document

`POST /v1/crm-documents`

Generates a document from a CRM template for a CRM record (a deal, contact, company or smart process item) and attaches it to that record. Fields are passed at the JSON root without a fields wrapper.

## Request fields (body)

| Field | Type | Required | Description |
|------|-----|:-----:|---------|
| `templateId` | number | yes | CRM template ID, a positive integer. Templates available for a record: [`GET /v1/crm-document-templates/available`](/docs/entities/crm-document-templates/available) |
| `entityTypeId` | number | yes | CRM record type, a positive integer: `2` — deal, `3` — contact, `4` — company. Other types are in the "CRM record types" list on the [`GET /v1/crm-documents`](/docs/entities/documents/crm-list) page |
| `entityId` | number | yes | Record ID, a positive integer. The source depends on the type: deals — [`GET /v1/deals`](/docs/entities/deals/list), contacts — [`GET /v1/contacts`](/docs/entities/contacts/list), companies — [`GET /v1/companies`](/docs/entities/companies/list) |
| `values` | object | no | Template field values. For example, `DocumentNumber` sets the document number |
| `stampsEnabled` | boolean | no | Enable stamps and signatures. If the field is not passed, stamps are disabled. The `changeStampsEnabled` response field shows whether the template has stamps |

The request accepts no other fields, such as `title`. The stamps flag is passed only at the body root, not inside `values`.

## Examples

### curl — personal key

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/crm-documents" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "templateId": 87,
    "entityTypeId": 2,
    "entityId": 8781,
    "values": { "DocumentNumber": "VD-100" }
  }'
```

### curl — OAuth application

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/crm-documents" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "templateId": 87,
    "entityTypeId": 2,
    "entityId": 8781,
    "values": { "DocumentNumber": "VD-100" }
  }'
```

### JavaScript — personal key

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/crm-documents', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    templateId: 87,
    entityTypeId: 2,
    entityId: 8781,
    values: { DocumentNumber: 'VD-100' },
  }),
})

const { success, data } = await res.json()
console.log('Document:', data.id, data.number)
```

### JavaScript — OAuth application

```javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/crm-documents', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    templateId: 87,
    entityTypeId: 2,
    entityId: 8781,
    values: { DocumentNumber: 'VD-100' },
  }),
})

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

## Response fields

Returns HTTP status `201 Created` and the created document. The full description of the document fields is on the [Get a CRM document](/docs/entities/documents/crm-get) page.

| Field | Type | Description |
|------|-----|---------|
| `success` | boolean | Always `true` on success |
| `data.id` | number | ID of the created document. Returned as a number, unlike the [`GET /v1/crm-documents/:id`](/docs/entities/documents/crm-get) response |
| `data.title` | string | Document title generated from the template |
| `data.number` | string | Document number. Set by `values.DocumentNumber` or by the template numerator |
| `data.templateId` | string | Template ID |
| `data.entityTypeId` | string | CRM record type |
| `data.entityId` | number | CRM record ID |
| `data.values` | object | Template field values as passed, along with service keys |
| `data.stampsEnabled` | boolean | Whether stamps and signatures are enabled |
| `data.changeStampsEnabled` | boolean | Whether stamps can be enabled: `false` if the template has none |
| `data.createdBy` | number | Creator ID. List: [`GET /v1/users`](/docs/entities/users) |
| `data.downloadUrl` | string | Link for an employee to open the DOCX file in a browser |
| `data.downloadUrlMachine` | string | URL of [`/v1/crm-documents/:id/download`](/docs/entities/documents/download). Requires `X-Api-Key` with the `crm` scope |

## Response example

The main fields are shown. Full list: [Get a CRM document](/docs/entities/documents/crm-get).

```json
{
  "success": true,
  "data": {
    "changeStampsEnabled": false,
    "downloadUrl": "https://example.bitrix24.com/bitrix/services/main/ajax.php?action=crm.documentgenerator.document.download&SITE_ID=s1&id=1981",
    "publicUrl": null,
    "title": "Addresses VD-100",
    "number": "VD-100",
    "id": 1981,
    "createTime": "2026-10-08T17:55:00+00:00",
    "createdBy": 1317,
    "stampsEnabled": false,
    "isTransformationError": false,
    "values": {
      "productsTableVariant": "",
      "stampsEnabled": false,
      "_creationMethod": "rest",
      "DocumentNumber": "VD-100"
    },
    "templateId": "87",
    "entityId": 8781,
    "entityTypeId": "2",
    "downloadUrlMachine": "https://vibecode.bitrix24.com/v1/crm-documents/1981/download"
  }
}
```

## Error response example

404 — no template with this `templateId` exists:

```json
{
  "success": false,
  "error": {
    "code": "ENTITY_NOT_FOUND",
    "message": "Template not found"
  }
}
```

## Errors

| HTTP | Code | Description |
|------|-----|---------|
| 400 | `MISSING_REQUIRED_FIELDS` | The body is not a JSON object, for example an array. Message: `A document body is required` |
| 400 | `MISSING_REQUIRED_FIELDS` | `templateId`, `entityTypeId` or `entityId` is missing, or the value is not a positive integer. Message: `templateId, entityTypeId and entityId must be positive integers` |
| 400 | `READONLY_FIELD` | The body contains a field not listed in the table above, for example `title` |
| 400 | `INVALID_PARAMS` | `values` is not an object, `values` contains `stampsEnabled`, or `stampsEnabled` is not a boolean |
| 404 | `ENTITY_NOT_FOUND` | No template with this `templateId` exists. Message: `Template not found` |
| 422 | `BITRIX_ERROR` | This `entityTypeId` is not supported for documents, for example `999`. Message: `No provider for entityTypeId` |
| 502 | `BITRIX_INVALID_RESPONSE` | Bitrix24 responded without a document |
| 403 | `BITRIX_ACCESS_DENIED` | No access to the CRM record, including a contact that does not exist. Message: `Access denied` |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | The key is in read-only mode |
| 403 | `SCOPE_DENIED` | The key lacks the `crm` scope |
| 401 | `MISSING_API_KEY` | The `X-Api-Key` header is missing |
| 401 | `TOKEN_MISSING` | No tokens are mapped to the key: an OAuth application key was called without a user session |

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

## Known specifics

**Deal existence is not checked.** With `entityTypeId: 2`, a document is created even for an `entityId` that matches no deal: the response is `201`. For a contact with a nonexistent ID, `403 BITRIX_ACCESS_DENIED` is returned. Check the record beforehand, for example via [`GET /v1/deals/:id`](/docs/entities/deals/get).

**PDF and image appear later.** The creation response contains only DOCX links. Links to the PDF and image appear in the [`GET /v1/crm-documents/:id`](/docs/entities/documents/crm-get) response once the files are ready. Until then, downloading the [PDF](/docs/entities/documents/pdf) returns `409 DOCUMENT_NOT_READY`.

**IDs can be passed as strings.** `"templateId": "87"` is accepted the same way as `87`.

## See also

- [Get a CRM document](/docs/entities/documents/crm-get)
- [Update a CRM document](/docs/entities/documents/crm-update)
- [Upload a CRM document](/docs/entities/documents/crm-upload)
- [Documents by CRM entity](/docs/entities/documents/crm-list)
- [Templates for a CRM record](/docs/entities/crm-document-templates/available)
- [Documents](/docs/entities/documents)
