[{"data":1,"prerenderedAt":7},["ShallowReactive",2],{"docs-entities\u002Fcrm-payments\u002Fproducts-add":3,"docs-tabs-entities\u002Fcrm-payments\u002Fproducts-add":6},{"content":4,"lastmod":5},"\n## Add a line item to a CRM payment\n\n`POST \u002Fv1\u002Fcrm-payments\u002F:id\u002Fproducts`\n\nAdds a line item to a CRM payment: the specified quantity taken from a product row of a CRM item, such as a deal. The payment amount is recalculated immediately.\n\nFields are passed flat at the JSON root, without a `fields` wrapper.\n\n## Parameters\n\n| Parameter | Type | Required | Description |\n|----------|-----|:-----:|---------|\n| `id` (path) | number | yes | Payment ID. Payments of a CRM item: [`GET \u002Fv1\u002Fcrm-payments`](\u002Fdocs\u002Fentities\u002Fcrm-payments\u002Flist) |\n\n## Request fields (body)\n\n| Field | Type | Required | Description |\n|------|-----|:-----:|---------|\n| `rowId` | number | yes | ID of the CRM item's product row. List: [`GET \u002Fv1\u002Fcrm-payments\u002Favailable-products`](\u002Fdocs\u002Fentities\u002Fcrm-payments\u002Favailable-products), field `productRows[].id` |\n| `quantity` | number | yes | Quantity, a positive integer. Must not exceed the row's remainder, which is the `productRows[].quantity` field in the [available product rows](\u002Fdocs\u002Fentities\u002Fcrm-payments\u002Favailable-products) |\n\n## Examples\n\n### curl — personal key\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Fcrm-payments\u002F573\u002Fproducts\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{ \"rowId\": 2357, \"quantity\": 2 }'\n```\n\n### curl — OAuth application\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Fcrm-payments\u002F573\u002Fproducts\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{ \"rowId\": 2357, \"quantity\": 2 }'\n```\n\n### JavaScript — personal key\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Fcrm-payments\u002F573\u002Fproducts', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({ rowId: 2357, quantity: 2 }),\n})\n\nconst { data } = await res.json()\nconsole.log('Line item ID:', data.id, 'payment amount:', data.payment.sum)\n```\n\n### JavaScript — OAuth application\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Fcrm-payments\u002F573\u002Fproducts', {\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({ rowId: 2357, quantity: 2 }),\n})\n\nconst { data } = await res.json()\n```\n\n## Response fields\n\nA successful response returns HTTP status `201`.\n\n| Field | Type | Description |\n|------|-----|---------|\n| `success` | boolean | `true` on success |\n| `data.id` | number | ID of the created payment line item. Passed as `itemId` to [`PATCH`](\u002Fdocs\u002Fentities\u002Fcrm-payments\u002Fproducts-update) and [`DELETE \u002Fv1\u002Fcrm-payments\u002F:id\u002Fproducts\u002F:itemId`](\u002Fdocs\u002Fentities\u002Fcrm-payments\u002Fproducts-delete) |\n| `data.payment` | object | The payment after the line item is added, with the same fields as in [`GET \u002Fv1\u002Fcrm-payments\u002F:id`](\u002Fdocs\u002Fentities\u002Fcrm-payments\u002Fget) |\n| `data.payment.id` | number | Payment ID |\n| `data.payment.sum` | number | Payment amount including the new line item |\n| `meta.readbackUnavailable` | boolean | Returned only with the value `true` when the line item was added but the payment could not be read back. In that case `data.payment` contains only `id`. Do not add the line item again. Check the line items via [`GET \u002Fv1\u002Fcrm-payments\u002F:id\u002Fproducts`](\u002Fdocs\u002Fentities\u002Fcrm-payments\u002Fproducts-list) |\n\n## Response example\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 445,\n    \"payment\": {\n      \"id\": 573,\n      \"accountNumber\": \"1035\u002F1\",\n      \"paid\": \"N\",\n      \"datePaid\": null,\n      \"empPaidId\": null,\n      \"paySystemId\": 19,\n      \"sum\": 3000,\n      \"currency\": \"USD\",\n      \"paySystemName\": \"Card payment\"\n    }\n  }\n}\n```\n\n## Error response example\n\n422 — `quantity` exceeds the product row's remainder:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"BITRIX_ERROR\",\n    \"message\": \"Not enough product to add to the payment\",\n    \"b24Code\": \"0\"\n  }\n}\n```\n\n## Errors\n\n| HTTP | Code | Description |\n|------|-----|---------|\n| 400 | `MISSING_REQUIRED_FIELDS` | The body is missing and there is no `Content-Type` header, `rowId` or `quantity` is not provided, or the value is not a positive integer, for example `1.5` |\n| 400 | `FST_ERR_CTP_EMPTY_JSON_BODY` | The `Content-Type: application\u002Fjson` header is sent with an empty body |\n| 400 | `READONLY_FIELD` | The body contains a field other than `rowId` and `quantity`, or the body is not a JSON object, for example `null` or an array |\n| 400 | `INVALID_ID` | `id` is not a positive integer |\n| 404 | `ENTITY_NOT_FOUND` | No payment with this `id`, message `Payment has not been found` |\n| 404 | `ENTITY_NOT_FOUND` | The row lookup confirmed that no product row has this `rowId`; message `Product row was not found.` in every portal language |\n| 404 | `ENTITY_NOT_FOUND` | The product row exists, but this payment cannot pay for it; message `Product was not found.` on en\u002Fde\u002Fkz portals, or a localized Russian message on ru portals (shown in the Russian documentation) |\n| 422 | `BITRIX_ERROR` | `quantity` exceeds the row's remainder, message `Not enough product to add to the payment` |\n| 422 | `BITRIX_ERROR` | Bitrix24 rejected the request. The reason is in `error.message` |\n| 422 | `BITRIX_NO_EFFECT` | The line item was not created, for example because a row with this `rowId` is already in this payment. The existing line item does not change. To change its quantity, use [`PATCH \u002Fv1\u002Fcrm-payments\u002F:id\u002Fproducts\u002F:itemId`](\u002Fdocs\u002Fentities\u002Fcrm-payments\u002Fproducts-update) |\n| 403 | `BITRIX_ACCESS_DENIED` | The key's user has no access to the CRM item or the payment in Bitrix24 |\n| 403 | `WRITE_BLOCKED_READONLY_KEY` | The key is not allowed to write |\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| 401 | `MISSING_API_KEY` | `X-Api-Key` is not provided |\n\nFull list of common API errors — [Errors](\u002Fdocs\u002Ferrors).\n\n## Known specifics\n\n**The added quantity is taken from the row's remainder.** After 2 units are added from a row of 3 units, the `quantity` of this row in the [available product rows](\u002Fdocs\u002Fentities\u002Fcrm-payments\u002Favailable-products) becomes `1`.\n\n## See also\n\n- [Available product rows](\u002Fdocs\u002Fentities\u002Fcrm-payments\u002Favailable-products)\n- [List payment line items](\u002Fdocs\u002Fentities\u002Fcrm-payments\u002Fproducts-list)\n- [Change the quantity in a line item](\u002Fdocs\u002Fentities\u002Fcrm-payments\u002Fproducts-update)\n- [Delete a line item from a payment](\u002Fdocs\u002Fentities\u002Fcrm-payments\u002Fproducts-delete)\n- [Create a CRM payment](\u002Fdocs\u002Fentities\u002Fcrm-payments\u002Fcreate)\n- [CRM payments](\u002Fdocs\u002Fentities\u002Fcrm-payments)\n","2026-10-12",{},1794739357280]