[{"data":1,"prerenderedAt":7},["ShallowReactive",2],{"docs-entities\u002Fleads\u002Fcreate":3,"docs-tabs-entities\u002Fleads\u002Fcreate":6},{"content":4,"lastmod":5},"\n## Create lead\n\n`POST \u002Fv1\u002Fleads`\n\nCreates a new lead in CRM.\n\n## Request fields (body)\n\n| Parameter | Type | Description |\n|----------|-----|---------|\n| `title` | string | Lead title |\n| `name` | string | Contact first name |\n| `lastName` | string | Contact last name |\n| `secondName` | string | Middle name |\n| `stageId` | string | Lead status — canonical name, the `statusId` alias is also accepted. Standard statuses: `NEW`, `IN_PROCESS`, `PROCESSED`. A Bitrix24 account may have its own — list: `GET \u002Fv1\u002Fstatuses?filter[entityId]=STATUS`. In the response the value is returned in the `stageId` field. Before writing, the value is matched exactly against the status dictionary — a status that does not exist is rejected with `UNKNOWN_STAGE`, and no record is created. An empty value is not checked: the lead gets the default status |\n| `opportunity` | number | Amount — canonical name, the `amount` alias is also accepted. Important: for the value to persist, pass `isManualOpportunity: true` in the same request — otherwise Bitrix24 recalculates the amount from the product rows |\n| `isManualOpportunity` | boolean | Manual amount mode (see `opportunity`) |\n| `currency` | string | Currency (alias `currencyId`). List: `GET \u002Fv1\u002Fcurrencies` |\n| `companyTitle` | string | Company name (text, not ID) |\n| `phone` | string \\| string[] \\| object[] | Phone. Accepts three forms: a string `\"+1...\"`, an array of strings `[\"+1...\", \"+1...\"]`, or an array of objects `[{ \"value\": \"+1...\", \"typeId\": \"WORK\" }, …]`. `typeId`: `WORK \\| HOME \\| MOBILE \\| OTHER` (default `WORK`). Important: the UPPER form `[{ \"VALUE\": \"...\", \"VALUE_TYPE\": \"WORK\" }]` is **not accepted** — it returns `400 INVALID_MULTIFIELD_SHAPE`. Use camelCase: `[{ \"value\": \"...\", \"typeId\": \"WORK\" }]` |\n| `email` | string \\| string[] \\| object[] | Email. Accepts three forms: a string `\"a@b.com\"`, an array of strings `[\"a@b.com\", \"b@c.com\"]`, or an array of objects `[{ \"value\": \"a@b.com\", \"typeId\": \"WORK\" }, …]`. `typeId`: `WORK \\| HOME \\| MAILING \\| OTHER` (default `WORK`). Important: the UPPER form `[{ \"VALUE\": \"...\", \"VALUE_TYPE\": \"WORK\" }]` is **not accepted** — it returns `400 INVALID_MULTIFIELD_SHAPE`. Use camelCase: `[{ \"value\": \"...\", \"typeId\": \"WORK\" }]` |\n| `post` | string | Position |\n| `comments` | string | Comment |\n| `sourceId` | string | Source. List: `GET \u002Fv1\u002Fstatuses?filter[entityId]=SOURCE` |\n| `sourceDescription` | string | Source description |\n| `assignedById` | number | Assignee. List: `GET \u002Fv1\u002Fusers` |\n| `opened` | boolean | Available to everyone |\n| `ufCrm*` | per field schema | A user field of the Bitrix24 account, for example `ufCrmProjectCode`. The actual name and type are in the schema [`GET \u002Fv1\u002Fleads\u002Ffields`](\u002Fdocs\u002Fentities\u002Fleads\u002Ffields), and the value format for each type is in [User fields (UF)](\u002Fdocs\u002Fentity-api#user-fields-uf). An `enumeration` field takes the option `ID` from the field's `items` array in the schema, and a multiple field takes an array of such `ID`s. If you send the option label `VALUE` instead of the `ID`, the value is lost: a single-value field gets `0`. A number that is not among the options is stored as is. Neither the label nor a non-existent `ID` raises an error, and the request returns `201`, so map the label to its `ID` on your side and check the stored value of this field in the response `data` |\n\nFull list of fields: [GET \u002Fv1\u002Fleads\u002Ffields](\u002Fdocs\u002Fentities\u002Fleads\u002Ffields).\n\n## Examples\n\n### curl — personal key\n\n```bash\ncurl -X POST https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Fleads \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"title\": \"Website request\",\n    \"name\": \"Maria\",\n    \"lastName\": \"Davis\",\n    \"phone\": \"+12025550123\",\n    \"sourceId\": \"WEB\",\n    \"stageId\": \"NEW\"\n  }'\n```\n\n### curl — OAuth application\n\n```bash\ncurl -X POST https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Fleads \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"title\": \"Website request\",\n    \"name\": \"Maria\",\n    \"lastName\": \"Davis\",\n    \"phone\": \"+12025550124\",\n    \"sourceId\": \"WEB\",\n    \"stageId\": \"NEW\"\n  }'\n```\n\n### JavaScript — personal key\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Fleads', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    title: 'Website request',\n    name: 'Maria',\n    lastName: 'Davis',\n    phone: '+12025550125',\n    sourceId: 'WEB',\n    stageId: 'NEW',\n  }),\n})\n\nconst { success, data } = await res.json()\nconsole.log('Lead ID:', data.id)\n```\n\n### JavaScript — OAuth application\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Fleads', {\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    title: 'Website request',\n    name: 'Maria',\n    lastName: 'Davis',\n    phone: '+12025550126',\n    sourceId: 'WEB',\n    stageId: 'NEW',\n  }),\n})\n\nconst { success, data } = await res.json()\n```\n\n### Alternative form — array of objects with explicit `typeId`\n\nIf you need to specify multiple values or an explicit type (`HOME`, `MOBILE`):\n\n```json\n{\n  \"phone\": [\n    { \"value\": \"+12025550127\", \"typeId\": \"WORK\" },\n    { \"value\": \"+12025550123\", \"typeId\": \"MOBILE\" }\n  ],\n  \"email\": [\n    { \"value\": \"work@example.com\", \"typeId\": \"WORK\" },\n    { \"value\": \"personal@example.com\", \"typeId\": \"HOME\" }\n  ]\n}\n```\n\n## Response fields\n\n| Field | Type | Description |\n|------|-----|---------|\n| `success` | boolean | `true` on successful creation |\n| `data` | object | The created lead. Full list of fields — [Lead fields](\u002Fdocs\u002Fentities\u002Fleads\u002Ffields) |\n| `data.id` | number | ID of the created lead |\n| `data.title` | string | Title |\n| `data.stageId` | string | Lead status |\n| `data.assignedById` | number | Assignee |\n| `data.createdBy` | number | Creator |\n| `data.createdTime` | datetime | Creation date |\n\nThe lead card URL in Bitrix24 is built from `data.id`:\n\n```\nhttps:\u002F\u002F\u003Cportal>.bitrix24.com\u002Fcrm\u002Flead\u002Fdetails\u002F\u003Cid>\u002F\n```\n\n`\u003Cportal>` — the Bitrix24 portal domain. Access is limited by the employee's permissions in Bitrix24.\n\n## Response example\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 5001,\n    \"title\": \"Website request\",\n    \"stageId\": \"NEW\",\n    \"assignedById\": 1,\n    \"createdBy\": 1,\n    \"createdTime\": \"2026-04-15T13:00:00+00:00\",\n    \"updatedTime\": \"2026-04-15T13:00:00+00:00\",\n    \"opened\": true,\n    \"sourceId\": \"WEB\"\n  }\n}\n```\n\n## Error response example\n\n403 — no scope:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"SCOPE_DENIED\",\n    \"message\": \"This endpoint requires 'crm' scope\"\n  }\n}\n```\n\n## Errors\n\n| HTTP | Code | Description |\n|------|-----|---------|\n| 403 | `SCOPE_DENIED` | The API key does not have the `crm` scope |\n| 401 | `TOKEN_MISSING` | The API key has no configured tokens |\n| 400 | `INVALID_MULTIFIELD_SHAPE` | Wrong shape for `phone` or `email` — the expected shape is `[{ \"value\", \"typeId\" }]`. The same code is returned when `phone` or `email` holds an object without `value` — for example empty or with keys such as `n0`, `0` or `011` — or a number or `true`\u002F`false`, on its own or as an array item, or when the raw `fm` is not an array, for example a string, a number, an empty object or an object keyed by type such as `PHONE`: `fm` is accepted only as an array `[{ \"typeId\", \"valueType\", \"value\" }]`. The request is refused and nothing is written |\n| 400 | `MULTIFIELD_ID_NOT_SUPPORTED` | `phone`, `email` or the raw `fm[]` contains an object with an `id` field. There is nothing to address on create: Bitrix24 assigns multifield row IDs itself, so the request is refused and nothing is written. The same refusal applies when `fm`, `phone` or `email` is sent as an object keyed by row IDs (`{\"fm\": {\"11\": {…}}}`) |\n| 400 | `READONLY_FIELD` | Attempt to write a read-only field |\n| 400 | `UNKNOWN_STAGE` | `stageId` \u002F `statusId` is not in the lead status dictionary (`STATUS`): a typo, wrong letter case, or a deal stage instead of a lead status. No record is created; `message` suggests the exact spelling, `details.knownStages` lists the dictionary's statuses |\n\nFull list of common API errors — [Errors](\u002Fdocs\u002Ferrors).\n\n## Known specifics\n\n**Simple CRM mode (no leads):** when the Bitrix24 account runs CRM in simple mode, Bitrix24 converts the lead right on creation — it comes back `CONVERTED` and closed, with a contact and a deal created from it that the request never asked for. The requested stage is not kept. Vibecode changes nothing in the request: this is Bitrix24's own behavior, and the mode cannot be switched through the API — only in the CRM settings. The response stays `201`, and `meta.warnings` gets a `LEAD_AUTO_CONVERTED` warning with the IDs of the contact (`contactId`) and deal (`dealId`) Bitrix24 created; `null` when the record was not created or not found: a contact you linked yourself via `contactId` is reused by Bitrix24 and does not count as created. There is no warning when `CONVERTED` was requested explicitly. On such an account, create deals and contacts directly.\n\n**Lead conversion:** Bitrix24 REST has no dedicated conversion method. To \"convert\" a lead, create a deal\u002Fcontact\u002Fcompany with `leadId` and update the lead status:\n\n```javascript\n\u002F\u002F 1. Create a deal from the lead\nawait fetch('\u002Fv1\u002Fdeals', { body: { title: 'From lead', leadId: 5001 } })\n\u002F\u002F 2. Close the lead\nawait fetch('\u002Fv1\u002Fleads\u002F5001', { method: 'PATCH', body: { statusId: 'CONVERTED' } })\n```\n\n## See also\n\n- [Working with files in CRM fields](\u002Fdocs\u002Frecipes\u002Fcrm-files)\n- [List leads](\u002Fdocs\u002Fentities\u002Fleads\u002Flist)\n- [Lead fields](\u002Fdocs\u002Fentities\u002Fleads\u002Ffields)\n- [Duplicate search](\u002Fdocs\u002Fduplicates)\n- [Deals](\u002Fdocs\u002Fentities\u002Fdeals)\n- [Entity API](\u002Fdocs\u002Fentity-api)\n- [Limits and optimization](\u002Fdocs\u002Foptimization)\n","2026-11-03",{},1794739386520]