For AI agents: markdown of this page — /docs-content-en/entities/deals/fields.md documentation index — /llms.txt
Deal fields
GET /v1/deals/fields
Returns the full list of available fields, including user fields (ufCrm*).
Examples
curl — personal key
curl "https://vibecode.bitrix24.com/v1/deals/fields" \
-H "X-Api-Key: YOUR_API_KEY"
curl — OAuth application
curl "https://vibecode.bitrix24.com/v1/deals/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/deals/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/deals/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. Enum values carry an English label.
| Field | Type | Description |
|---|---|---|
Fieldsuccess |
Typeboolean | DescriptionAlways true on success |
Fielddata |
Typeobject | DescriptionThe deal field schema and the operations available for deals. Its keys are in the rows below |
Fielddata.fields |
Typeobject | DescriptionThe deal field schema: field name → an object with type, readonly and label. Some fields also carry description and extra attributes such as nullable, multiple, enum and items. The standard fields are listed below, and the ufCrm* user fields of this Bitrix24 account are added to them |
Fielddata.relations |
Typeobject | DescriptionRelations: contact covers all contacts linked to the deal and the operations on them, company is the deal's company. See Deal contacts |
Fielddata.products |
Typeobject | DescriptionOperations on the deal's product rows, the setWarning notice that set replaces all rows, and the product row field schema. See Deal product fields |
Fielddata.activities |
Typeobject | DescriptionDeal activities: the list and create operations and the call, meeting, email and task activity types. See Activities of a CRM record and Create an activity for a CRM record |
Fielddata.actions |
Typeobject | DescriptionActions on a deal: move gives the method, path and parameters for moving the deal to another stage. See Move deal to another stage |
Fielddata.aggregatable |
Typearray | DescriptionStandard fields allowed in the aggregation groupBy: amount, stageId, stageSemanticId, categoryId, assignedById, sourceId |
Fielddata.batch |
Typearray | DescriptionDeal write operations available in batch calls: create, update, delete |
Fielddata.import |
Typeobject | DescriptionMethod, path and maximum batch size for importing records |
Fielddata.include |
Typearray | DescriptionThe names the include parameter accepts: contact, company |
Standard deal fields
The response elements of contactIds are numbers (number[]): OpenAPI describes them as number, while this endpoint and fieldsDetailed in /v1/guide publish readItemSchema: { "type": "number" }. The field remains read-only; values and their order do not change.
| Field | Type | RO | Description |
|---|---|---|---|
Fieldid |
Typenumber | ROyes | DescriptionDeal ID |
Fieldtitle |
Typestring | RO | DescriptionTitle |
Fieldamount |
Typenumber | RO | DescriptionAmount |
Fieldcurrency |
Typestring | RO | DescriptionCurrency. List: GET /v1/currencies |
FieldstageId |
Typestring | RO | DescriptionFunnel stage. The set of stages and their identifiers are configured in your Bitrix24 account and differ between funnels. Current list — GET /v1/statuses?filter[entityId]=DEAL_STAGE for the main funnel, GET /v1/statuses?filter[entityId]=DEAL_STAGE_{N} for the funnel with categoryId={N} (the categoryId value is taken from GET /v1/deal-categories) |
FieldcategoryId |
Typenumber | RO | DescriptionFunnel ID (0 = main). List: GET /v1/deal-categories |
FieldstageSemanticId |
Typestring | ROyes | DescriptionSemantic category of the current stage: P — in progress, S — success, F — failure |
FieldcompanyId |
Typenumber | RO | DescriptionCompany ID. Search: GET /v1/companies |
FieldcontactId |
Typenumber | RO | DescriptionPrimary contact ID. Search: GET /v1/contacts |
FieldcontactIds |
Typenumber[] | ROyes | DescriptionAll linked contacts. Search: GET /v1/contacts |
FieldassignedById |
Typenumber | RO | DescriptionAssignee. List: GET /v1/users |
FieldcreatedBy |
Typenumber | ROyes | DescriptionCreator. Search: GET /v1/users |
FieldupdatedBy |
Typenumber | ROyes | DescriptionModified by. Search: GET /v1/users |
FieldcreatedAt |
Typedatetime | ROyes | DescriptionCreation date |
FieldupdatedAt |
Typedatetime | ROyes | DescriptionModification date |
FieldclosedAt |
Typedatetime | RO | DescriptionClosing date |
Fieldclosed |
Typeboolean | ROyes | DescriptionWhether the deal is closed |
FieldisWon |
Typeboolean | ROyes | DescriptionWhether the deal is in a won stage (stageSemanticId = S). Computed by Bitrix24; comes only in a list or search with an explicit select (see below). Not accepted in filter — 400 UNKNOWN_FILTER_FIELD, filter on stageSemanticId instead; sorting works |
FieldisLose |
Typeboolean | ROyes | DescriptionWhether the deal is in a lost stage (stageSemanticId = F). Like isWon: explicit select only, not accepted in filter, sorting works |
FieldisWork |
Typeboolean | ROyes | DescriptionWhether the deal is in an in-progress stage (stageSemanticId = P). Like isWon: explicit select only, not accepted in filter, sorting works |
FieldhasProducts |
Typeboolean | ROyes | DescriptionWhether the deal has at least one product row (GET /v1/deals/{id}/products). Explicit select only, like isWon. Not accepted in filter (400 UNKNOWN_FILTER_FIELD): Bitrix24 matches the flag only against a boolean value, the Y/N form matches no record, and there is no substitute filter — read select=hasProducts or the product rows; sorting works |
FieldreceivedAmount |
Typenumber | ROyes | DescriptionAmount counted as received, in the account's accounting currency: while the deal is in a won stage it equals amount converted at the account's currency rate (same as amount when currency is the accounting currency), 0 otherwise. Computed by Bitrix24; comes only in an explicit select (see below). Filter (including $gt/$lt) and sorting work |
FieldlostAmount |
Typenumber | ROyes | DescriptionAmount counted as lost, in the account's accounting currency: while the deal is in a lost stage it equals amount converted at the account's currency rate, 0 otherwise. Like receivedAmount: explicit select only, filter and sorting work |
FieldsourceId |
Typestring | RO | DescriptionSource. List: GET /v1/statuses?filter[entityId]=SOURCE |
FieldsourceDescription |
Typestring | RO | DescriptionSource description |
Fieldprobability |
Typenumber | RO | DescriptionProbability of success (%) |
Fieldopened |
Typeboolean | RO | DescriptionAvailable to everyone |
Fieldcomments |
Typestring | RO | DescriptionComment |
Fieldobservers |
Typenumber[] | RO | DescriptionObservers. List: GET /v1/users |
FieldtypeId |
Typestring | RO | DescriptionRecord type. List: GET /v1/statuses?filter[entityId]=DEAL_TYPE |
FieldisReturning |
Typeboolean | RO | DescriptionRepeat deal |
FieldleadId |
Typenumber | RO | DescriptionLead the deal was created from. Arrives as null when the deal was not converted from a lead. Lookup: GET /v1/leads |
FieldquoteId |
Typenumber | RO | DescriptionQuote the deal was created from. Arrives as null when the deal was not created from one. Lookup: GET /v1/quotes |
FieldtaxValue |
Typenumber | ROyes | DescriptionTax amount on the deal, in the deal currency. Arrives as 0 when no tax applies. Computed by Bitrix24 from the product rows and rejected by all write operations. Measured 2026-09-11 on live Bitrix24 accounts of both platforms: create and update in both amount modes, import in both modes — the read-back is 0 every time. Therefore declared read-only: a write is refused instead of answering success and dropping the value. Set the tax through the product rows |
FieldoriginId |
Typestring | RO | DescriptionIdentifier of this deal in the external system it was imported from. Arrives as null for deals created in Bitrix24 |
FieldoriginatorId |
Typestring | RO | DescriptionExternal system the deal was imported from. Arrives as null for deals created in Bitrix24 |
FieldadditionalInfo |
Typestring | RO | DescriptionFree-form additional information on the deal. Arrives as null when unset |
FieldlastActivityBy |
Typenumber | RO | DescriptionUser who performed the last timeline activity on the deal. Arrives as 0 when there was none. Lookup: GET /v1/users |
The seven fields above — leadId, quoteId, taxValue, originId, originatorId, additionalInfo and lastActivityBy — are accepted in filter and in sorting, including in GET /v1/deals, POST /v1/deals/search and POST /v1/deals/aggregate. Five of them (leadId, quoteId, originId, originatorId, additionalInfo) may arrive as null, and for the three string fields an empty string from Bitrix24 is normalized to null — compare against an empty value, not against "".
The six computed fields — isWon, isLose, isWork, hasProducts, receivedAmount, lostAmount — are calculated by Bitrix24 only for a list, a search or the list action of the global batch POST /v1/batch whose select names the field explicitly and without * (GET /v1/deals?select=id,isWon,receivedAmount, POST /v1/deals/search with select). A single GET /v1/deals/{id}, a list without select and the list action of the entity batch (its select is a projection, not forwarded to Bitrix24) return null for them — that is «not requested», not «empty». All six are read-only: a sent value is rejected (create and update — 400 READONLY_FIELD, import — 400 IMPORT_ITEM_VALIDATION, entity batch — 400 BATCH_ITEM_VALIDATION, global batch — READONLY_FIELD under the call). The four flags are not accepted in filter (400 UNKNOWN_FILTER_FIELD): a boolean filter travels to Bitrix24 as Y/N, while Bitrix24 matches these flags only against a boolean value — for the three stage flags, the string Y returns the opposite set of records; for hasProducts, it matches no records. Filter by stageSemanticId for deal stages; there is no alternative filter for product presence. Sorting by all six works; receivedAmount and lostAmount are also accepted in sum/avg/min/max of POST /v1/deals/aggregate — the result is in the account's accounting currency, unlike sum(amount), which adds deal amounts in their own currencies as they are.
The UTM fields (utmSource, utmMedium, utmCampaign, utmContent, utmTerm) are returned on reads but accepted neither in filter nor in sorting. Such a request is rejected with 400 UNKNOWN_FILTER_FIELD or 400 UNKNOWN_SORT_FIELD before Bitrix24 is called, and the reason for each field arrives in its description in this same endpoint's response. For contacts, filter by contactId (the primary contact) or by contactIds (any linked contact).
User fields (ufCrm*) are also returned in responses and accepted on create/update. For an enumeration field, this endpoint returns an array of options at data.fields.<field name>.items, shaped as { "ID": "3983", "VALUE": "warm" }. This is not the enum key of declared fields with value and label elements: to write to a user field, send the ID, while VALUE is the option label for display. A label sent instead of the identifier is lost without an error. Details — Value format by type.
Response example
{
"success": true,
"data": {
"fields": {
"id": { "type": "number", "readonly": true, "label": "ID", "description": "Unique numeric identifier of the deal." },
"title": { "type": "string", "readonly": false, "label": "Title", "description": "Deal title." },
"assignedById": { "type": "number", "readonly": false, "label": "Assignee", "description": "ID of the responsible user. List: GET /v1/users." },
"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" }] }
},
"relations": {
"contact": { "type": "many", "entity": "contacts", "operations": ["list", "add", "remove", "set", "clear"] },
"company": { "type": "one", "entity": "companies", "includable": true }
},
"activities": { "operations": ["list", "create"], "types": ["call", "meeting", "email", "task"] },
"actions": {
"move": { "description": "Change deal stage", "method": "POST", "path": "/v1/deals/{id}/move", "params": { "stageId": { "type": "string", "required": true }, "categoryId": { "type": "string", "required": false } } }
},
"aggregatable": ["amount", "stageId", "stageSemanticId", "categoryId", "assignedById", "sourceId"],
"batch": ["create", "update", "delete"],
"import": { "method": "POST", "path": "/v1/deals/import", "maxItems": 100 },
"include": ["contact", "company"]
}
}
Four fields from data.fields are shown, along with the other data keys. The data.products block is omitted from the example, and the full set of fields is in the tables above.
What to do with the names from data.include is covered on the Get deal page. More about the include parameter — Related data.
Error response example
403 — the key lacks the crm scope:
{
"success": false,
"error": {
"code": "SCOPE_DENIED",
"message": "This endpoint requires 'crm' scope",
"hint": "This request needs the 'crm' scope, which the calling key does not carry. Add 'crm' to this key in the developer cabinet (or through the management API), then repeat the call.",
"cause": "key_scope_missing",
"requiredScope": "crm",
"keyScopes": ["task", "im"],
"fix": { "action": "edit_key_scopes", "via": "cabinet" },
"userMessage": "The app's API key lacks the “CRM” permission. You can add it in the key settings in the developer cabinet."
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| HTTP403 | CodeSCOPE_DENIED |
DescriptionAPI key lacks the crm scope |
| HTTP401 | CodeTOKEN_MISSING |
DescriptionAPI key has no configured tokens |
| HTTP429 | CodeRATE_LIMITED |
DescriptionRate limit exceeded: 300 requests per minute per portal. All API keys of the portal share one limit. The current limit is returned in the x-ratelimit-limit header. Retry after the delay in the Retry-After header |
For the full list of common API errors, see Errors.