[{"data":1,"prerenderedAt":7},["ShallowReactive",2],{"docs-entities\u002Fdeals\u002Fproducts-fields":3,"docs-tabs-entities\u002Fdeals\u002Fproducts-fields":6},{"content":4,"lastmod":5},"## Deal product fields\n\n`GET \u002Fv1\u002Fdeals\u002F:id\u002Fproducts\u002Ffields`\n\nReturns descriptions of the fields on deal product rows: names, types, and whether each field is readable and writable.\n\n> **The discount amount is called `discount`** — the same name as in the row data and on write. The previous name `discountSum` remains a deprecated alias: it is still returned by this endpoint and still accepted on write, so code written against the old field list keeps working. Product rows themselves carry only `discount` — migrate to it.\n\n## Parameters\n\n| Parameter | Type | Required | Description |\n|----------|-----|:-----:|---------|\n| `id` (path) | number | yes | Deal ID. Does not affect the response: the field dictionary is the same for every deal |\n\n## Examples\n\n### curl — personal key\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Fdeals\u002F741\u002Fproducts\u002Ffields\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\"\n```\n\n### curl — OAuth application\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Fdeals\u002F741\u002Fproducts\u002Ffields\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\"\n```\n\n### JavaScript — personal key\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Fdeals\u002F741\u002Fproducts\u002Ffields', {\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n  },\n})\n\nconst { success, data } = await res.json()\nconsole.log('Fields:', Object.keys(data).length)\n```\n\n### JavaScript — OAuth application\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Fdeals\u002F741\u002Fproducts\u002Ffields', {\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n  },\n})\n\nconst { success, data } = await res.json()\n```\n\n## Response fields\n\n| Field | Type | Description |\n|------|-----|---------|\n| `success` | boolean | Always `true` on success |\n| `data` | object | Product row field dictionary. The key is the field name; the value is its definition |\n| `data.\u003Cfield>.type` | string | Value type: `integer`, `double`, `string`, `char` |\n| `data.\u003Cfield>.isReadOnly` | boolean | Read-only: the field cannot be written |\n| `data.\u003Cfield>.isRequired` | boolean | Required flag. `false` on every product-row field: a write accepts a row that carries at least one writable field |\n| `data.\u003Cfield>.isImmutable` | boolean | `true` on `ownerId` and `ownerType`: the row owner is set by the request path. Absent on `priceAccount` and `xmlId` |\n| `data.\u003Cfield>.isMultiple` | boolean | `false` on product row fields. Absent on `priceAccount` and `xmlId` |\n| `data.\u003Cfield>.isDynamic` | boolean | `false` on product row fields. Absent on `priceAccount` and `xmlId` |\n| `data.\u003Cfield>.title` | string | Field label. Absent on `priceAccount` and `xmlId` |\n| `data.\u003Cfield>.description` | string | Field note. Present on `id` and `discountSum` |\n| `meta.warnings` | array | Present only when Bitrix24 described some of the fields but not all. An item with the code `fields_partial` lists the fields whose definitions were derived without labels |\n\nProduct row fields described by `data`:\n\n| Field | Type | RO | Required | Description |\n|------|-----|:--:|:-----:|---------|\n| `id` | integer | yes | | Row ID |\n| `productId` | integer | | | Product ID. Catalog: [`GET \u002Fv1\u002Fproducts`](\u002Fdocs\u002Fentities\u002Fproducts\u002Flist). A row without `productId` is created with `productId` set to `0` and the name from `productName` — see [Add a product](\u002Fdocs\u002Fentities\u002Fdeals\u002Fproducts-add) |\n| `productName` | string | | | Product name |\n| `price` | double | | | Price |\n| `quantity` | double | | | Quantity |\n| `discount` | double | | | Discount amount. Applied when `discountTypeId` is `1` |\n| `discountSum` | double | | | Deprecated alias of `discount` — accepted on write, absent from product rows |\n| `discountRate` | double | | | Discount percentage. Applied when `discountTypeId` is `2` |\n| `discountTypeId` | integer | | | How the discount is set: `1` — as an amount in `discount`, `2` — as a percentage in `discountRate`. Defaults to `2` |\n| `taxRate` | double | | | Tax (%) |\n| `taxIncluded` | char | | | Tax included in price. In product rows the field is returned as `true` or `false`, even though the dictionary gives its type as `char`. You can write any of the values `true`, `false`, `Y`, `N` |\n| `priceExclusive` | double | yes | | Price excluding tax, with discount |\n| `priceNetto` | double | yes | | Net price |\n| `priceBrutto` | double | yes | | Gross price |\n| `measureCode` | integer | | | Unit of measure code |\n| `measureName` | string | yes | | Unit of measure |\n| `customized` | char | yes | | Modified (`Y`\u002F`N`) |\n| `sort` | integer | | | Sort order |\n| `type` | integer | yes | | Product type — the same value as the product's `type` in `GET \u002Fv1\u002Fcatalog-products\u002F:id`: `1` — simple product, `3` — parent product with variations, `7` — service |\n| `storeId` | integer | yes | | Warehouse ID |\n| `taxName` | string | yes | | Tax name. Present only in the dictionary, never in product rows. In a write request body it is rejected with `400 INVALID_PARAMS` |\n| `ownerId` | integer | yes | | Owner (deal) ID |\n| `ownerType` | string | yes | | Owner type |\n| `priceAccount` | double | yes | | Price in the reporting currency |\n| `xmlId` | string | yes | | External code of the row |\n\n## Response example\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": { \"type\": \"integer\", \"isRequired\": false, \"isReadOnly\": true, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"ID\", \"description\": \"Row identity. Read-only as an attribute, and NOT a handle for editing: PUT \u002Fproducts does not preserve it — a row whose fields change comes back with a new id even if the previous one was sent. To edit a row and keep its id use PATCH \u002Fproducts\u002F{rowId}.\" },\n    \"ownerId\": { \"type\": \"integer\", \"isRequired\": false, \"isReadOnly\": true, \"isImmutable\": true, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"Owner ID\" },\n    \"ownerType\": { \"type\": \"string\", \"isRequired\": false, \"isReadOnly\": true, \"isImmutable\": true, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"Owner type\" },\n    \"productId\": { \"type\": \"integer\", \"isRequired\": false, \"isReadOnly\": false, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"Product\" },\n    \"productName\": { \"type\": \"string\", \"isRequired\": false, \"isReadOnly\": false, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"Product name\" },\n    \"price\": { \"type\": \"double\", \"isRequired\": false, \"isReadOnly\": false, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"Price\" },\n    \"priceExclusive\": { \"type\": \"double\", \"isRequired\": false, \"isReadOnly\": true, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"Price excluding tax, with discount\" },\n    \"priceNetto\": { \"type\": \"double\", \"isRequired\": false, \"isReadOnly\": true, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"PRICE_NETTO\" },\n    \"priceBrutto\": { \"type\": \"double\", \"isRequired\": false, \"isReadOnly\": true, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"PRICE_BRUTTO\" },\n    \"quantity\": { \"type\": \"double\", \"isRequired\": false, \"isReadOnly\": false, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"Quantity\" },\n    \"discountTypeId\": { \"type\": \"integer\", \"isRequired\": false, \"isReadOnly\": false, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"Discount type\" },\n    \"discountRate\": { \"type\": \"double\", \"isRequired\": false, \"isReadOnly\": false, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"Discount value\" },\n    \"discount\": { \"type\": \"double\", \"isRequired\": false, \"isReadOnly\": false, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"Discount amount\" },\n    \"taxRate\": { \"type\": \"double\", \"isRequired\": false, \"isReadOnly\": false, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"Tax\" },\n    \"taxIncluded\": { \"type\": \"char\", \"isRequired\": false, \"isReadOnly\": false, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"Tax included in price\" },\n    \"customized\": { \"type\": \"char\", \"isRequired\": false, \"isReadOnly\": true, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"Modified\" },\n    \"measureCode\": { \"type\": \"integer\", \"isRequired\": false, \"isReadOnly\": false, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"Unit of measure code\" },\n    \"measureName\": { \"type\": \"string\", \"isRequired\": false, \"isReadOnly\": true, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"Unit of measure\" },\n    \"sort\": { \"type\": \"integer\", \"isRequired\": false, \"isReadOnly\": false, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"Sort order\" },\n    \"type\": { \"type\": \"integer\", \"isRequired\": false, \"isReadOnly\": true, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"TYPE\" },\n    \"storeId\": { \"type\": \"integer\", \"isRequired\": false, \"isReadOnly\": true, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"STORE_ID\" },\n    \"taxName\": { \"type\": \"string\", \"isRequired\": false, \"isReadOnly\": true, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"TAX_NAME\" },\n    \"priceAccount\": { \"type\": \"double\", \"isReadOnly\": true, \"isRequired\": false },\n    \"xmlId\": { \"type\": \"string\", \"isReadOnly\": true, \"isRequired\": false },\n    \"discountSum\": { \"type\": \"double\", \"isRequired\": false, \"isReadOnly\": false, \"isImmutable\": false, \"isMultiple\": false, \"isDynamic\": false, \"title\": \"Discount amount\", \"description\": \"Deprecated alias of `discount`; kept so clients written against the previous field list keep working. Accepted on write, never present in row data — migrate to `discount`.\" }\n  }\n}\n```\n\n> **About `id`.** An `id` supplied in `PUT \u002Fv1\u002Fdeals\u002F:id\u002Fproducts` items does not guarantee the row's previous identifier: an unchanged row gets the same `id` even without this field, while a changed row gets a new one. For targeted editing, use `PATCH \u002Fv1\u002Fdeals\u002F:id\u002Fproducts\u002F:rowId`.\n\n## Error response example\n\n401 — API key not passed:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"MISSING_API_KEY\",\n    \"message\": \"API key required. Pass via X-Api-Key header.\"\n  }\n}\n```\n\n## Errors\n\n| HTTP | Code | Description |\n|------|-----|---------|\n| 403 | `SCOPE_DENIED` | API key lacks the `crm` scope |\n| 401 | `MISSING_API_KEY` | The `X-Api-Key` header is not passed |\n| 401 | `TOKEN_MISSING` | API key has no configured tokens |\n| 429 | `RATE_LIMITED` | Rate limit exceeded: 300 requests per minute per portal. All API keys of the portal share one limit. The current limit is returned in the `x-ratelimit-limit` header. Retry after the delay in the `Retry-After` header |\n\nFor the full list of common API errors, see [Errors](\u002Fdocs\u002Ferrors).\n\n## See also\n\n- [Product rows](\u002Fdocs\u002Fentities\u002Fdeals\u002Fproducts-get)\n- [Add a product](\u002Fdocs\u002Fentities\u002Fdeals\u002Fproducts-add)\n- [Set products](\u002Fdocs\u002Fentities\u002Fdeals\u002Fproducts-set)\n- [Deal fields](\u002Fdocs\u002Fentities\u002Fdeals\u002Ffields)\n","2026-11-10",{},1794739368973]