For AI agents: markdown of this page — /docs-content-en/entities/items/products-fields.md documentation index — /llms.txt

Item product fields

GET /v1/items/:entityTypeId/:id/products/fields

Returns a description of each field on an item's product rows: name, type, and whether the field is readable and writable.

The discount amount is called discount — matching the data and the write contract. 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.

Use the entityTypeId field from GET /v1/smart-processes in the /v1/items/:entityTypeId path. The type record's internal id is a different identifier. For example, if a type is returned as { "id": 3, "entityTypeId": 174 }, the path starts with /v1/items/174. Use the returned value rather than assuming all type IDs start at 1030.

Parameters

Parameter Type Required Description
ParameterentityTypeId (path) Typenumber Requiredyes DescriptionSmart process type ID
Parameterid (path) Typenumber Requiredyes DescriptionItem ID. Does not affect the response: the field dictionary is the same for every item

Examples

curl — personal key

Terminal
curl "https://vibecode.bitrix24.com/v1/items/156/741/products/fields" \
  -H "X-Api-Key: YOUR_API_KEY"

curl — OAuth application

Terminal
curl "https://vibecode.bitrix24.com/v1/items/156/741/products/fields" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN"

JavaScript — personal key

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/items/156/741/products/fields', {
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
  },
})

const { success, data } = await res.json()
console.log('Fields:', Object.keys(data).length)

JavaScript — OAuth application

javascript
const res = await fetch('https://vibecode.bitrix24.com/v1/items/156/741/products/fields', {
  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 Typeobject DescriptionProduct row field dictionary. The key is the field name, the value is its definition
Fielddata.<field>.type Typestring DescriptionValue type: integer, double, string, char
Fielddata.<field>.isReadOnly Typeboolean DescriptionRead-only: the field cannot be written
Fielddata.<field>.isRequired Typeboolean DescriptionRequired flag. false on every product-row field
Fielddata.<field>.isImmutable Typeboolean Descriptiontrue on ownerId and ownerType: the row owner is set by the request path. Absent on priceAccount and xmlId
Fielddata.<field>.isMultiple Typeboolean Descriptionfalse on product row fields. Absent on priceAccount and xmlId
Fielddata.<field>.isDynamic Typeboolean Descriptionfalse on product row fields. Absent on priceAccount and xmlId
Fielddata.<field>.title Typestring DescriptionField label. Absent on priceAccount and xmlId
Fielddata.<field>.description Typestring DescriptionField note. Present on id and discountSum
Fieldmeta.warnings Typearray DescriptionPresent only when Bitrix24 did not describe all of the fields. An item with the code fields_partial lists the fields whose definitions were derived without labels

Product row fields described by data:

Field Type RO Required Description
Fieldid Typeinteger ROyes Required DescriptionRow ID
FieldproductId Typeinteger RO Required DescriptionProduct ID. Catalog: GET /v1/products
FieldproductName Typestring RO Required DescriptionProduct name
Fieldprice Typedouble RO Required DescriptionPrice
Fieldquantity Typedouble RO Required DescriptionQuantity
Fielddiscount Typedouble RO Required DescriptionDiscount amount. Applied when discountTypeId is 1
FielddiscountSum Typedouble RO Required DescriptionDeprecated alias of discount — accepted on write, absent from product rows
FielddiscountRate Typedouble RO Required DescriptionDiscount percentage. Applied when discountTypeId is 2
FielddiscountTypeId Typeinteger RO Required DescriptionHow the discount is set: 1 — as an amount in discount, 2 — as a percentage in discountRate. Defaults to 2
FieldtaxRate Typedouble RO Required DescriptionTax (%)
FieldtaxIncluded Typechar RO Required DescriptionTax included in price (Y/N)
FieldpriceExclusive Typedouble ROyes Required DescriptionPrice excluding tax, with discount
FieldpriceNetto Typedouble ROyes Required DescriptionNet price
FieldpriceBrutto Typedouble ROyes Required DescriptionGross price
FieldmeasureCode Typeinteger RO Required DescriptionUnit of measure code
FieldmeasureName Typestring ROyes Required DescriptionUnit of measure
Fieldcustomized Typechar ROyes Required DescriptionModified (Y/N)
Fieldsort Typeinteger RO Required DescriptionSort order
Fieldtype Typeinteger ROyes Required DescriptionProduct type — the same value as the product's type in GET /v1/catalog-products/:id: 1 — simple product, 3 — parent product with variations, 7 — service
FieldstoreId Typeinteger ROyes Required DescriptionWarehouse ID
FieldtaxName Typestring ROyes Required DescriptionTax name. Present only in the dictionary, never in product rows. In a write request body it is rejected with 400 INVALID_PARAMS
FieldownerId Typeinteger ROyes Required DescriptionOwner (item) ID
FieldownerType Typestring ROyes Required DescriptionOwner type
FieldpriceAccount Typedouble ROyes Required DescriptionPrice in the reporting currency
FieldxmlId Typestring ROyes Required DescriptionExternal code of the row

Response example

The example shows 6 of the 25 fields (24 product-row field names plus the deprecated discountSum alias). The full list is in the table above.

JSON
{
  "success": true,
  "data": {
    "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 /products 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 /products/{rowId}." },
    "ownerId": { "type": "integer", "isRequired": false, "isReadOnly": true, "isImmutable": true, "isMultiple": false, "isDynamic": false, "title": "Owner ID" },
    "ownerType": { "type": "string", "isRequired": false, "isReadOnly": true, "isImmutable": true, "isMultiple": false, "isDynamic": false, "title": "Owner type" },
    "productId": { "type": "integer", "isRequired": false, "isReadOnly": false, "isImmutable": false, "isMultiple": false, "isDynamic": false, "title": "Product" },
    "price": { "type": "double", "isRequired": false, "isReadOnly": false, "isImmutable": false, "isMultiple": false, "isDynamic": false, "title": "Price" },
    "priceExclusive": { "type": "double", "isRequired": false, "isReadOnly": true, "isImmutable": false, "isMultiple": false, "isDynamic": false, "title": "Price excluding tax, with discount" }
  }
}

About id. An id supplied in the items array of PUT /v1/items/:entityTypeId/:id/products does not guarantee that the row keeps its 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 /v1/items/:entityTypeId/:id/products/:rowId.

Error response example

400 — entityTypeId in the path is not a positive integer:

JSON
{
  "success": false,
  "error": {
    "code": "INVALID_DYNAMIC_PARAM",
    "message": "Invalid entityTypeId: must be a positive integer"
  }
}

Errors

HTTP Code Description
HTTP400 CodeINVALID_DYNAMIC_PARAM DescriptionentityTypeId is not a positive integer or is reserved (1, 2, 3, 4, 7, 31)
HTTP403 CodeSCOPE_DENIED DescriptionThe API key does not have the crm scope
HTTP401 CodeMISSING_API_KEY DescriptionThe X-Api-Key header is not passed
HTTP401 CodeTOKEN_MISSING DescriptionThe API 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.

See also