For AI agents: markdown of this page — /docs-content-en/entities/quotes/search.md documentation index — /llms.txt
Search quotes
POST /v1/quotes/search
Search CRM quotes with filters and auto-pagination. Equivalent to GET /v1/quotes with filters, but via POST — more convenient for complex requests with many conditions.
Request fields (body)
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
Parameterfilter |
Typeobject | Requiredno | Default— | DescriptionFilter by the fields from GET /v1/quotes/fields.Filtering syntax. Example: ?filter[stageId]=DRAFT |
Parameterlimit |
Typenumber | Requiredno | Default50 |
DescriptionNumber of records (up to 5000) |
Parameteroffset |
Typenumber | Requiredno | Default0 |
DescriptionSkip N records. Rejected when combined with a date-range filter wider than 14 days — see UNSTABLE_OFFSET_PAGINATION in the "Errors" section |
Parameterorder |
Typeobject | Requiredno | Default— | DescriptionSorting: { "createdTime": "desc" } |
Parameterselect |
Typestring[] | Requiredno | Default— | DescriptionField selection: ["id", "title", "amount"] |
Parameterinclude |
Typestring | array | Requiredno | Default— | DescriptionRelated records: deal, contact, company — as an array or a comma-separated string. They arrive in the _included field of each data element. See Related data |
ParameterwithTotal |
Typeboolean | Requiredno | Default— | DescriptionWhether you need the record count in meta.total. false — do not request a count; this is the only way to guarantee that meta.total is absent from the response. Without the parameter, the API key setting applies, then the platform default. Paging and counts |
ParameterautoWindow |
Typeboolean | Requiredno | Defaulttrue |
DescriptionSplit the result set into weekly windows when filtering by a date range wider than 14 days. false disables splitting |
Examples
curl — personal key
curl -X POST "https://vibecode.bitrix24.com/v1/quotes/search" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"filter": { "stageId": "DRAFT" },
"limit": 10,
"order": { "amount": "desc" }
}'
curl — OAuth application
curl -X POST "https://vibecode.bitrix24.com/v1/quotes/search" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"filter": { "stageId": "DRAFT" },
"limit": 10,
"order": { "amount": "desc" }
}'
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/quotes/search', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
filter: { stageId: 'DRAFT' },
limit: 10,
order: { amount: 'desc' },
}),
})
const { success, data } = await res.json()
console.log('Found:', data.length)
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/quotes/search', {
method: 'POST',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
filter: { stageId: 'DRAFT' },
limit: 10,
order: { amount: 'desc' },
}),
})
const { success, data } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
Fielddata |
Typearray | DescriptionArray of quotes (all fields — see Fields) |
Fieldmeta.total |
Typenumber | DescriptionHow many records matched the filter. An optional field: if no count was requested and the page is filled up to limit, it is absent from the response |
Fieldmeta.hasMore |
Typeboolean | DescriptionWhether there are more records beyond limit |
Fieldmeta.nextAfterId |
Typestring | DescriptionThe identifier of the last returned record. Returned when the sort is strictly id ascending, while hasMore is true. Pass it back in the >id filter — a cheap replacement for a growing offset |
Fieldmeta.durationMs |
Typenumber | DescriptionRequest duration in milliseconds |
Fieldmeta.autoWindowed |
Typeboolean | Descriptiontrue if the result set was split into time windows |
Fieldmeta.windowCount |
Typenumber | DescriptionNumber of windows. Present with autoWindowed: true |
Fieldmeta.batchWaves |
Typenumber | DescriptionNumber of parallel request waves. Present with autoWindowed: true |
The meta fields sit next to data, not inside it. Paginate using meta.hasMore: a page whose data length equals limit can still be the last one.
The card URL of any quote from the data array is built from its id:
https://<portal>.bitrix24.com/crm/type/7/details/<id>/
7 — the entityTypeId of a quote in Bitrix24. <portal> — the Bitrix24 portal domain. Access is restricted by the employee's permissions in Bitrix24.
Response example
{
"success": true,
"data": [
{
"id": 412,
"title": "Quote for server hardware",
"amount": 1500,
"currency": "USD",
"stageId": "DRAFT",
"dealId": 741,
"assignedById": 29,
"createdTime": "2026-04-15T10:30:00.000Z"
}
],
"meta": {
"total": 23,
"hasMore": true,
"durationMs": 247
}
}
With a date-range filter wider than 14 days, meta also contains autoWindowed, windowCount, and batchWaves:
{
"success": true,
"data": [ /* ... */ ],
"meta": {
"total": 35,
"hasMore": true,
"autoWindowed": true,
"windowCount": 339,
"batchWaves": 7,
"durationMs": 9492
}
}
Error response example
403 — no scope:
{
"success": false,
"error": {
"code": "SCOPE_DENIED",
"message": "This endpoint requires 'crm' scope"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| HTTP400 | CodeUNSTABLE_OFFSET_PAGINATION |
Descriptionoffset greater than zero together with a date-range filter wider than 14 days. Two different retrieval algorithms produce inconsistent results, so the request is rejected. Fetch everything in a single request with limit up to 5000, or pass autoWindow: false with sorting by id, or split the date range into parts yourself |
| HTTP400 | CodeINVALID_INCLUDE |
Descriptioninclude contains an unknown name. The message lists the allowed ones: deal, contact, company |
| 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 common API errors, see Errors.
Known specifics
Time-window splitting. A date-range filter wider than 14 days is automatically split into weekly windows executed in parallel waves, so the result set bypasses the ceiling of 5000 records per call. meta then contains autoWindowed: true, the number of windows windowCount, and the number of waves batchWaves. The autoWindow: false parameter disables splitting. While splitting is active, an offset greater than zero is rejected with UNSTABLE_OFFSET_PAGINATION.