For AI agents: markdown of this page — /docs-content-en/entities/crm-document-templates/create.md documentation index — /llms.txt

Create a CRM document template

POST /v1/crm-document-templates

Creates a CRM document template from a .docx file passed as a base64 string and binds it to CRM record types. Fields go in the JSON root without a wrapper.

Request fields (body)

Field Type Required Description
name string yes Template name
file string yes Contents of your .docx file as a base64 string, no more than 2 MiB after decoding. See "Known specifics" for how to get the string
numeratorId number yes ID of the numerator that assigns numbers to documents. A positive integer. The list of numerators is not exposed through /v1/...
region string yes Template region, for example uk
entityTypeId array yes Non-empty array of CRM record types, numbers or strings: 2 — deal, 3 — contact, 4 — company. Smart process types — GET /v1/smart-processes
users array no Array of access codes as strings: UA — all employees, U<id> — the employee with this ID from GET /v1/users. When called with a personal key without this field, the template is available only to the key owner: the response returns that employee's U<id>
active string no Whether the template is active: Y or N. Defaults to Y
withStamps string no Stamps and signatures in documents: Y or N. Defaults to N
sort number no Sort index. Defaults to 500
code string no Template symbolic code

The fields id, fileId, moduleId, download, downloadMachine, isDeleted, isDefault, createTime, updateTime, createdBy, updatedBy, providers are read-only. A request with any of them is rejected with 400 READONLY_FIELD. The name is compared ignoring case and underscores: module_id and ModuleId are rejected too.

Examples

In the examples, contract.docx is your template file. The request body is assembled into the template.json file and then sent.

curl — personal key

Terminal
printf '{"name":"Supply agreement","numeratorId":1,"region":"uk","entityTypeId":[2],"users":["UA"],"file":"%s"}' \
  "$(base64 < contract.docx | tr -d '\n')" > template.json

curl -X POST "https://vibecode.bitrix24.com/v1/crm-document-templates" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @template.json

curl — OAuth application

Terminal
printf '{"name":"Supply agreement","numeratorId":1,"region":"uk","entityTypeId":[2],"users":["UA"],"file":"%s"}' \
  "$(base64 < contract.docx | tr -d '\n')" > template.json

curl -X POST "https://vibecode.bitrix24.com/v1/crm-document-templates" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  --data-binary @template.json

JavaScript — personal key

javascript
import { readFile } from 'node:fs/promises'

const file = (await readFile('contract.docx')).toString('base64')

const res = await fetch('https://vibecode.bitrix24.com/v1/crm-document-templates', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Supply agreement',
    numeratorId: 1,
    region: 'uk',
    entityTypeId: [2],
    users: ['UA'],
    file,
  }),
})

const { success, data } = await res.json()
console.log('Template ID:', data.id)

JavaScript — OAuth application

javascript
import { readFile } from 'node:fs/promises'

const file = (await readFile('contract.docx')).toString('base64')

const res = await fetch('https://vibecode.bitrix24.com/v1/crm-document-templates', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Supply agreement',
    numeratorId: 1,
    region: 'uk',
    entityTypeId: [2],
    users: ['UA'],
    file,
  }),
})

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

Response fields

Field Type Description
success boolean Always true on success
data object The created template
data.id string Template ID, as a string
data.name string Template name
data.region string Template region
data.code string | null Template symbolic code, null — no code set
data.download string Template file download URL in the Bitrix24 web interface. To download through the API, use downloadMachine
data.active string Whether the template is active: Y or N
data.moduleId string Owner module, always crm
data.numeratorId string Numerator ID, as a string
data.withStamps string Stamps and signatures: Y or N
data.users object Access codes as an object, each code serves as both key and value: {"UA": "UA"}
data.isDeleted string Deletion flag: N for an active template
data.sort string Sort index, as a string
data.createTime string Creation date in ISO 8601 with a time zone offset
data.updateTime string Last modification date in ISO 8601 with a time zone offset
data.entityTypeId array CRM record types as strings, exactly as passed in the request. When the template is read, the deal type expands by funnel — see What to know before you start
data.downloadMachine string .docx download URL through the Vibecode API — GET /v1/crm-document-templates/:id/download

Response example

HTTP 201:

JSON
{
  "success": true,
  "data": {
    "id": "263",
    "name": "Supply agreement",
    "region": "uk",
    "code": null,
    "download": "https://example.bitrix24.com/bitrix/services/main/ajax.php?action=crm.documentgenerator.template.download&SITE_ID=s1&id=263",
    "active": "Y",
    "moduleId": "crm",
    "numeratorId": "1",
    "withStamps": "N",
    "users": {
      "UA": "UA"
    },
    "isDeleted": "N",
    "sort": "500",
    "createTime": "2026-10-08T13:20:29+00:00",
    "updateTime": "2026-10-08T13:20:29+00:00",
    "entityTypeId": ["2"],
    "downloadMachine": "https://vibecode.bitrix24.com/v1/crm-document-templates/263/download"
  }
}

Error response example

400 — a required field is missing:

JSON
{
  "success": false,
  "error": {
    "code": "MISSING_REQUIRED_FIELDS",
    "message": "Required field 'numeratorId' is missing."
  }
}

Errors

HTTP Code Description
400 MISSING_REQUIRED_FIELDS One of the required fields is missing, or its value is null, an empty string or an empty array. An empty body {} gets the same code
400 INVALID_PARAMS file is not a base64 string. A placeholder instead of the file contents is rejected with this code before the request reaches Bitrix24
400 INVALID_PARAMS users is not an array of non-empty strings, for example, the {"UA": "UA"} object was passed in the shape the response returns
400 INVALID_PARAMS entityTypeId is not an array, or it contains a value that is neither a positive number nor a non-empty string
400 INVALID_PARAMS name or region is not a string, numeratorId is not a positive integer
400 INVALID_PARAMS The request body is not a JSON object
400 READONLY_FIELD The body contains a read-only field, for example moduleId or fileId
413 PAYLOAD_TOO_LARGE The file exceeds 2 MiB after decoding file, or the JSON body exceeds 3 MiB
429 LARGE_BODY_BACKEND_BUSY The body exceeds 1 MiB and the platform is already processing the maximum volume of large bodies. Retry after Retry-After seconds
422 BITRIX_WRITE_NOT_APPLIED The template was created, but Bitrix24 did not save all of the passed entityTypeId or users. The created template ID is in error.details.createdTemplateId. Check the template with GET /v1/crm-document-templates/:id before retrying: a repeated request creates another template
422 BITRIX_ERROR Bitrix24 rejected the creation. The reason text is in error.message
403 WRITE_BLOCKED_READONLY_KEY The key works in read-only mode
403 SCOPE_DENIED The key lacks the crm scope
401 TOKEN_MISSING The key has no configured tokens
429 RATE_LIMITED Bitrix24 rate-limited requests to the portal. Retry after the delay in the Retry-After header

Full list of common API errors — Errors.

Known specifics

How to get the file value. Build the base64 string from your file with base64 < contract.docx | tr -d '\n', on macOS — base64 -i contract.docx | tr -d '\n'. Removing line breaks from the output is mandatory: a string with line breaks fails the base64 check.

See also