For AI agents: markdown of this page — /docs-content-en/entities/leads/products-update.md documentation index — /llms.txt
Update a lead product
PATCH /v1/leads/:id/products/:rowId
Updates a lead product row. Pass only the fields you want to change.
Field names are validated. A field name that is not in the writable set is not dropped silently: the request is rejected with
400 INVALID_PARAMSand the error text lists the writable names. Read-only fields that appear in product-row responses —priceAccount,ownerId,storeIdand others — are accepted and ignored, so an object read viaGETcan be sent back as is.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
Parameterid (path) |
Typenumber | Requiredyes | DescriptionLead ID. List: GET /v1/leads |
ParameterrowId (path) |
Typenumber | Requiredyes | DescriptionProduct row ID, not the catalog productId. List: GET /v1/leads/:id/products |
Request fields (body)
| Field | Type | Required | Description |
|---|---|---|---|
Fieldprice |
Typenumber | Requiredno | DescriptionUnit price |
Fieldquantity |
Typenumber | Requiredno | DescriptionQuantity |
FieldproductId |
Typenumber | Requiredno | DescriptionProduct ID. Catalog: GET /v1/products |
FieldproductName |
Typestring | Requiredno | DescriptionRow name |
FielddiscountTypeId |
Typenumber | Requiredno | DescriptionHow the discount is set: 1 — as an amount in discount, 2 — as a percentage in discountRate. Omitting the field keeps the row's current value — to switch the discount mode, send it explicitly |
Fielddiscount |
Typenumber | Requiredno | DescriptionDiscount amount. Applied only when discountTypeId is 1 |
FielddiscountRate |
Typenumber | Requiredno | DescriptionDiscount percentage. Applied only when discountTypeId is 2 |
FieldtaxRate |
Typenumber | Requiredno | DescriptionTax rate (%) |
FieldtaxIncluded |
Typeboolean | Requiredno | DescriptionTax included in the price |
FieldmeasureCode |
Typenumber | Requiredno | DescriptionUnit of measure code, for example 796 — piece. List: GET /v1/catalog-measures |
Fieldsort |
Typenumber | Requiredno | DescriptionSort order |
Examples
curl — personal key
curl -X PATCH "https://vibecode.bitrix24.com/v1/leads/1001333/products/2385" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "price": 9999, "quantity": 10 }'
curl — OAuth application
curl -X PATCH "https://vibecode.bitrix24.com/v1/leads/1001333/products/2385" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "price": 9999, "quantity": 10 }'
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/leads/1001333/products/2385', {
method: 'PATCH',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({ price: 9999, quantity: 10 }),
})
const { success, data } = await res.json()
console.log('Updated:', data.price, 'x', data.quantity)
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/leads/1001333/products/2385', {
method: 'PATCH',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({ price: 9999, quantity: 10 }),
})
const { success, data } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
Fieldsuccess |
Typeboolean | DescriptionAlways true on success |
Fielddata |
Typeobject | DescriptionThe full updated product row (id stays the same). Row fields — see Product fields |
Response example
{
"success": true,
"data": {
"id": 2385,
"ownerId": 1001333,
"ownerType": "L",
"productId": 6967,
"productName": "Parent product",
"price": 9999,
"priceAccount": 9999,
"priceExclusive": 9999,
"priceNetto": 9999,
"priceBrutto": 9999,
"quantity": 10,
"discountTypeId": 2,
"discountRate": 0,
"discount": 0,
"taxRate": null,
"taxIncluded": false,
"customized": "Y",
"measureCode": 796,
"measureName": "pcs",
"sort": 0,
"xmlId": "",
"type": 3,
"storeId": null
}
}
Error response example
404 — row not found:
{
"success": false,
"error": {
"code": "ENTITY_NOT_FOUND",
"message": "Item not found"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| HTTP400 | CodeINVALID_PARAMS |
DescriptionThe body contains a field name that is not among the writable fields — see Product fields |
| HTTP400 | CodeINVALID_PARAMS |
DescriptionThe body carries no writable product-row field — an empty object, or read-only fields only. The error text lists the writable names |
| HTTP400 | CodeINVALID_ROW_ID |
DescriptionrowId in the path is not a positive integer. The message is Product row ID must be a positive integer |
| HTTP404 | CodeENTITY_NOT_FOUND |
DescriptionNo product row with this rowId. The message is Item not found |
| HTTP404 | CodeENTITY_NOT_FOUND |
DescriptionA row with this rowId exists but belongs to another CRM record, not to lead id, or carries no owner and cannot pass the check. The message is Product row not found |
| HTTP403 | CodeWRITE_BLOCKED_READONLY_KEY |
DescriptionThe key is read-only — see access rights |
| HTTP403 | CodeSCOPE_DENIED |
DescriptionThe API key lacks the crm scope |
| HTTP401 | CodeTOKEN_MISSING |
DescriptionThe API key has no configured tokens |
Full list of common API errors — Errors.