[{"data":1,"prerenderedAt":8},["ShallowReactive",2],{"docs-entities\u002Fcrm-search":3,"docs-tabs-entities\u002Fcrm-search":6},{"content":4,"lastmod":5},"# CRM search\n\nFind a client or a deal across several CRM types in one request: by title, full name, phone or email.\n\nBitrix24 API: `crm.entity.search`\nScope: `crm`\n\n## Operations\n\n- [Search CRM records](.\u002Fcrm-search\u002Fsearch.md) — `POST \u002Fv1\u002Fcrm\u002Fsearch`\n\n## Key fields\n\n| Field | Type | Description |\n|------|-----|---------|\n| `searchQuery` | string | Search string |\n| `options.types` | array | CRM types to search: `LEAD`, `DEAL`, `CONTACT`, `COMPANY`, `INVOICE`, `QUOTE`, `SMART_INVOICE` or a smart process `entityTypeId` as a number from [`GET \u002Fv1\u002Fsmart-processes`](\u002Fdocs\u002Fentities\u002Fsmart-processes\u002Flist) |\n| `options.scope` | string | Where to search: `DENOMINATION` — title and full name, `INDEX` — full-text index including phone and email |\n| `data[].type`, `data[].id` | string, number | Type and ID of the found record. Use them to read the record through its own section, for example [`GET \u002Fv1\u002Fcontacts\u002F:id`](\u002Fdocs\u002Fentities\u002Fcontacts\u002Fget) |\n| `meta.limits` | array | Types excluded from the search by a Bitrix24 plan restriction |\n\n## Before you start\n\n1. **At most 20 records across all types combined, no pagination.** A broad query without `options.types` can fill all 20 slots with records of a single type. To find a contact or a company, pass `types`.\n2. **Phone and email are searched only with `scope: \"INDEX\"`.** Without `scope` the search covers title and full name, and a query by phone number returns an empty list.\n3. **An empty `data` does not mean there are no records.** If `meta.limits` is not empty, the types it lists are excluded by a Bitrix24 plan restriction, and their records are not in the response.\n4. **A read-only key is enough.** The search changes nothing on the Bitrix24 account.\n\n## Typical scenario\n\n1. Find a client by phone: [`POST \u002Fv1\u002Fcrm\u002Fsearch`](.\u002Fcrm-search\u002Fsearch.md) with `searchQuery` and `options.scope: \"INDEX\"`.\n2. Check `meta.limits`: if it is not empty, some types were left out of the search.\n3. Read the found record by `type` and `id`, for example [`GET \u002Fv1\u002Fcontacts\u002F:id`](\u002Fdocs\u002Fentities\u002Fcontacts\u002Fget).\n4. Create a to-do for the found client: [`POST \u002Fv1\u002Factivity-todos`](\u002Fdocs\u002Fentities\u002Factivities\u002Ftodos\u002Fcreate).\n\n## Limits\n\n| Limit | Value |\n|-------|----------|\n| Records per response | at most 20 across all types combined |\n| Pagination | none |\n| Batch calls | not supported: [`POST \u002Fv1\u002Fbatch`](\u002Fdocs\u002Fbatch) returns `UNKNOWN_ENTITY` for `crm-search`, call the search as a separate request |\n| Request rate | shared across the Vibecode API — see [Limits and optimization](\u002Fdocs\u002Foptimization) |\n\n## See also\n\n- [Contacts](.\u002Fcontacts.md)\n- [Companies](.\u002Fcompanies.md)\n- [Leads](.\u002Fleads.md)\n- [Deals](.\u002Fdeals.md)\n- [Entity reference](\u002Fdocs\u002Fentity-api)\n","2026-10-20",{"crm-search\u002Fsearch.md":7},"## Search CRM records\n\n`POST \u002Fv1\u002Fcrm\u002Fsearch`\n\nSearches leads, deals, contacts, companies and other CRM records in one request by title, full name, phone or email. Returns at most 20 records across all types combined.\n\n## Request fields (body)\n\n| Field | Type | Required | Description |\n|------|-----|:-----:|---------|\n| `searchQuery` | string | yes | Search string, not empty and not whitespace only |\n| `options.types` | array | no | CRM types to search: `LEAD`, `DEAL`, `CONTACT`, `COMPANY`, `INVOICE`, `QUOTE`, `SMART_INVOICE`, or a smart process `entityTypeId` as a number from [`GET \u002Fv1\u002Fsmart-processes`](\u002Fdocs\u002Fentities\u002Fsmart-processes\u002Flist). A smart process can also be passed as the string `DYNAMIC_\u003CentityTypeId>`. Without the field, the search covers all of these types |\n| `options.scope` | string | no | Where to search: `DENOMINATION` — title and full name, `INDEX` — full-text index including phone and email. Without the field, the search covers title and full name, and a phone or email query returns an empty `data` array |\n| `options.categoryId` | number | no | Integer. Does not narrow deal results by pipeline: with the `categoryId` of a pipeline from [`GET \u002Fv1\u002Fdeal-categories`](\u002Fdocs\u002Fentities\u002Fdeal-categories\u002Flist), the same records come back as without it |\n\nThe body and `options` accept no other fields: an unknown field is rejected with `400 INVALID_PARAMS`.\n\n## Examples\n\n### curl — personal key\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Fcrm\u002Fsearch\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"searchQuery\": \"+12025550123\",\n    \"options\": { \"scope\": \"INDEX\" }\n  }'\n```\n\n### curl — OAuth application\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Fcrm\u002Fsearch\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"searchQuery\": \"+12025550123\",\n    \"options\": { \"scope\": \"INDEX\" }\n  }'\n```\n\n### JavaScript — personal key\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Fcrm\u002Fsearch', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    searchQuery: '+12025550123',\n    options: { scope: 'INDEX' },\n  }),\n})\n\nconst { data, meta } = await res.json()\nfor (const item of data) console.log(item.type, item.id, item.title)\nif (meta.limits.length) console.log('Excluded by plan:', meta.limits.map((l) => l.type))\n```\n\n### JavaScript — OAuth application\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Fcrm\u002Fsearch', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    searchQuery: '+12025550123',\n    options: { scope: 'INDEX' },\n  }),\n})\n\nconst { data, meta } = await res.json()\n```\n\n## Response fields\n\n| Field | Type | Description |\n|------|-----|---------|\n| `success` | boolean | `true` on success |\n| `data` | array | Records found, at most 20 across all types combined |\n| `data[].id` | number | Record ID |\n| `data[].type` | string | Record type, for example `LEAD`, `DEAL`, `CONTACT`, `COMPANY` |\n| `data[].entityTypeId` | number | Numeric record type, for example `1` — lead, `2` — deal, `3` — contact, `4` — company |\n| `data[].title` | string | Record title or full name |\n| `data[].subTitle` | string | Additional line, for example the contact name on a lead. Can be empty |\n| `data[].links.show` | string \\| null | Path to the record card in the Bitrix24 web interface, relative to the Bitrix24 account address, for example `\u002Fcrm\u002Fcontact\u002Fdetails\u002F3167\u002F`. Not an API endpoint |\n| `data[].attributes.phone` | array | Record phone numbers, items `{ type, value }`. The field is absent if there are no phone numbers |\n| `data[].attributes.email` | array | Record emails, items `{ type, value }`. The field is absent if there are no emails |\n| `meta.limit` | number | Maximum number of records in the response, always `20` |\n| `meta.limits` | array | Types excluded from the search by a Bitrix24 plan limit. Items `{ type, title, description }`. An empty array means no exclusions |\n| `meta.limitsMeaning` | string | Explanation of `meta.limits` |\n\n## Response example\n\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 3167,\n      \"type\": \"CONTACT\",\n      \"entityTypeId\": 3,\n      \"title\": \"Anna Smith\",\n      \"subTitle\": \"\",\n      \"links\": {\n        \"show\": \"\u002Fcrm\u002Fcontact\u002Fdetails\u002F3167\u002F\"\n      },\n      \"attributes\": {\n        \"phone\": [\n          { \"type\": \"WORK\", \"value\": \"+12025550123\" }\n        ],\n        \"email\": [\n          { \"type\": \"WORK\", \"value\": \"anna.smith@example.com\" }\n        ]\n      }\n    }\n  ],\n  \"meta\": {\n    \"limit\": 20,\n    \"limits\": [],\n    \"limitsMeaning\": \"These CRM types were omitted because the Bitrix24 search tariff limit was exceeded\"\n  }\n}\n```\n\n## Error response example\n\n400 — unknown type in `options.types`:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"INVALID_PARAMS\",\n    \"message\": \"Unknown CRM type\"\n  }\n}\n```\n\n## Errors\n\n| HTTP | Code | Description |\n|------|-----|----------|\n| 400 | `MISSING_REQUIRED_FIELDS` | `searchQuery` is not passed, is not a string, or is whitespace only |\n| 400 | `INVALID_PARAMS` | Unknown type in `options.types`, including a smart process `entityTypeId` that does not exist on the portal. Checked before the search |\n| 400 | `INVALID_PARAMS` | `options.scope` is neither `DENOMINATION` nor `INDEX`, `options.categoryId` is not an integer, `options.types` is not an array |\n| 400 | `INVALID_PARAMS` | Unknown field in the body or in `options`, or the body or `options` is not a JSON object |\n| 502 | `BITRIX_RESPONSE_INVALID` | Bitrix24 returned a search response of an unexpected shape |\n| 403 | `SCOPE_DENIED` | The key has no `crm` scope |\n| 401 | `TOKEN_MISSING` | The key has no Bitrix24 connection |\n\nFull list of common API errors — [Errors](\u002Fdocs\u002Ferrors).\n\n## Known specifics\n\n**The 20 slots are shared between types.** A short query without `options.types` can return 20 leads and no contacts. To find a customer, pass `types: [\"CONTACT\", \"COMPANY\"]`.\n\n**An empty `data` with a non-empty `meta.limits` does not mean there are no records.** Records of the types in `meta.limits` did not make it into the response. Find them with the list method of the relevant entity, for example [`GET \u002Fv1\u002Fcontacts`](\u002Fdocs\u002Fentities\u002Fcontacts\u002Flist) with a filter.\n\n## See also\n\n- [Get a contact](\u002Fdocs\u002Fentities\u002Fcontacts\u002Fget)\n- [Get a company](\u002Fdocs\u002Fentities\u002Fcompanies\u002Fget)\n- [Smart process types](\u002Fdocs\u002Fentities\u002Fsmart-processes)\n- [CRM search](..\u002Fcrm-search.md)\n",1794739358573]