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 |
|---|---|---|---|
id (path) |
number | yes | Lead ID. List: GET /v1/leads |
rowId (path) |
number | yes | Product row ID, not the catalog productId. List: GET /v1/leads/:id/products |
Request fields (body)
| Field | Type | Required | Description |
|---|---|---|---|
price |
number | no | Unit price |
quantity |
number | no | Quantity |
productId |
number | no | Product ID. Catalog: GET /v1/products |
productName |
string | no | Row name |
discountTypeId |
number | no | How 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 |
discount |
number | no | Discount amount. Applied only when discountTypeId is 1 |
discountRate |
number | no | Discount percentage. Applied only when discountTypeId is 2 |
taxRate |
number | no | Tax rate (%) |
taxIncluded |
boolean | no | Tax included in the price |
measureCode |
number | no | Unit of measure code, for example 796 — piece. List: GET /v1/catalog-measures |
sort |
number | no | Sort 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 |
|---|---|---|
success |
boolean | Always true on success |
data |
object | The 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 |
|---|---|---|
| 400 | INVALID_PARAMS |
The body contains a field name that is not among the writable fields — see Product fields |
| 400 | INVALID_PARAMS |
The body carries no writable product-row field — an empty object, or read-only fields only. The error text lists the writable names |
| 400 | INVALID_ROW_ID |
rowId in the path is not a positive integer. The message is Product row ID must be a positive integer |
| 404 | ENTITY_NOT_FOUND |
No product row with this rowId. The message is Item not found |
| 404 | ENTITY_NOT_FOUND |
A 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 |
| 403 | WRITE_BLOCKED_READONLY_KEY |
The key is read-only — see access rights |
| 403 | SCOPE_DENIED |
The API key lacks the crm scope |
| 401 | TOKEN_MISSING |
The API key has no configured tokens |
Full list of common API errors — Errors.