For AI agents: markdown of this page — /docs-content-en/entities/invoices/products-get.md documentation index — /llms.txt
Invoice product rows
GET /v1/invoices/:id/products
Returns the list of product rows attached to an invoice.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
Parameterid (path) |
Typenumber | Requiredyes | DescriptionInvoice ID |
Parameterlimit (query) |
Typenumber | Requiredno | DescriptionHow 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 |
Parameteroffset (query) |
Typenumber | Requiredno | DescriptionOffset in rows, not in pages: offset=7 starts the output at the eighth row |
Without 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 invoice has in total.
Examples
curl — personal key
curl "https://vibecode.bitrix24.com/v1/invoices/741/products" \
-H "X-Api-Key: YOUR_API_KEY"
curl — OAuth application
curl "https://vibecode.bitrix24.com/v1/invoices/741/products" \
-H "X-Api-Key: YOUR_APP_KEY" \
-H "Authorization: Bearer USER_SESSION_TOKEN"
JavaScript — personal key
const res = await fetch('https://vibecode.bitrix24.com/v1/invoices/741/products', {
headers: {
'X-Api-Key': 'YOUR_API_KEY',
},
})
const { success, data } = await res.json()
console.log('Products:', data.length)
JavaScript — OAuth application
const res = await fetch('https://vibecode.bitrix24.com/v1/invoices/741/products', {
headers: {
'X-Api-Key': 'YOUR_APP_KEY',
'Authorization': 'Bearer USER_SESSION_TOKEN',
},
})
const { success, data } = await res.json()
Response fields
| Field | Type | Description |
|---|---|---|
Fieldsuccess |
Typeboolean | DescriptionAlways true on success |
Fielddata |
Typearray | DescriptionArray of product rows |
Fielddata[].id |
Typenumber | DescriptionProduct row ID. The same value appears as rowId in single-row operations |
Fielddata[].productId |
Typenumber | DescriptionProduct ID. Catalog: GET /v1/products |
Fielddata[].productName |
Typestring | DescriptionProduct name |
Fielddata[].price |
Typenumber | DescriptionPrice per unit |
Fielddata[].quantity |
Typenumber | DescriptionQuantity |
Fielddata[].discount |
Typenumber | DescriptionDiscount amount |
Fielddata[].taxRate |
Typenumber/null | DescriptionTax rate (%) |
Fielddata[].taxIncluded |
Typeboolean | DescriptionTax included in the price |
Fielddata[].ownerId |
Typenumber | DescriptionID of the owning invoice, the same one as in the request path |
Fielddata[].ownerType |
Typestring | DescriptionRow owner type, SI for an invoice |
Fielddata[].storeId |
Typenumber | null | DescriptionWarehouse ID. List: GET /v1/warehouses. null when inventory management is off |
Fieldmeta.total |
Typenumber | DescriptionHow many product rows the invoice has in total. Present when Bitrix24 returned the count, otherwise the field is absent from the response. |
Fieldmeta.hasMore |
Typeboolean | DescriptionWhether rows exist beyond the returned page. Accurate for any requested window, not just the first one |
Fieldmeta.warnings |
Typearray | DescriptionPresent only when the request carried limit=0: a single entry with code equal to LIMIT_ZERO_IGNORED |
Only the main fields are shown. The full list of 25 fields, including priceAccount and measureCode, is in Product fields.
Response example
{
"success": true,
"data": [
{
"id": 1669,
"ownerId": 741,
"ownerType": "SI",
"productId": 1,
"productName": "Server equipment",
"price": 1000,
"quantity": 2,
"discount": 0,
"taxRate": null,
"taxIncluded": false,
"storeId": null
}
],
"meta": {
"total": 1,
"hasMore": false
}
}
Error response example
404 — invoice not found:
{
"success": false,
"error": {
"code": "ENTITY_NOT_FOUND",
"message": "Item not found"
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| HTTP404 | CodeENTITY_NOT_FOUND |
DescriptionInvoice not found — the same response as GET /v1/invoices/{id} |
| HTTP403 | CodeBITRIX_ACCESS_DENIED |
DescriptionThe invoice exists but the employee's permissions restrict access to it |
| HTTP422 | CodeBITRIX_ERROR |
DescriptionThe id in the URL is not a number — message Argument '=ownerId' is required |
| HTTP403 | CodeSCOPE_DENIED |
DescriptionAPI key lacks the crm scope |
| HTTP401 | CodeTOKEN_MISSING |
DescriptionAPI key has no configured tokens |
| HTTP429 | CodeRATE_LIMITED |
DescriptionRate 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 |
For the full list of common API errors, see Errors.