For AI agents: markdown of this page — /docs-content-en/entities/categories/list.md documentation index — /llms.txt
List funnels
GET /v1/categories/:entityTypeId
Returns the funnels of the specified CRM entity type.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
ParameterentityTypeId (path) |
Typenumber | Requiredyes | DescriptionCRM entity type ID. Deals — 2, contacts — 3, companies — 4, invoices — 31, smart processes — from GET /v1/smart-processes |
Parameterselect (query) |
Typestring | Requiredno | DescriptionComma-separated response fields, for example id,name. Without the parameter, all fields are returned. The id field is always returned. Names come from Pipeline fields |
Parameterlimit (query) |
Typenumber | Requiredno | DescriptionHow many pipelines to return. 50 by default, 5000 maximum |
Parameteroffset (query) |
Typenumber | Requiredno | DescriptionHow many pipelines to skip from the start of the list: ?offset=1 starts from the second pipeline |
Parametersort (query) |
Typestring | Requiredno | DescriptionAccepted but does not change the order: pipelines always come sorted by the sort field ascending. The field name is checked against Pipeline fields, and an unknown one returns 400 UNKNOWN_SORT_FIELD. The same applies to the order object: ?order[sort]=desc |
Parameterfilter (query) |
Typeobject | Requiredno | DescriptionFiltering works only by code, as an exact match: ?filter[code]=CATALOG_CONTRACTOR_CONTACT. Only contact and company pipelines have a code, so for other types this filter returns an empty list. Other filter fields are accepted but do not narrow the result. An unknown field name returns 400 UNKNOWN_FILTER_FIELD; valid names come from GET /v1/categories/:entityTypeId/fields.Filtering syntax |
ParameterwithTotal (query) |
Typestring | Requiredno | DescriptionAccepted but does not affect the response: meta.total is returned for any value and any offset |
Examples
The examples use entityTypeId = 2 (deals); replace it with the type you need.
curl — personal key
curl -X GET https://vibecode.bitrix24.com/v1/categories/2 \
-H "X-Api-Key: YOUR_API_KEY"
curl — OAuth application
curl -X GET https://vibecode.bitrix24.com/v1/categories/2 \
-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/categories/2', {
headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})
const { success, data } = await res.json()
console.log(`Pipelines: ${data.length}`)
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/categories/2', {
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
})
const { success, data } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
Fieldsuccess |
Typeboolean | DescriptionAlways true on success |
Fielddata |
Typearray | DescriptionArray of funnels for the type |
Fielddata[].id |
Typenumber | DescriptionFunnel ID. For deals the main funnel has ID 0 |
Fielddata[].name |
Typestring | DescriptionFunnel name |
Fielddata[].sort |
Typenumber | DescriptionSort order |
Fielddata[].entityTypeId |
Typenumber | DescriptionCRM entity type ID, mirrors the path parameter |
Fielddata[].isDefault |
Typeboolean | DescriptionMarks the main pipeline of the type |
Fielddata[].originId |
Typestring | null | DescriptionExternal identifier. null for pipelines with no external binding. Deal pipelines only |
Fielddata[].originatorId |
Typestring | null | DescriptionSource of the external binding. null for pipelines with none. Deal pipelines only |
Fielddata[].isSystem |
Typestring | DescriptionSystem pipeline: Y — created by Bitrix24, N — created by a user. Contact and company pipelines only. |
Fielddata[].code |
Typestring | null | DescriptionSymbolic code of a system pipeline, for example CATALOG_CONTRACTOR_CONTACT. null for the main pipeline and for user-created ones. Contact and company pipelines only |
Fieldmeta.total |
Typenumber | DescriptionHow many pipelines the type has in total — independent of limit and offset |
Fieldmeta.hasMore |
Typeboolean | DescriptionWhether pipelines remain beyond the current page |
Fieldmeta.warnings |
Typearray | DescriptionReturned when select lists a name that is absent from the pipeline schema, or the createdDate field, which Bitrix24 does not return. The request still runs: a field with an unknown name comes back for the pipelines that have it, and is absent for the rest. Each warning is an object with code, field and message, and the code is UNKNOWN_SELECT_FIELD |
The field set depends on the entity type. Deals return originId and originatorId, except for the main pipeline (id 0). Contacts (3) and companies (4) return isSystem and code. Invoices and smart processes return only the common fields. The createdDate field from the pipeline schema is not returned for any type, even when listed in select.
For deals (entityTypeId = 2), get the stages of the main pipeline (id = 0) from GET /v1/statuses?filter[entityId]=DEAL_STAGE and the stages of an additional pipeline (id = N) from GET /v1/statuses?filter[entityId]=DEAL_STAGE_{id} (for example, id = 1 → DEAL_STAGE_1). This deal-stage directory naming rule does not apply to invoices or smart processes.
Response example
The response always contains meta. Additional deal funnels have originId and originatorId; the main funnel (id 0) does not:
{
"success": true,
"data": [
{ "id": 1, "name": "Newest", "sort": 100, "entityTypeId": 2, "isDefault": false, "originId": null, "originatorId": null },
{ "id": 11, "name": "English", "sort": 200, "entityTypeId": 2, "isDefault": false, "originId": null, "originatorId": null },
{ "id": 0, "name": "General", "sort": 300, "entityTypeId": 2, "isDefault": true }
],
"meta": { "total": 3, "hasMore": false }
}
Smart process funnels have a shorter set of fields:
{
"success": true,
"data": [
{ "id": 3, "name": "General", "sort": 500, "entityTypeId": 174, "isDefault": true },
{ "id": 23, "name": "Extra pipeline", "sort": 510, "entityTypeId": 174, "isDefault": false }
],
"meta": { "total": 2, "hasMore": false }
}
Company and contact pipelines come back with isSystem and code:
{
"success": true,
"data": [
{ "id": 0, "name": "Default pipeline", "sort": 0, "entityTypeId": 4, "isDefault": true, "isSystem": "Y", "code": null },
{ "id": 17, "name": "Vendors", "sort": 500, "entityTypeId": 4, "isDefault": false, "isSystem": "Y", "code": "CATALOG_CONTRACTOR_COMPANY" }
],
"meta": { "total": 2, "hasMore": false }
}
Error response example
404 — type not found:
{
"success": false,
"error": {
"code": "ENTITY_NOT_FOUND",
"message": "Smart process not found"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| HTTP404 | CodeENTITY_NOT_FOUND |
DescriptionentityTypeId does not match an existing CRM type |
| HTTP400 | CodeUNKNOWN_FILTER_FIELD |
Descriptionfilter names a field the pipeline does not have. The message lists the valid names |
| HTTP400 | CodeUNKNOWN_SORT_FIELD |
Descriptionsort or order names a field the pipeline does not have. The message lists the valid names |
| HTTP422 | CodeBITRIX_ERROR |
DescriptionThe CRM type does not support pipelines. Quotes (type 7) have no pipelines |
| HTTP403 | CodeSCOPE_DENIED |
DescriptionThe API key lacks the crm scope |
| HTTP401 | CodeTOKEN_MISSING |
DescriptionThe API 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 general API errors, see Errors.
Known specifics
Sort and filter by name on the client side. The server filters pipelines only by code and always sorts them by the sort field in ascending order. To find a pipeline by name, search data: data.filter(c => c.name === 'Sales').
Find a system pipeline by code, not by id. Bitrix24 sets the code of a system pipeline, such as CATALOG_CONTRACTOR_COMPANY, and it is the same across Bitrix24 accounts. The id of the same system pipeline differs from one account to another.
Paging is relative to the full list for the type. meta.total reports how many funnels the type has in total and does not change with limit or offset — walk the list until meta.hasMore is false.