For AI agents: markdown of this page — /docs-content-en/entities/leads/fields.md documentation index — /llms.txt
Lead fields
GET /v1/leads/fields
Returns the full list of available fields, including user fields (ufCrm_*).
Examples
curl — personal key
curl "https://vibecode.bitrix24.com/v1/leads/fields" \
-H "X-Api-Key: YOUR_API_KEY"
curl — OAuth application
curl "https://vibecode.bitrix24.com/v1/leads/fields" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN"
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/leads/fields', {
headers: {
'X-Api-Key': 'YOUR_API_KEY',
},
})
const { success, data } = await res.json()
console.log('Fields:', Object.keys(data.fields).length)
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/leads/fields', {
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
})
const { success, data } = await res.json()
Response fields
The label and description field captions are returned in English, while the ones the platform takes straight from the Bitrix24 account come in the account language. Request headers do not switch the language.
| Field | Type | RO | Description |
|---|---|---|---|
id |
number | yes | Lead ID |
title |
string | Lead title | |
name |
string | First name | |
lastName |
string | Last name | |
secondName |
string | Middle name | |
stageId |
string | Lead status (stage) — canonical name in responses: NEW, IN_PROCESS, … List: GET /v1/statuses?filter[entityId]=STATUS |
|
statusId |
string | Write/filter/sort alias of stageId. Important: In list/get/search responses the value arrives in the stageId field and the statusId key is not returned — read stageId. Do not pass both the alias and the canonical name in one request |
|
stageSemanticId |
string | yes | Stage semantic category: P — in progress, S — success, F — failure. Read-only; accepted in filters and sorting |
companyTitle |
string | Company name | |
companyId |
number | Company ID. Lookup: GET /v1/companies |
|
contactId |
number | Contact ID. Lookup: GET /v1/contacts |
|
opportunity |
number | Amount — canonical name in responses. Important: For the written value to persist, pass isManualOpportunity: true in the same request |
|
amount |
number | Write/filter alias of opportunity. In responses the value arrives in the opportunity field |
|
isManualOpportunity |
boolean | Manual amount mode. Without true, the amount is recalculated from the product rows and the written value is overwritten |
|
currency |
string | Write/filter alias of currencyId. Currency. List: GET /v1/currencies |
|
currencyId |
string | Currency — canonical name in responses | |
sourceId |
string | Source. List: GET /v1/statuses?filter[entityId]=SOURCE |
|
sourceDescription |
string | Source description | |
assignedById |
number | Assignee. List: GET /v1/users |
|
createdBy |
number | yes | Creator. Lookup: GET /v1/users |
opened |
boolean | Available to everyone | |
comments |
string | Comment | |
post |
string | Position | |
phone |
multifield | Phone. On input (POST/PATCH) accepts string | string[] | object[]. On output phone is a string with the primary value, per-type values are in phoneWork/phoneMobile, and the full list with types is in the fm[] array (format { id, typeId, valueType, value }). Important: PATCH only adds new records — old phone entries are not removed. See Update lead. Important: The UPPER form [{ "VALUE": "...", "VALUE_TYPE": "WORK" }] is not accepted — it returns 400 INVALID_MULTIFIELD_SHAPE. Use camelCase: [{ "value": "...", "typeId": "WORK" }]. |
|
email |
multifield | Email. On input accepts string | string[] | object[]. On output email is a string with the primary value, per-type values are in emailWork/emailHome/emailMailing, and the full list is in the fm[] array. Important: PATCH only adds new records — old email entries are not removed. Important: The UPPER form [{ "VALUE": "...", "VALUE_TYPE": "WORK" }] is not accepted — it returns 400 INVALID_MULTIFIELD_SHAPE. Use camelCase: [{ "value": "...", "typeId": "WORK" }]. |
|
birthdate |
datetime | Birth date | |
hasPhone |
boolean | yes | Whether a phone is set |
hasEmail |
boolean | yes | Whether an email is set |
hasImol |
boolean | yes | Whether there is an Open Channel contact |
isReturnCustomer |
boolean | yes | Repeat customer |
createdTime |
datetime | yes | Creation date |
updatedTime |
datetime | yes | Modification date |
originatorId |
string | External source — identifier of the external system the lead was imported from; null for leads created in Bitrix24 |
|
dateClosed |
datetime | yes | Date the lead was closed; null while the lead is open |
lastCommunicationTime |
string | yes | Date of the last communication with the lead; null if there was none |
utmSource |
string | utm_source tag of the traffic source; null if not set |
|
utmMedium |
string | utm_medium tag of the traffic source; null if not set |
|
utmCampaign |
string | utm_campaign tag of the traffic source; null if not set |
|
utmContent |
string | utm_content tag of the traffic source; null if not set |
|
utmTerm |
string | utm_term tag of the traffic source; null if not set |
The UTM fields are returned in list/get but accepted neither in filter nor in sorting. A request with filter[utmSource] answers 400 UNKNOWN_FILTER_FIELD, one with sort=utmSource answers 400 UNKNOWN_SORT_FIELD, and both refusals arrive before Bitrix24 is called.
User fields (ufCrm_*) are also returned in responses and accepted on create/update.
Available includes
The GET /v1/leads/fields endpoint returns the list of available includes: contact, company.
Usage example: Get leads.
More about includes: Related data.
Response example
{
"success": true,
"data": {
"fields": {
"id": { "type": "number", "readonly": true, "label": "ID", "description": "Unique numeric identifier of the lead." },
"title": { "type": "string", "readonly": false, "label": "Title", "description": "Lead title." },
"stageSemanticId": { "type": "string", "readonly": true, "label": "Stage semantics", "description": "Semantic category of the current stage — codes are decoded in enum.", "enum": [{ "value": "P", "label": "In progress" }, { "value": "S", "label": "Success" }, { "value": "F", "label": "Failure" }] },
"assignedById": { "type": "number", "readonly": false, "label": "Assignee", "description": "ID of the responsible user. List: GET /v1/users." }
},
"batch": ["create", "update", "delete"]
}
}
Only 4 of the many fields are shown. The full list is in the table above.
Errors
| HTTP | Code | Description |
|---|---|---|
| 403 | SCOPE_DENIED |
The API key does not have the crm scope |
| 401 | TOKEN_MISSING |
The API key has no configured tokens |
| 429 | RATE_LIMITED |
Rate limit exceeded: 300 requests per minute per portal, all API keys of the portal share one limit. The exact value arrives in the x-ratelimit-limit header (the cap is divided across replicas). Retry after the delay in the Retry-After header |
Full list of common API errors — Errors.