For AI agents: markdown of this page — /docs-content-en/entities/catalog-offers/update.md documentation index — /llms.txt
Update an offer
PATCH /v1/catalog-offers/:id
Updates an existing product offer. Fields are passed flat at the JSON root; pass only the ones you change — the rest keep their current values.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id (path) |
number | yes | Offer identifier. List: GET /v1/catalog-offers |
Request fields (body)
The main updatable fields are name, active, purchasingPrice, and quantity.
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | no | Offer name |
active |
boolean | no | Whether the offer is active |
iblockSectionId |
number | no | Catalog section ID. List: GET /v1/catalog-sections |
measure |
number | no | Unit of measure ID. List: GET /v1/catalog-measures |
weight |
number | no | Weight of one product unit |
vatIncluded |
boolean | no | VAT included in the price |
canBuyZero |
boolean | no | Allow purchase when stock is zero |
quantityTrace |
boolean | no | Enable quantity tracking |
subscribe |
boolean | no | Allow subscription to the product |
barcodeMulti |
boolean | no | Separate barcodes for product units |
withoutOrder |
boolean | no | Available for ordering without stock on hand |
purchasingPrice |
number | no | Purchase price |
purchasingCurrency |
string | no | Purchase price currency. List: GET /v1/currencies |
quantity |
number | no | Stock on hand |
quantityReserved |
number | no | Reserved quantity |
code |
string | no | Symbolic code |
xmlId |
string | no | External code |
sort |
number | no | Sort order |
vatId |
number | no | VAT rate ID. List: GET /v1/catalog-vat-rates |
height |
number | no | Height |
length |
number | no | Length |
width |
number | no | Width |
dateActiveFrom |
datetime | no | Activity start |
dateActiveTo |
datetime | no | Activity end |
previewText |
string | no | Preview text |
detailText |
string | no | Detailed description |
previewTextType |
string | no | Preview text format: text or html |
detailTextType |
string | no | Detailed description format: text or html |
previewPicture |
object | no | Preview image |
detailPicture |
object | no | Detailed image |
iblockSection |
object | no | Array of IDs of the catalog sections the offer belongs to. List: GET /v1/catalog-sections |
recurSchemeLength |
number | no | Payment period length. Only for on-premise Bitrix24 when selling content |
recurSchemeType |
string | no | Payment period unit: H, D, W, M, Q, S, Y. Only for on-premise Bitrix24 when selling content |
trialPriceId |
number | no | ID of the trial payment product. Only for on-premise Bitrix24 when selling content |
propertyNNN |
object/array | no | Catalog property value, where NNN is the property ID. Catalog properties are listed in GET /v1/catalog-offers/fields?iblockId=<id> |
The body must contain at least one writable field. An empty PATCH is rejected with 400 EMPTY_UPDATE_BODY, and a body with only unknown field names is rejected with 400 NO_RECOGNIZED_UPDATE_FIELDS.
The parentId, iblockId and type fields are not accepted on update: the link to the parent product and the catalog are set at creation, and Bitrix24 computes the type. Fields with readonly: true in Offer fields, for example available, are filled by the system. A body with any of these fields is rejected with 400 READONLY_FIELD.
Examples
curl — personal key
curl -X PATCH "https://vibecode.bitrix24.com/v1/catalog-offers/7191" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"purchasingPrice": 470
}'
curl — OAuth application
curl -X PATCH "https://vibecode.bitrix24.com/v1/catalog-offers/7191" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"purchasingPrice": 470
}'
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/catalog-offers/7191', {
method: 'PATCH',
headers: {
'X-Api-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
purchasingPrice: 470,
}),
})
const { success, data } = await res.json()
console.log('Purchase price:', data.purchasingPrice)
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/catalog-offers/7191', {
method: 'PATCH',
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
purchasingPrice: 470,
}),
})
const { success, data } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true on success |
data |
object | Full object of the updated offer. The field set is the same as in GET /v1/catalog-offers/:id |
Response example
The main fields are shown.
{
"success": true,
"data": {
"id": 7191,
"iblockId": 27,
"name": "Basic T-shirt, size M",
"parentId": { "value": "7189", "valueId": "3895" },
"type": 4,
"active": true,
"available": true,
"measure": 9,
"purchasingPrice": 470,
"purchasingCurrency": "USD",
"quantity": null,
"dateCreate": "2026-10-08T18:41:55.000Z",
"timestampX": "2026-10-08T18:41:59.000Z"
}
}
Error response example
404 — no offer with the specified id exists:
{
"success": false,
"error": {
"code": "ENTITY_NOT_FOUND",
"message": "offer does not exist."
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 404 | ENTITY_NOT_FOUND |
No record with the specified id exists (offer does not exist.) |
| 422 | BITRIX_ERROR |
The id belongs to a regular product, not an offer (productType is not allowed for this catalog) |
| 400 | EMPTY_UPDATE_BODY |
The request body is empty — pass at least one field |
| 400 | NO_RECOGNIZED_UPDATE_FIELDS |
The body has no recognized writable field. The message lists the allowed ones |
| 400 | READONLY_FIELD |
The body contains a field that is not accepted on update: parentId, iblockId, type or a read-only field, for example available |
| 403 | SCOPE_DENIED |
The key lacks the catalog scope |
| 401 | MISSING_API_KEY |
The X-Api-Key header was not passed |
Full list of common API errors — Errors.
Known specifics
An offer cannot be moved to another parent product. parentId is set only at creation. To link the offer to another parent product, recreate it with the required parentId and delete the old one.