Skip to content

Changelog

2026-10-20

  • Products — new PUT /products/{id} and PUT /products change only the fields you send: name, description, category, brand, barcode, unit, extra (merged into the product's additional fields) and stock per warehouse. See Updating products.
  • Products (breaking) — POST /products now only creates: id in the body is a 422, an existing product with the same sku/barcode is a 409 with details.product_id, and an error in the request creates nothing. Previously such a request answered 201 and could leave the product unchanged. See Creating products.
  • POST /product_stock — takes cost_price; "price": 0 is now saved. updated in the answer is the list of product ids.

2026-10-19

  • Promotions — product stock has a new promotion field: the promotion applied to the product in the warehouse, including one on an additional price (price_type; price before and after it, its end). promotion_id in a sale item counts the sale towards the promotion in HugeProfit; the price of such an item may be omitted — we fill in the promotion price. New promotion_* error codes. See Sale with a promotion.
  • Products — a promotion price in sale_price now has two decimals ("5.40", not "5.4").
  • Sales — all request fields of POST/PUT /sales are now documented in one block; PUT replaces the sale as a whole. See Sales.

2026-10-17

  • Courier delivery (Nova Poshta) — the sale's delivery takes a courier address (settlement_ref, street, house, flat), and POST /sales/{id}/waybill sends the parcel to the door. New lookups GET /delivery/settlements and GET /delivery/streets. See Delivery.

2026-10-16

  • Nova Poshta waybills — new POST /sales/{id}/waybill creates a waybill through the connected Nova Poshta account (cash on delivery, declared value, payer, parcel size) and saves its number to the sale; new delivery:write scope. See Nova Poshta waybill.
  • Sales — new delivery field saves the client's Nova Poshta branch address with the sale; client_delivery_id, delivery_info and tracking_number are now documented. See Sales.
  • Reference — Nova Poshta carrier_accounts list their senders. See Reference.
  • Safe retries of POST /sales — new external_id field (your order number): a repeat with the same number creates no second sale and answers 409 with details.sale_id; new GET /sales?external_id= filter; the number comes in the sale object and in the order_* webhooks. See Repeating a request safely.
  • Sales — amount is no longer required and is counted from the items; if passed, it must equal the items' sum, otherwise 422 with details.expected. sale_amount defaults to amount minus the discount (the discount used to be ignored). Non-numeric or too large amounts, quantities and discounts are a 422 (they used to be a 500 or a silent zero). Not enough stock — 422 with details.shortages.
  • Fixed — PUT /sales returns the sale's new id (an edit re-creates the sale under a new id), not the old one.
  • Polling for changes — updated_from/updated_to filters on GET /sales and in /query; after_id pages on past the last sale you got. See Sales.
  • Webhooks — order_update now also fires when the status changes (delivery tracking included) and when a waybill is added; data carries status, tracking_number, external_id, previous_status, previous_id. See Webhooks.
  • Waybill label — new GET /sales/{id}/waybill/label returns a PDF. See Waybill label.
  • Products — sku and barcode filters (up to 500 comma-separated values) on GET /products and in /query.
  • Delivery — GET /delivery/warehouses: exact number filter, sorted by number, limit up to 500.
  • Errors — errors that used to carry a code like NotCorrectInstockError now carry the stable codes from the table: a rejected operation is a 422 validation_error, a reached plan limit — the new 403 limit_exceeded.

2026-10-07

  • Rate limits — each key may make 120 requests per minute; responses carry X-RateLimit-* headers, and over the limit the API answers 429 with Retry-After. See Rate limits.

2026-10-06

  • Shipments — new payments list: every payment for the goods with its date, including deferred and partial ones. See Shipments.
  • Expenses — new shipment_id filter on GET /expenses and in /query; without dates it returns all payments of the shipment regardless of date. See Expenses.
  • Products — type now also returns bundle and service (they used to come as simple); bundles carry their composition in bundle_items; new GET /products/{id}/similar; image URLs end with a ?c= version that changes when a photo is replaced. See Products.
  • Orders — GET /orders/{id} returns tracking_number and sale_status; new PUT /orders/{id} cancels an order created by the same key (releasing its reserved stock) or sets its order_text. See Orders.
  • Delivery — Nova Poshta and Meest city and branch lookups: GET /delivery/cities, GET /delivery/warehouses. See Delivery.
  • Reference — new carrier_accounts section: the connected delivery services, whose id is the account_id for Meest lookups. See Reference.
  • Media — image hosting: POST /media uploads images and returns public links, GET /media lists the account's files. See Media.
  • Productions — new POST /productions/{id}/run runs a recipe: writes the components off, adds the results to stock, records the expenses. See Running a recipe.
  • Write-offs — new POST /write_offs writes goods off a warehouse in one call; categories are in write_off_categories of /reference. See Write-offs.
  • Fixed — stock changed through POST /product_stock now reaches the connected marketplaces.

2026-10-05

  • Webhooks — url must point to a public http(s) host: localhost and private-network addresses are rejected with 422 (also in /webhooks/test), and redirects are no longer followed. See Subscriptions.

2026-09-30

  • Clients — search by phone on GET /clients and in /query: phone now matches the whole number in any notation (380671234567, 0671234567, +38 (067) 123-45-67), and the new phone_contains filter finds clients whose number contains the given digits (at least 3). See Clients.

2026-09-17

  • Clients — new with_chats=telegram filter on GET /clients, GET /clients/{id} and in /query: embeds the client's messenger chats as a chats array (type, integration_id, chat_id). See Clients.

v2.0 — initial release

The v2 public API launches alongside v1 (/bapi), which continues to work unchanged.

  • Clean, stable schema — de-prickled field names, one response envelope, nested items.
  • Resources — reference, warehouses, suppliers, products (+ stock, sync), categories, clients (+ tags), sales, marketplace orders, shipments, expenses, productions.
  • Composite /query — fetch many resources in one call, with per-resource ?include=.
  • Native webhooks — durable delivery queue, HMAC signatures, retries with backoff, a delivery journal and a synchronous /webhooks/test.
  • Hashed API keys with scopes; GET /me introspection.

Not yet exposed

Production runs (inventory execution) are not available through the API yet — recipes can be created and read, but not executed.