# Sales pipelines

Sales pipelines (deal categories). Each pipeline has its own set of stages.

Bitrix24 API: `crm.dealcategory.*`
Scope: `crm`

Pipeline stages: `GET /v1/statuses?filter[entityId]=DEAL_STAGE_{categoryId}`

The main pipeline with id `0` is not returned by `/v1/deal-categories` and is not addressable by id here — use the universal endpoint `/v1/categories/2` for it.

## Operations

- [Create a pipeline](./deal-categories/create.md) — `POST /v1/deal-categories`
- [List pipelines](./deal-categories/list.md) — `GET /v1/deal-categories`
- [Get a pipeline](./deal-categories/get.md) — `GET /v1/deal-categories/:id`
- [Update a pipeline](./deal-categories/update.md) — `PATCH /v1/deal-categories/:id`
- [Delete a pipeline](./deal-categories/delete.md) — `DELETE /v1/deal-categories/:id`
- [Search pipelines](./deal-categories/search.md) — `POST /v1/deal-categories/search`
- [Pipeline fields](./deal-categories/fields.md) — `GET /v1/deal-categories/fields`
- [Aggregate pipelines](./deal-categories/aggregate.md) — `POST /v1/deal-categories/aggregate`

## Key fields

| Field | Description |
|------|---------|
| `id` | Pipeline ID. Pass it in the deal's `categoryId` field. List: [`GET /v1/deal-categories`](./deal-categories/list.md) |
| `name` | Pipeline name. Required on create |
| `sort` | Sort order among pipelines |
| `isLocked` | Whether the pipeline is locked — unavailable on the current plan. Read-only |
| `createdAt` | Creation date. Read-only |

Full list of fields — [`GET /v1/deal-categories/fields`](./deal-categories/fields.md).

## What to know before you start

1. **The main pipeline is not in this section.** The pipeline with `id` `0` is not included in the list or in `meta.total`, and `GET /v1/deal-categories/0` returns `422 BITRIX_ERROR`. Read it via [`GET /v1/categories/2/0`](/docs/entities/categories/get), where `2` is the "deal" entity type.
2. **Stages live in CRM dictionaries.** The stages of the pipeline with `id` N are stored in the `DEAL_STAGE_N` dictionary: [`GET /v1/statuses?filter[entityId]=DEAL_STAGE_N`](/docs/entities/statuses/list). The stages of the main pipeline are stored in the `DEAL_STAGE` dictionary.
3. **The request body is flat.** On create and update, `name` and `sort` are passed at the JSON root, without a `fields` wrapper.
4. **The filter is exact match only.** List, search, and aggregation filter by `id`, `name`, and `sort` using equality or `$in`. Comparison operators and a filter on `isLocked` or `createdAt` return `400 UNSUPPORTED_FILTER`.
5. **Aggregation has no grouping.** `groupBy` on any field returns `400 INVALID_PARAMS`: pipelines have no fields to group by.

## Typical scenario

A new pipeline with its own stages:

1. Create a pipeline: [`POST /v1/deal-categories`](./deal-categories/create.md) with `name` — the response contains `data.id`.
2. Review the pipeline stages: [`GET /v1/statuses?filter[entityId]=DEAL_STAGE_{id}`](/docs/entities/statuses/list) and, if needed, add your own via [`POST /v1/statuses`](/docs/entities/statuses/create).
3. Create a deal in this pipeline: [`POST /v1/deals`](/docs/entities/deals/create) with `categoryId` equal to the pipeline `id`.
4. Rename the pipeline or change its sort order: [`PATCH /v1/deal-categories/:id`](./deal-categories/update.md).

## Limits

| Limit | Value |
|-------|----------|
| Records per page | `limit`, `50` by default |
| Pagination | `offset` and `meta.hasMore` |
| Batch requests | up to 50 operations in [`POST /v1/batch`](/docs/batch) |
| Request rate | shared across the Vibecode API — see [Limits and optimization](/docs/optimization) |

## See also

- [Deals](/docs/entities/deals)
- [CRM dictionaries](/docs/entities/statuses)
- [Pipelines](/docs/entities/categories)
- [Entity API](/docs/entity-api)
- [Filtering syntax](/docs/filtering)
- [Batch](/docs/batch)
- [API reference](/docs/api-reference)
