Skip to content

Data model

Almost everything in BILLZ is scoped to a shop.

A catalog unit. product_type_id takes one of three values: product, service or bundle; the reference list is GET /v2/product-type. Variability is a separate flag, is_variative; both a product with variations and its variations have the type “product”.

Field Meaning
id product UUID
name, sku, barcode name, SKU, barcode
is_variative flag of a product with variations
parent_id reference to the parent for a variation; an empty string for a standalone product
product_type_id product / service / bundle (exactly three values)
categories[], brand_id classification
custom_fields[] arbitrary company-defined characteristics: custom_field_id, custom_field_name, custom_field_system_name, custom_field_value, from_parent (the value is inherited from the parent)
product_attributes[] variation attributes: attribute_id, attribute_name, attribute_value_id, attribute_value

A child product with its own barcode and set of attributes. References the parent via parent_id. The variation name is built as “parent name / attribute value / attribute value”; the original parent name is stored separately in base_name.

Grouping with group_variations=true is supported only in POST /v2/product-search-with-filters: there the parent stays in the list and the variations come nested in variations. GET /v2/products has no such parameter: variations come as a flat list.

An attribute and a custom field are different entities, although filters use the common product_field_filters parameter split by field_type: attribute or custom.

A physical point of sale. Stock, prices, cash registers, sales and warehouse processes are tied to shop_id. A user works in the context of the “current shop”.

// GET /v2/products
{
"shop_measurement_values": [
{ "shop_id": "...", "shop_name": "Nike Store", "active_measurement_value": 5 }
],
"shop_prices": [
{ "shop_id": "...", "shop_name": "Nike Store",
"retail_price": 1000000, "retail_currency": "UZS",
"supply_price": 600000, "supply_currency": "UZS",
"promo_price": 500000, "promos": [ ] }
]
}

The structure depends on the method: in POST /v2/product-search-with-filters, instead of active_measurement_value there are total_measurement_value, total_active_measurement_value, total_inactive_measurement_value, total_in_transfer_measurement_value and others.

promo_price applies only when promos is not empty; promos contains only the promotion with the lowest price.

In GET /v2/products the supply_price and supply_currency fields are zeroed out (0 and "") if the key’s role has no permission to see the cost price. In the response this is indistinguishable from a real zero cost price.

A buyer of the company: phone, cards, cashback, debts. The API has two adjacent sets of methods — client (creation and search, including by chat_id for bots) and customer (details, balance). The models are different.

Available to the integration key: POST /v1/client, GET /v1/client, PUT /v1/client/:id, POST /v1/client-card, GET /v1/client-by-chat-id, GET /v1/customer/:id, PATCH /v1/customer/set-balance/:id.

The full list of structures with a description of every field is in the API reference.