[{"data":1,"prerenderedAt":7},["ShallowReactive",2],{"docs-entities\u002Fdeals\u002Fproducts-get":3,"docs-tabs-entities\u002Fdeals\u002Fproducts-get":6},{"content":4,"lastmod":5},"\n## Deal product rows\n\n`GET \u002Fv1\u002Fdeals\u002F:id\u002Fproducts`\n\nReturns the list of product rows attached to a deal.\n\n## Parameters\n\n| Parameter | Type | Required | Description |\n|----------|-----|:-----:|---------|\n| `id` (path) | number | yes | Deal ID |\n| `limit` (query) | number | no | How many rows to return per call, from 1 to 5000, 50 by default. A value above 5000 is clamped to 5000. `limit=0` is not a page size: the default applies and `meta.warnings` carries an entry with code `LIMIT_ZERO_IGNORED` |\n| `offset` (query) | number | no | Offset in rows, not in pages: `offset=7` starts the output at the eighth row |\n\nWithout `limit` and `offset` the endpoint returns the first page of results. `meta.hasMore` tells you whether rows exist beyond it, and `meta.total` how many the deal has in total.\n\n## Examples\n\n### curl — personal key\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Fdeals\u002F741\u002Fproducts\" \\\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\" \\\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', {\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n  },\n})\n\nconst { success, data } = await res.json()\nconsole.log('Products:', data.length)\n```\n\n### JavaScript — OAuth application\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.com\u002Fv1\u002Fdeals\u002F741\u002Fproducts', {\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` | array | Array of product rows. All row fields — [Product fields](\u002Fdocs\u002Fentities\u002Fdeals\u002Fproducts-fields) |\n| `meta.total` | number | How many product rows the deal has in total. Present when Bitrix24 returned the count, otherwise the field is absent from the response. |\n| `meta.hasMore` | boolean | Whether rows exist beyond the returned page. Correct for any requested window, not only the first one |\n| `meta.warnings` | array | Present only when the request carried `limit=0`: a single entry with `code` equal to `LIMIT_ZERO_IGNORED` |\n\n`data[].id` is the product row ID, the same value used as `rowId` in single-row operations. `data[].ownerId` matches the deal ID from the request path, and `data[].ownerType` is `D` for a deal. `data[].taxIncluded` is returned as a `boolean`. `data[].storeId` is a warehouse ID from [`GET \u002Fv1\u002Fwarehouses`](\u002Fdocs\u002Fentities\u002Fwarehouses\u002Flist), or `null` when inventory management is off.\n\n## Response example\n\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 1663,\n      \"ownerId\": 741,\n      \"ownerType\": \"D\",\n      \"productId\": 1,\n      \"productName\": \"Server equipment\",\n      \"price\": 1000,\n      \"quantity\": 2,\n      \"discount\": 0,\n      \"taxRate\": null,\n      \"taxIncluded\": false,\n      \"storeId\": null\n    }\n  ],\n  \"meta\": {\n    \"total\": 1,\n    \"hasMore\": false\n  }\n}\n```\n\n## Error response example\n\n404 — deal not found:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"ENTITY_NOT_FOUND\",\n    \"message\": \"Item not found\"\n  }\n}\n```\n\n## Errors\n\n| HTTP | Code | Description |\n|------|-----|---------|\n| 404 | `ENTITY_NOT_FOUND` | Deal not found |\n| 403 | `SCOPE_DENIED` | API key lacks the `crm` scope |\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- [Set products](\u002Fdocs\u002Fentities\u002Fdeals\u002Fproducts-set)\n- [Get a deal](\u002Fdocs\u002Fentities\u002Fdeals\u002Fget)\n- [CRM products](\u002Fdocs\u002Fentities\u002Fproducts)\n- [Limits and optimization](\u002Fdocs\u002Foptimization)\n","2026-10-23",{},1794739369123]