Api documentation
This is just api documentation. All api work on REST API technology.
Root URL api: https://crm.h-profit.com/bapi/
All requests should be sent with these http headers:
AuthorizationExample:VWR2bQm7BzdJ7EEi0qYjJORK5BTelPez
Content-Type:application/json
These should be attached to each request!
Requests and responses
GETparameters go in the query string, the other methods take a JSON body. Parameters ofPOST,PUTandDELETEmay also be passed in the query string.- A successful response always contains
"success": trueplus the fields described for the endpoint. - An error comes as
{"success": false, "error": "<text>"}, sometimes withinfo(details). HTTP status —400,403,404or429. - Dates in responses are UNIX timestamps unless stated otherwise.
- Request limits per minute — see Rate limits.
Common errors:
error |
Status | Reason |
|---|---|---|
not-correct-api-key |
403 | The Authorization key is missing or wrong |
integration-disabled-or-not-found |
403 | The API integration is turned off or deleted in HugeProfit |
rate-limit-exceeded |
429 | Too many requests, see Rate limits |
not correct json |
400 | The request body is not valid JSON |
Products
Product api is work in GET and POST
URL - /bapi/products
Get products GET
Retrieve a list of products. Only products present on the warehouses available to the API key are returned.
Request query:
| Parameter | Type | Required | Description |
|---|---|---|---|
limit |
int | no | Page size. Default 500 |
offset |
int | no | Offset. Default 0 |
product_id |
int | no | One product |
pids |
string | no | Several products: 92967,5433,5343. Variations come with their parent product and all its other variations, grouped together |
sku |
string | no | Products with this article (SKU). No match — empty data |
category_id |
int | no | Products of this category. Applied to the page already selected by limit / offset, so a page may contain fewer products |
warehouse_id |
int | no | Stock of this warehouse only |
modify_start |
int | no | Products changed after this moment, UNIX timestamp. Only together with modify_end |
modify_end |
int | no | Products changed before this moment, UNIX timestamp. Only together with modify_start |
count |
int | no | 1 — return only the number of products: {"total": 90} (without success) |
Errors: Invalid pids format, Empty pids list.
Response fields
data is a list of products:
| Field | Type | Description |
|---|---|---|
id |
int | Product ID |
name |
string | Name |
type_product |
int | 1 — simple, 2 — variable (parent of variations), 3 — bundle, 4 — service |
parent_id |
int | Only for a variation: ID of the parent product |
brand |
object | {"id", "name"} or {} |
category |
array | Category chain from the product category up to the root: [{"id", "name", "parent_id"}] |
attr |
array | Attributes: [{"id", "name", "value"}] |
af |
object / null | Additional fields: {"Field name": "value"} |
description |
string / null | Description |
images |
array | Image URLs |
size |
string | Size |
unit |
string | Unit of measure. Default units |
sku |
string | Article: the first non-empty one among the warehouses |
barcode |
string / null | Barcode |
remote_id |
string | ID of the product in your system, if a link exists (see Product Sync) |
stock |
array | Stock by warehouse, see below |
stock[]:
| Field | Type | Description |
|---|---|---|
id |
int | ID of the stock record |
mid |
int | Warehouse ID |
name |
string | Warehouse name |
instock |
number | Available stock (without reserve) |
quantity |
number | Physical stock |
net_price |
number | Cost price |
price |
number | Sale price |
sale_price |
number | Same as price; does not include the promotion |
sku |
string | Article on this warehouse |
promotion |
object / null | Current promotion, see Promotion on a warehouse |
Example response
{
"success": true,
"data": [
{
"id": 98598,
"name": "GA&MA Сімпл гель 047 Амбер 15мл",
"brand": {
"name": "GA&MA",
"id": 6148
},
"category": [
{
"id": 18183,
"name": "Гелі",
"parent_id": 18179
},
{
"id": 18179,
"name": "Нігті",
"parent_id": null
}
],
"attr": [],
"af": null,
"description": null,
"images": [
"https://crm.h-profit.com/bimages/get/0-6578-877855-0.jpg"
],
"size": "xxx",
"unit": "units",
"sku": "4134804",
"barcode": null,
"stock": [
{
"id": 85608,
"mid": 8584,
"name": "hp_client",
"instock": 0,
"quantity": 0,
"net_price": 0,
"price": 60.0000,
"sale_price": 60.0000,
"sku": "4134804",
"promotion": {
"id": 12,
"name": "Autumn sale",
"discount_type": "percent",
"discount_value": 10.00,
"price_type": null,
"price_before": 60.00,
"price": 54.00,
"ends_at": 1793483999
}
}
],
"type_product": 1
}
]
}
Promotion on a warehouse
stock[].promotion is the promotion currently applied to the product in this warehouse, or null:
| Field | Description |
|---|---|
id |
Promotion ID — send it as promotion_id of a sale item, see Sale with a promotion |
name |
Promotion name |
discount_type |
percent — percentage discount, fixed — fixed amount off, new_price — new price |
discount_value |
Discount size or the new price |
price_type |
Which price the promotion is based on: null — the main price, otherwise the additional price name ("Wholesale") |
price_before |
Price without the promotion: the main price or that additional price of the product |
price |
Promotion price: show it to the buyer and send it in the sale |
ends_at |
Promotion end, UNIX timestamp; null — no end date |
This is the promotion HugeProfit fills in on its sale form: the highest-priority one among promotions on the main price, or, if there are none, among promotions on additional prices. A promotion on an additional price is computed from that price's value in the product; if the product has no such price, there is no promotion either. A promotion appears here only if it lowers the price. Promotion changes show up here with a delay of up to a minute. sale_price does not include the promotion.
Update products POST
Create new products or edit existing ones. Body: {"data": [...]}, up to 500 products per request.
Product fields:
| Field | Type | Required | Description |
|---|---|---|---|
id |
int | no | ID of the product to edit. Without it a new product is created |
name |
string | yes | Name, at least 2 characters (a product with a shorter name is skipped), up to 200 |
category |
string / array | no | Category path from the root: "Clothes//Hoodies" or ["Clothes", "Hoodies"] (items may be {"name": "..."}). Missing categories are created. Empty — the general category |
brand |
string | no | Brand name; a new brand is created |
description |
string | no | Description |
images |
array | no | Image URLs |
unit |
string | no | Unit of measure. Default units |
sku |
string | no | Article |
barcode |
string | no | Barcode, up to 20 characters |
af |
array | no | Additional fields: [{"name": "Material", "value": "Cotton"}]. A new name becomes a new additional field |
attr |
array | no | Attributes: [{"name": "Color", "value": "Red"}]. Ignored when variations are sent |
remote_id |
string | no | ID of the product in your system. Without id, a product already linked to this remote_id is edited; a new product is linked to it. Links are returned in sync |
stock |
array | no | Stock and prices by warehouse, see below |
variations |
array | no | Variations of a variable product, see below |
stock[]:
| Field | Type | Required | Description |
|---|---|---|---|
marketplace_id |
int | one of the two | Warehouse ID (warehouses in Reference) |
warehouse_name |
string | one of the two | Warehouse name; if there is no such warehouse, it is created |
quantity |
number | no | Physical stock |
instock |
number | no | Available stock |
net_price |
number | no | Cost price |
price |
number | no | Sale price |
variations[] — the product becomes variable: the first item gives the article, prices and attributes of the main
product, the next items become its variations (all with the stock warehouses of the product):
| Field | Type | Required | Description |
|---|---|---|---|
sku |
string | no | Variation article |
remote_id |
string | no | Variation ID in your system |
price |
number | no | Sale price |
net_price |
number | no | Cost price |
attributes |
array | no | What distinguishes the variation: [{"name": "Size", "value": "XL"}] |
Response:
| Field | Type | Description |
|---|---|---|
data |
array | IDs of the created / edited products |
sync |
object | {"<remote_id>": <product id>} — links created by remote_id |
errors |
array | Errors of individual products, e.g. Warehouse <id> is not access |
Errors of the whole request: no data (empty data), more then 500 products.
Example request
{
"data": [
{
"name": "New good",
"brand": "",
"category": "Best category//Hoodies",
"description": "Description for this good",
"unit": "шт",
"sku": "New_product_565",
"barcode": "675544998867",
"remote_id": "A-565",
"af": [
{"name": "Material", "value": "Cotton"}
],
"stock": [
{
"marketplace_id": 546,
"instock": 6,
"quantity": 6,
"net_price": 98,
"price": 140
}
]
},
{
"name": "T-shirt",
"category": ["Clothes", "T-shirts"],
"stock": [
{"warehouse_name": "Main", "quantity": 0, "price": 300}
],
"variations": [
{
"sku": "TS-S",
"remote_id": "TS-S",
"price": 300,
"net_price": 150,
"attributes": [{"name": "Size", "value": "S"}]
},
{
"sku": "TS-M",
"remote_id": "TS-M",
"price": 300,
"net_price": 150,
"attributes": [{"name": "Size", "value": "M"}]
}
]
}
]
}
Example response
{
"success": true,
"data": [64857, 64858],
"sync": {
"A-565": 64857
}
}
Product Stock
URL - /bapi/product_stock
Update product stocks POST
The convenience of this handler is that you only need to pass the product id, warehouse, and the quantity, price and/or cost price.
The body is an array of elements:
| Field | Type | Required | Description |
|---|---|---|---|
product_id |
int | yes | Product ID |
marketplace_id |
int | yes | Warehouse ID; warehouse is an alias |
quantity |
number | one of the three | New stock |
price |
number | one of the three | New sale price |
net_price |
number | one of the three | New cost price, greater than 0 |
comment |
string | no | Shown in the product history |
net_price can't be set when the cost price on this warehouse is taken from a supply or is made up of several
cost items — the whole element is rejected with an error.
Response: success_updated_products — IDs of updated products; errors — [{"product_id", "message"}] for
rejected elements. If the body is not a non-empty array — {"success": false, "error": "Wrong structure"}.
Example request
[
{
"product_id": 58218,
"marketplace_id": 8521,
"quantity": 16,
"price": 299.99,
"net_price": 180.5,
"comment": ""
}
]
Example response
{
"success": true,
"errors": [
{
"product_id": 582187,
"message": "no found product"
}
],
"success_updated_products": [
58218
]
}
Possible errors in errors[].message:
message |
Reason |
|---|---|
not valid product_id |
Incorrect product identifier |
not valid marketplace_id |
Incorrect warehouse identifier |
marketplace_id {} not found |
This warehouse was not found |
marketplace_id {} is no access |
No access to this warehouse |
quantity not valid |
The quantity value is incorrect |
price not valid |
The price value is incorrect |
net_price not valid |
The cost price is not a number or is not greater than 0 |
net_price is set by shipment or cost items |
The cost price on this warehouse comes from a supply or from several cost items |
quantity, price or net_price should be provided |
None of quantity, price or net_price is provided |
no found product |
This product was not found |
Product Categories
URL - /bapi/product_categories
Get categories GET
Retrieve a list of product categories.
| Parameter | Type | Required | Description |
|---|---|---|---|
category_id |
int | no | Return only this category |
data[]: id, name, parent_id (0 or null — root category), types, created_at (date string).
Example response
{
"success": true,
"data": [
{
"id": 17497,
"user_id": 11,
"name": "Іграшки",
"types": 1,
"created_at": "2024-09-02 06:42:20",
"parent_id": 0
},
{
"id": 17498,
"user_id": 11,
"name": "Інше",
"types": 1,
"created_at": "2024-09-02 06:42:30",
"parent_id": 0
}
]
}
Create and edit categories POST
Body: {"categories": [...]}.
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | yes | Category name |
parent_id |
int / null | yes | Parent category; null — root category |
id |
int | no | ID of the category to edit. Without it a new category is created |
An element without name or parent_id is skipped. Response data[]: {"status": "ok", "name", "cid"}, where
cid is the category ID.
Note. A category name is unique within its parent, case-insensitive: "Hoodies" may exist both in "Men" and "Women". Creating a name that is already taken in the same parent returns the
cidof the existing category. Renaming or moving a category to a parent that already has this name, or under its own subcategory, returns an error.
Example request
{
"categories": [
{
"name": "Test product category",
"parent_id": null
},
{
"id": 67,
"name": "Games (SEGA)",
"parent_id": 34
}
]
}
Example response
{
"success": true,
"data": [
{
"status": "ok",
"name": "Test product category",
"cid": 87
},
{
"status": "ok",
"name": "Games (SEGA)",
"cid": 67
}
]
}
Delete product category DELETE
| Field | Type | Required | Description |
|---|---|---|---|
cid |
int | yes | Category ID |
Note. Products of the deleted category lose their binding to it.
Response: {"success": true, "status": "ok"}. Error: Bad cID — cid is missing or not a number.
Example request
{
"cid": 67
}
Sales
URL - /bapi/sales (/bapi/orders is the same endpoint)
Get sales GET
Retrieve a list of sales.
| Parameter | Type | Required | Description |
|---|---|---|---|
limit |
int | no | Page size, up to 5000. Default 500 |
offset |
int | no | Offset. Default 0 |
date_from |
int | no | Period start, UNIX timestamp (e.g. 1695340800) |
date_to |
int | no | Period end, UNIX timestamp (e.g. 1695427199) |
client_id |
int | no | Sales of this client |
warehouse_id |
int | no | Sales with at least one item from this warehouse |
status |
string | no | Sales with this order_status, see statuses |
refund / is_refund |
bool | no | true — only refunds instead of regular sales |
Without date_from / date_to the sales of the last 90 days are returned. By default only regular sales are
returned (not refunds).
Errors: limit can't be more than 5000; date_from later than date_to, an invalid timestamp or date_from in the
future — 400 with the reason.
Response fields
data is a list of sales:
| Field | Type | Description |
|---|---|---|
oid |
int | Sale ID |
order_number |
string | Sale number shown in HugeProfit |
purchase_date |
int | Sale date, UNIX timestamp |
date_ident |
string | Sale date as YYYYMMDD |
order_status |
string | Status, see Sale statuses |
amount |
number | Sum of the items |
amount_sale |
number | Amount the buyer pays (after the order discount) |
prepaid_amount |
number | Prepayment |
discount, discount_type |
number, string | Order discount: % — percent, stable — fixed amount |
fee |
number / null | Channel commission |
account_id |
int | Payment account |
prapaid_account_id |
int / null | Prepayment account |
currency |
string | Currency ID of the sale |
client_id |
int / null | Client ID |
clients_delivery_id |
int / null | Client delivery address (client.client_deliveries[].id) |
channel_id |
string | Sales channel IDs as a JSON string: "[867]" |
responsible_user_id |
int | Employee who created the sale |
comment |
string | Comment |
delivery_info |
string / null | Delivery service, see Delivery services |
tracking_number |
string / null | Tracking number (TTN) |
remote_order_id |
int / null | Order from Remote orders the sale was created from |
seller_order_id |
string | Order number on a marketplace |
cash_from_client |
number / null | Cash received from the buyer |
af |
string | Additional sale fields as a JSON string |
more_info |
string | Service data as a JSON string |
dps |
array / null | Fiscal receipts of the sale |
terminal_trx |
string / null | Payment terminal transaction |
items |
array | Sale items, see below |
client |
object | Only if the sale has a client: id, name, phone, email, first_name, last_name, middle_name, client_deliveries[] |
items[]:
| Field | Type | Description |
|---|---|---|
oiid |
int | Item ID |
product_id |
int | Product ID |
product_name |
string | Product name |
product_deleted |
int | 1 — the product has been deleted |
parent_id |
int / null | Parent product of a variation |
mid |
int | Warehouse ID |
quantity |
number | Quantity |
base_price |
number | Unit price before the item discount |
price |
number | Unit price |
discount |
number | Item discount |
amount |
number | Item total |
net_price |
number | Unit cost price |
profit, item_profit |
number | Profit of the item |
tax, channel_tax |
number | Tax and channel commission of the item |
type_price |
string | Price type label |
barcode |
string / null | Barcode |
is_refund |
int | 1 — the item has been returned |
Example response
{
"success": true,
"data": [
{
"purchase_date": 1744362309,
"date_ident": "20250411",
"amount": 20.00,
"oid": 3994,
"amount_sale": 20.00,
"more_info": "{\"account_fee\": 0, \"fee_type\": 0}",
"af": "",
"prepaid_amount": 0.00,
"responsible_user_id": 11,
"channel_id": "[905]",
"client_id": 106747,
"comment": "",
"cash_from_client": null,
"discount": 0.00,
"discount_type": "%",
"order_status": "saled",
"account_id": 2,
"prapaid_account_id": null,
"clients_delivery_id": 33043,
"seller_order_id": "",
"tracking_number": null,
"delivery_info": null,
"remote_order_id": null,
"order_number": "11042501",
"currency": "2",
"fee": null,
"terminal_trx": null,
"dps": null,
"items": [
{
"oiid": 4780,
"is_refund": 0,
"quantity": 1.000,
"barcode": null,
"product_id": 79499,
"mid": 8511,
"parent_id": null,
"net_price": 0,
"tax": 0,
"channel_tax": 0,
"price": 20.00,
"base_price": 20.00,
"amount": 20.00,
"discount": 0.00,
"type_price": "",
"profit": 20.00,
"item_profit": 20.00,
"product_name": "Хороший вариативный товар. ",
"product_deleted": 0,
"ukzt": null
}
],
"client": {
"id": 106747,
"name": "Іван Іванов Іванович",
"phone": "380860005555",
"email": "",
"first_name": "Іван",
"last_name": "Іванов",
"middle_name": "Іванович",
"client_deliveries": [
{
"id": 33043,
"delivery_id": 1,
"city": "8d5a980d-391c-11dd-90d9-001a92567626",
"post_office": "1ec09d88-e1c2-11e3-8c4a-0050568002cf"
}
]
}
}
]
}
Create sales PUT
Create new sale
Request fields:
| Field | Type | Required | Description |
|---|---|---|---|
products |
object / array | yes | Sale items, see Sale item |
account_id |
int | yes | Account that receives the payment (accounts in Reference). The sale currency is the account currency |
amount |
number | yes | Sum of the items: finish_price × count over all items. Greater than 0 |
amount_sale |
number | yes | Amount the buyer pays: amount minus the order discount. Without a discount equals amount |
prepaid_amount |
number | yes | Prepayment. Send 0 if there is none |
client_id |
int / null | yes | Client ID (see Clients). null — sale without a client |
account_prepaid |
int | with prepayment | Account that receives the prepayment. Without it the prepayment is not credited |
date |
string | no | Sale date, ISO 8601 in UTC: 2024-12-12T13:35:11.259Z. Default — now |
order_status |
string | no | Sale status, see Sale statuses. Default — saled |
custom_status |
string | no | Only with order_status: "delivery": the sale gets this status instead of delivery |
channel_id |
int / object / array | no | Sales channel (sales_channels in Reference): 867, [867, 905], {"value": 867} or [{"value": 867}, {"value": 905}]; the string "[867]" as returned by GET is accepted too. Without a channel the sale gets the technical channel 1 |
discount |
number | no | Order discount. Default 0 |
discount_type |
string | no | % (default) — percent, stable — fixed amount in the sale currency |
fee |
number | no | Marketplace / channel commission for this sale, in the sale currency; reduces the profit. It is not calculated from the channel settings — send the amount yourself |
comment |
string | no | Comment, up to 300 characters |
postoffice |
int | no | Client delivery address: client_deliveries[].id from Clients. An unknown ID is ignored |
delivery_info |
string | no | Delivery service code, see Delivery services. A note can follow a colon: "1: Branch 5". Up to 200 characters |
tracking_number |
string | no | Tracking number (TTN), up to 20 characters. It is linked to the carrier only if delivery_info holds just a numeric code ("1"), without a note |
cash_from_client |
number | no | Cash received from the buyer; the change on the fiscal receipt is calculated from it |
af |
string | no | Additional sale fields as a JSON string: "{\"Source\": \"Instagram\"}". Keys are the names of the sale additional fields from your settings. A JSON object instead of a string is ignored |
expenses |
array | no | Expenses created together with the sale, see Sale expenses |
remote_order_id |
int | no | id of an order from Remote orders: the sale is created from this order, its reserve is released and the order is marked as processed |
When the sale is created, amount_sale (or amount, if it is less) minus the prepayment and the account commission is credited to account_id — whatever the status.
Sale item
products is an object with any string keys ({"0": {...}, "1": {...}}) or an array of items. In an array, items with the same pid are merged into the last one, so to sell one product from two warehouses use the object form.
| Field | Type | Required | Description |
|---|---|---|---|
pid |
int | yes | Product ID |
mid |
int | yes | Warehouse ID (warehouses in Reference) |
count |
number | yes | Quantity, fractional allowed (0.5) |
finish_price |
number | yes, except an item with promotion_id |
Unit price after the item discount — the item is sold at this price |
discount |
number | no | Item discount for display: positive — percent, negative — fixed amount per unit (-20). The order discount does not apply to an item with a non-zero discount |
default_price |
number | no | Unit price before the item discount, used with discount. Default — finish_price |
type_price |
string | no | Price type label, e.g. additional price name ("Wholesale"), up to 255 characters |
promotion_id |
int | no | Promotion the item is sold under, see Sale with a promotion |
The order discount (discount + discount_type) is spread over the items without their own discount, so amount_sale must already include it. In the example below the 5% discount applies only to the second item: amount_sale = 190 − 100 × 5% = 185.
Sale with a promotion
To count a sale towards a promotion — its limits, budget and statistics in HugeProfit — send promotion_id in the item: the product's stock[].promotion.id or another promotion applied to this product in this warehouse (as in the sale form's price list). HugeProfit computes the price — from the main price or, for a promotion on an additional price, from that price:
finish_pricemay be omitted — we fill inpromotion.price;- a
finish_priceyou send must equal the promotion price to the cent, otherwise the error ispromotion_price_mismatchwith the correct price ininfo.expected; - compute
amountandamount_salefrom the promotion price.
Without promotion_id the item is sold at finish_price and the promotion does not count it, even if the price matches the promotion price. If type_price is not sent, HugeProfit shows the promotion name next to the item.
"products": [
{"pid": 41895, "mid": 3, "count": 2, "promotion_id": 12}
]
Promotion errors ({"success": false, "error": "promotion_...", "info": {...}}): when the error belongs to an item, info holds its product_id, warehouse_id and promotion_id.
error |
Cause | What to do |
|---|---|---|
promotion_inactive |
The promotion was turned off, has ended or has not started yet | Re-read the product and show the buyer the current price |
promotion_not_applicable |
The promotion does not apply to this product in this warehouse, the product has no such additional price, or it does not lower the price | Same |
promotion_price_mismatch |
finish_price does not equal the promotion price |
Take the price from info.expected |
promotion_limit_usage |
The promotion usage limit is reached | Sell without the promotion |
promotion_limit_client |
Client client_id has used up their promotion limit |
Sell without the promotion |
Editing a sale checks the promotion the same way: if it has already ended, send the item without promotion_id — the price is kept, but the sale leaves the promotion's accounting.
Sale statuses
order_status |
What happens |
|---|---|
not sent, main_sale, saled |
Completed sale (saled): stock is written off |
reserve_sale |
Reserve: available stock decreases, physical stock stays. Stock is not checked |
delivery |
Sale in delivery; with custom_status the sale gets that status |
| any other string | Saved as is: delivering, cod, arrived or your own status (see statuses) |
For all statuses except reserve_sale the stock is checked first: if it is not enough, the sale is not created.
Delivery services
delivery_info |
Service |
|---|---|
1 |
Nova Poshta |
3 |
Ukrposhta |
6 |
Rozetka Delivery |
24 |
Meest |
justin, delivery_auto |
Justin, Delivery Auto |
pickup, city-delivery, outcity-delivery, international |
Pickup, city delivery, out-of-city delivery, international |
UPS, DHL, post office, other |
For accounts outside Ukraine |
Sale expenses
Each expense reduces the sale profit.
| Field | Type | Required | Description |
|---|---|---|---|
amount |
number | yes | Expense amount |
category |
int | no | Expense category (expenses_category in Reference) |
account_id |
int | no | Account the expense is paid from. Default — account_id of the sale |
expense_name |
string | no | Expense name |
mid |
int | no | Warehouse ID |
Response:
| Field | Type | Description |
|---|---|---|
oid |
int | ID of the created sale |
order_number |
string | Sale number, generated automatically (DDMMYY + number of the sale of the day) |
balance |
number | Balance of account_id after the sale |
expenses_ids |
array | IDs of the created expenses |
check, check_id, type |
Service fields, don't rely on them |
Example request
{
"products": {
"0": {
"pid": 41895,
"mid": 3,
"count": 2,
"finish_price": 45,
"default_price": 50,
"discount": 10
},
"1": {
"pid": 41900,
"mid": 3,
"count": 1,
"finish_price": 100
}
},
"amount": 190,
"amount_sale": 185,
"discount": 5,
"discount_type": "%",
"account_id": 2,
"prepaid_amount": 50,
"account_prepaid": 5,
"client_id": 106747,
"postoffice": 33043,
"order_status": "delivery",
"custom_status": "delivering",
"channel_id": {"value": 867},
"delivery_info": "1",
"tracking_number": "20450000000000",
"date": "2024-12-12T13:35:11.259Z",
"comment": "Call before delivery",
"af": "{\"Source\": \"Instagram\"}",
"expenses": [
{"amount": 30, "category": 12, "expense_name": "Packaging"}
]
}
Example response
{
"success": true,
"oid": 3732,
"order_number": "12122404",
"balance": 11934010.61,
"check": "allow",
"check_id": 0,
"type": "",
"expenses_ids": [5121]
}
Errors come as {"success": false, "error": "..."}:
error |
Reason |
|---|---|
Not all required keys. You required: ... |
products, account_id or amount is missing |
not all fields required |
products or account_id is empty, or amount ≤ 0 |
bad amount |
amount is more than 9 999 999 999 |
Change method to POST for edit |
oid is sent — use Edit sale |
invalid channel_id (...) |
A channel without value |
... (Problems with quantity products) |
Not enough stock |
... (Not found) |
account_id or account_prepaid not found |
error-long-comment |
A text field is too long (comment, tracking_number, delivery_info) |
... (Limit: sales) |
The sales limit of your plan is reached |
promotion_... |
The item's promotion was not applied, see Sale with a promotion |
Edit sale POST
The fields are the same as in Create sales, plus oid (required) — ID of the sale being edited.
Send the whole sale, not only the changed fields. The sale is saved under a new oid, which comes in the response;
the response fields are the same as when creating.
Example request
{
"oid": 3732,
"amount": 50,
"amount_sale": 50,
"client_id": null,
"channel_id": [],
"order_status": "saled",
"account_id": 2,
"date": "2024-12-12T13:35:11.259Z",
"discount": 0,
"discount_type": "%",
"products": {
"0": {
"pid": 41895,
"count": 2,
"discount": 1,
"finish_price": 50.99,
"mid": 3
}
},
"comment": "",
"prepaid_amount": 0
}
Example response
{
"success": true,
"oid": 3733,
"order_number": "12122404",
"balance": 11934010.61,
"check": "allow",
"check_id": 0,
"type": ""
}
Delete sale DELETE
| Field | Type | Required | Description |
|---|---|---|---|
oid |
int | yes | Sale ID |
Response: {"success": true, "balance": 11934010.61} — balance of the sale account after deletion. Error:
oid is invalid.
Fiscalize sale POST
URL - /bapi/sales/receipt
Issues a fiscal receipt for an existing sale through a connected cash register (Checkbox or Vchasno.Kasa) — like the Fiscalize button in HugeProfit.
| Field | Type | Required | Description |
|---|---|---|---|
oid |
int | yes | Sale ID |
cash_register_id |
int | no | Cash register, cash_registers in Reference. Without it — the first connected register that fits the sale, as in HugeProfit |
prepayment_comment |
string | no | Fiscalize only the prepayment of the sale (prepaid_amount) with this text in the receipt |
Response data:
| Field | Type | Description |
|---|---|---|
oid |
int | Sale ID |
receipt_id |
string | Receipt ID in the cash register |
type |
string | checkbox or vchasno |
status |
string | Receipt status from the cash register |
prepaid |
bool | true for a prepayment receipt |
cash_register_id |
int | Cash register that issued the receipt |
receipt_url |
string | Public page of the receipt for the buyer |
Example request
{
"oid": 3733,
"cash_register_id": 311,
"prepayment_comment": "Prepayment for order 3733"
}
Example response
{
"success": true,
"data": {
"oid": 3733,
"receipt_id": "4a1f0c3e-7d0b-4c71-9a9e-0e3f6d2b8c11",
"type": "checkbox",
"status": "CREATED",
"prepaid": false,
"cash_register_id": 311,
"receipt_url": "https://check.checkbox.ua/4a1f0c3e-7d0b-4c71-9a9e-0e3f6d2b8c11"
}
}
If the cash register shift is closed it is opened automatically: the error not-open-shift /
still-waiting-open-shift means to repeat the request in a minute. Other errors (400):
this check has already been fiscalized, prepaid-already-fiscalized, fiscal-in-progress (a receipt
for the sale is being issued right now), prepaid amount should be more than 0, fiscal-timeout (the cash
register did not answer and the receipt may already exist — check the sale before repeating), or the cash
register's own refusal text. Unknown or returned sale — 404; no connected register fits the sale — 404
not-active-warehouse-or-integration.
Clients
URL - /bapi/clients
Get clients GET
Retrieve a list of clients, sorted by ID.
| Parameter | Type | Required | Description |
|---|---|---|---|
limit |
int | no | Page size. Default 500 (100 recommended) |
offset |
int | no | Offset. Default 0 |
id |
int | no | One client |
updated_at |
int | no | Clients changed after this moment, UNIX timestamp |
phone |
string | no | Whole phone number in any notation: 380671234567, +380671234567, 0671234567, +38 (067) 123-45-67. Several clients may share one number, so the result is still a list |
phone_contains |
string | no | Part of the number, at least 3 digits, e.g. 4567. Can be combined with phone |
with_debt |
int | no | 1 — add the debt field. Omit it if you don't need debt: it costs an extra query |
with_chats |
string | no | Messenger types, comma-separated: add the chats field. Supported: telegram. Omit it if you don't need chats |
phone_contains with fewer than 3 digits and an unsupported with_chats value return 400.
Examples: GET /bapi/clients?id=105424&with_chats=telegram, GET /bapi/clients?phone=0671234567,
GET /bapi/clients?phone_contains=4567.
Response fields
data is a list of clients:
| Field | Type | Description |
|---|---|---|
id |
int | Client ID |
name |
string | Full name |
first_name, last_name, middle_name |
string | First, last and middle name |
nickname |
string | Nickname |
phone |
string | Phone, digits only |
email |
string | |
company |
string | Company |
birth_day |
string / null | Birthday, YYYY-MM-DD HH:MM:SS |
city, address, postal_code, state_or_region, country |
string / null | Address |
discount |
number | Client discount, % |
balance |
number | Client bonus balance |
total_amount |
number | Total purchase amount |
card_number, card_url |
string / null | Loyalty card |
comment |
string | Comment |
invoice |
string | Invoice details |
is_active |
int | 1 — active client |
responsible_user_id |
int / null | Responsible employee |
created_at, updated_at |
int | UNIX timestamps |
tags |
array | All client tags [{"id", "name", "color"}] in the order they were assigned |
client_tag_id, client_tag_name |
int / string / null | The first tag; kept for compatibility, use tags |
debt |
number | Only with with_debt=1: sum of amount_sale − prepaid_amount of unpaid sales |
chats |
array | Only with with_chats: the client's messenger chats, newest first, see below |
chats[]:
| Field | Description |
|---|---|
type |
Messenger type (telegram) |
integration_id |
ID of the connected messenger integration (bot) the chat belongs to |
chat_id |
Chat identifier in the messenger (for Telegram — the chat_id used by the Bot API) |
A bot can only message a client who has already written to that bot, so use chat_id together with the bot of
the matching integration_id.
Example response
{
"success": true,
"data": [
{
"id": 105424,
"is_active": 1,
"name": "",
"phone": "380999999999",
"email": "",
"birth_day": "1995-12-16 00:00:00",
"more_info": "{}",
"birth_day_child_1": null,
"birth_day_child_2": null,
"birth_day_child_3": null,
"discount": 0,
"total_amount": 0.00,
"city": "",
"postal_code": null,
"state_or_region": null,
"country": null,
"created_at": 1686981559,
"updated_at": 1742370000,
"address": "",
"responsible_user_id": null,
"comment": "",
"first_name": "Світлана",
"last_name": "Пасічко",
"middle_name": "Юріївна",
"ref": null,
"nickname": "",
"company": "",
"invoice": "",
"card_url": null,
"card_number": null,
"balance": 0.00,
"client_tag_id": 3,
"client_tag_name": "VIP",
"tags": [
{
"id": 3,
"name": "VIP",
"color": "#ff0000"
}
],
"debt": 1250.00,
"chats": [
{
"type": "telegram",
"integration_id": 512,
"chat_id": "123456789"
}
]
}
]
}
Create / Edit client POST
Create new or edit existing clients. Body: {"data": [...]}, up to 3000 clients per request.
How a client is matched:
- with
idof your client — this client is edited; - without
id, but with a phone that already belongs to your client — that client is edited; - otherwise a new client is created. A new client without a valid phone is skipped.
| Field | Type | Required | Description |
|---|---|---|---|
phone |
string | yes | Phone number in any notation, stored as digits. When editing by id, an empty value keeps the old number |
id |
int | no | ID of the client to edit |
first_name |
string | no | First name |
last_name |
string | no | Last name |
middle_name |
string | no | Middle name |
name |
string | no | Full name |
nickname |
string | no | Nickname |
email |
string | no | |
company |
string | no | Company |
birth_day |
string | no | Birthday, YYYY-MM-DD |
city |
string | no | City |
address |
string | no | Address |
comment |
string | no | Comment |
discount |
number | no | Client discount, % |
balance |
number | no | Bonus balance |
total_amount |
number | no | Total purchase amount |
debt |
number | no | Debt |
card_number |
string | no | Loyalty card number |
card_url |
string | no | Loyalty card URL |
af |
object / string | no | Additional fields: JSON object or a string with a JSON object |
tag_id |
int | no | Tag to bind to a new client (see Client Tags) |
tag_name |
string | no | Tag name to create and bind to a new client, if tag_id is not sent |
Response data — the processed clients as they were saved: your fields plus id (for a skipped client there is no
id). Error: more then 3000 clients.
Example request
{
"data": [
{
"first_name": "John",
"last_name": "Doe",
"middle_name": "Paul",
"phone": "380991234567",
"email": "john@example.com",
"birth_day": "1990-01-01",
"discount": 5,
"city": "Kyiv",
"address": "Khreshchatyk St, 1",
"comment": "VIP client",
"tag_id": 3
}
]
}
Example response
{
"success": true,
"data": [
{
"id": 106810,
"first_name": "John",
"last_name": "Doe",
"middle_name": "Paul",
"phone": "380991234567",
"email": "john@example.com",
"birth_day": "1990-01-01",
"discount": 5,
"city": "Kyiv",
"address": "Khreshchatyk St, 1",
"comment": "VIP client"
}
]
}
Delete clients DELETE
| Field | Type | Required | Description |
|---|---|---|---|
data |
array | yes | Client IDs, up to 3000 |
Response: {"success": true, "data": "ok"}. Errors: more then 3000 clients, bad type data (data is not an
array).
Example request
{
"data": [105424, 105425, 105426]
}
Client Tags
URL - /bapi/clients/tags
Manage client tags. Tags allow you to group and segment clients. A tag is {"id", "name", "color"}.
Get tags GET
Returns all tags, or tags of one client.
| Parameter | Type | Required | Description |
|---|---|---|---|
cid |
int | no | Client ID: return only this client's tags |
Example response
{
"success": true,
"data": [
{
"id": 1,
"name": "VIP",
"color": "#FFD700"
},
{
"id": 2,
"name": "Wholesale",
"color": "#00AAFF"
}
]
}
Create tag POST
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | yes | Tag name |
color |
string | no | HEX color: #FFD700 or #FFF. Default #000000 |
Response: data — ID of the created tag. Errors: name is required, unsupported color hexcode.
Example request
{
"name": "VIP",
"color": "#FFD700"
}
Example response
{
"success": true,
"data": 5
}
Bind or edit tag PUT
| Field | Type | Required | Description |
|---|---|---|---|
tid |
int | yes | Tag ID |
cid |
int | to bind | Client ID: bind the tag to this client |
name |
string | to edit | New tag name |
color |
string | to edit | New HEX color |
cid+tid— bind the tag to the client;data— ID of the binding.tid+nameand/orcolor— edit the tag;data— the tag ID.
Errors:
error |
Reason |
|---|---|
provide (cid + tid) to bind, or (tid + name/color) to edit |
Neither combination is sent |
cid and tid must be integers, tid must be an integer |
Wrong ID type |
error-client-not-found (404) |
No such client |
error-tag-not-found (404) |
No such tag |
tag-for-client-already-exist |
The client already has this tag |
unsupported color hexcode |
Invalid color |
Example request: bind
{
"cid": 105424,
"tid": 1
}
Example request: edit
{
"tid": 1,
"name": "Super VIP",
"color": "#FF0000"
}
Unbind or delete tag DELETE
| Field | Type | Required | Description |
|---|---|---|---|
tid |
int | yes | Tag ID |
cid |
int | no | Client ID: only unbind the tag from this client. Without it the tag is deleted completely |
Response: data — number of deleted records. Errors: tid is required, tid must be an integer,
cid must be an integer, error-client-tags-not-found (404) — nothing to delete.
Example request
{
"cid": 105424,
"tid": 1
}
Remote orders
URL - /bapi/remote_orders
Orders from your site or system. In HugeProfit they appear in the orders list, reserve stock and are turned into
sales by a manager (or via remote_order_id in Create sales).
Get orders GET
| Parameter | Type | Required | Description |
|---|---|---|---|
limit |
int | no | Page size, up to 1000. Default 500 |
offset |
int | no | Offset. Default 0 |
start |
int | no | Changed after, UNIX timestamp. Only together with end |
end |
int | no | Changed before, UNIX timestamp. Only together with start |
order_id |
string | no | One order by its number in your system (order_id) |
id |
int | no | One order by its ID in HugeProfit |
Without order_id / id only orders not yet turned into a sale (sales_id is null) are returned, sorted by the
modification date (date_modified) descending — so polling catches both new and changed orders. Without
start / end — orders changed over the past 3 months. With order_id or id the order is returned whatever its
date and state.
The list also contains orders of the other integrations of your account; tell yours apart by integration_id.
Error: limit can't be more than 1000.
Response fields
The orders are in response (not in data):
| Field | Type | Description |
|---|---|---|
id |
int | Order ID in HugeProfit |
order_id |
string | Order number in your system |
integration_id |
int | Integration the order belongs to |
order_name |
string | Order name |
status |
string | Status, see order statuses |
local_status |
string / null | Status set in HugeProfit |
price |
number | Order sum |
discount |
number | Order discount |
currency |
string / null | Currency |
date_created, date_modified |
string | Dates, YYYY-MM-DD HH:MM:SS |
first_name, last_name |
string | Buyer |
phone, email |
string / null | Buyer contacts |
client_id |
int / null | Client found or created in HugeProfit |
address_1 |
object | Delivery, see RemoteAddressType |
address_2 |
string / null | Additional delivery info |
order_data |
array | Items, see OrderDataType |
info |
object | Additional data, see InfoType |
sales_id |
int / null | Sale created from the order |
is_deleted |
int | Always 0 |
Example response
{
"success": true,
"response": [
{
"integration_id": 435,
"order_id": "321303990",
"user_id": 11,
"status": "pending",
"local_status": null,
"order_name": "Order ID: 321303990",
"order_atributes": null,
"info": {
"is_paid": false,
"payment_type": "Наложенный платеж"
},
"price": 500.32,
"discount": 0.0,
"currency": "грн",
"date_created": "2024-12-11 16:31:54",
"date_modified": "2024-12-11 16:31:55",
"phone": "+380672225522",
"email": null,
"address_1": {
"address_1": "",
"city": "",
"delivery_cost": 0,
"delivery_operator": "nova_poshta"
},
"address_2": "",
"is_deleted": 0,
"order_data": [
{
"id": 2423560633,
"name": "Зелена бавовняна шапка",
"product_id": 2423560633,
"sku": "shrek",
"quantity": 1.0,
"price": "500,32 грн",
"total": "500,32 грн",
"is_paid": false,
"payment_type": "Наложенный платеж",
"measure_unit": "шт."
}
],
"first_name": "Клієнт",
"last_name": "Плюс",
"client_id": 106623,
"id": 2673521,
"sales_id": null
}
]
}
Create order POST
Create a new order or update an existing one. The order goes in the data object of the body. Sending an order
with the same order_id again updates it (info and order_data are replaced, not merged); once the order has
become a sale, its items no longer change.
| Field | Type | Required | Description |
|---|---|---|---|
order_id |
int / string | yes | Order number in your system, digits only |
price |
number | yes | Order sum |
first_name |
string | yes | Buyer's first name |
address_1 |
object | yes | Delivery: address_1, city, delivery_cost are required, see RemoteAddressType |
order_data |
array | yes | Items, see OrderDataType. Required item keys: id, name, product_id, quantity, price, total, is_paid |
currency |
string | no | Currency: UAH, USD, грн... |
last_name |
string | no | Buyer's last name |
phone |
string | no | Buyer's phone; the client is found or created by it |
email |
string | no | Buyer's email |
address_2 |
string | no | Postal code or additional delivery info |
status |
string | no | Default pending, see order statuses |
order_name |
string | no | Default Order ID: {order_id} |
discount |
number | no | Order discount. Default 0 |
info |
object | no | Additional data: payment, comment, UTM, account and channel for the sale..., see InfoType |
order_created |
number | no | Creation date, UNIX timestamp. Default — now |
order_modified |
number | no | Modification date, UNIX timestamp. Default — now |
Items with local_product_id (ID of the product in HugeProfit) are reserved on the reserve warehouse of your
API integration. An item without one of the required keys is dropped silently.
Response: reservedProducts — reserved items as [product_id, warehouse_id] pairs.
error |
Reason |
|---|---|
Not all required keys. You required: ... |
One of the required fields is missing |
order_id is invalid |
order_id is empty or not numeric |
Address_1 is invalid |
address_1 lacks address_1, city or delivery_cost |
No product information found in your request... (400) |
No item of order_data has all the required keys |
Example request
{
"data": {
"order_id": 1001,
"price": 1030,
"currency": "UAH",
"first_name": "Ivan",
"last_name": "Petrenko",
"phone": "+380671234567",
"email": "ivan@example.com",
"status": "pending",
"order_created": 1733397480,
"address_1": {
"address_1": "Branch 5",
"city": "Kyiv",
"delivery_cost": 80,
"delivery_operator": "nova_poshta"
},
"order_data": [
{
"id": 501,
"name": "Green cotton hat",
"product_id": null,
"local_product_id": 41901,
"sku": "HAT-01",
"quantity": 2,
"price": 475,
"total": 950,
"is_paid": false,
"payment_type": "Cash On Delivery"
}
],
"info": {
"is_paid": false,
"payment_type": "Cash On Delivery",
"comment": "Call before delivery"
}
}
}
Example response
{
"success": true,
"reservedProducts": [
[41901, "3"]
]
}
Reference
URL - /bapi/reference_info
GET reference info
Reference data for other requests: accounts, categories, brands, warehouses, sales channels, cash registers.
| Parameter | Type | Required | Description |
|---|---|---|---|
types |
string | no | Comma-separated list of what to return: accounts,warehouses. Without it — everything. Unknown values are ignored |
types value |
Key in data |
Fields |
|---|---|---|
accounts |
accounts |
id, name, balance, currency_id, types (0 cash, 1 cash on delivery, 2 card, 3 IBAN, 4 unpaid), created_at |
products_category |
products_categories |
id, name, parent_id, types, created_at |
expenses_category |
expenses_categories |
id, name (translated to the account language), types, is_global, is_receipt, is_profit |
brand |
brands |
id, name |
warehouses |
warehouses |
id, name, w_type (1 main, 2 dropshipping, 3 negative stock allowed), created_at, is_deleted. Only warehouses available to the key |
sales_channels |
sales_channels |
id, name, is_global, integration_id, position, fee, color, created_at |
write_off_category |
write_off_categories |
id, name, parent_id, created_at, see Write-off |
production_category |
production_categories |
id, name, parent_id, created_at, see Productions |
cash_registers |
cash_registers |
id, type (checkbox or vchasno), name, see Fiscalize sale |
Dates are UNIX timestamps.
Example response
{
"success": true,
"data": {
"accounts": [
{
"id": 2,
"name": "Наличка",
"balance": 11972109.66,
"currency_id": 2,
"types": 0,
"created_at": 1587396469
}
],
"products_categories": [
{
"id": 17497,
"name": "Іграшки",
"types": 1,
"parent_id": 0,
"created_at": 1725259340
}
],
"expenses_categories": [
{
"id": 1,
"name": "Общие",
"types": 0,
"is_global": 1,
"is_receipt": 0,
"is_profit": 0
}
],
"brands": [
{
"id": 6017,
"name": "Новый бренд"
}
],
"warehouses": [
{
"id": 4,
"name": "Components",
"w_type": 3,
"created_at": 1587382394,
"is_deleted": 0
}
],
"sales_channels": [
{
"id": 1,
"name": "Channel Name",
"is_global": 1,
"integration_id": 435,
"position": 0,
"fee": 0.00,
"color": "blue",
"created_at": 1725259340
}
],
"write_off_categories": [
{"id": 2, "name": "Damage", "parent_id": null, "created_at": 1725259340}
],
"production_categories": [],
"cash_registers": [
{"id": 311, "type": "checkbox", "name": "Shop"}
]
}
}
Product Sync
URL - /bapi/products_sync
Links between HugeProfit products and product IDs in your system (remote_id) within an integration.
GET product sync
| Parameter | Type | Required | Description |
|---|---|---|---|
integration_id |
int | yes | Integration whose links to return |
Response data[]: product_id, integration_id, remote_id, user_id; newest products first.
Example response
{
"success": true,
"data": [
{
"product_id": 100025,
"user_id": 11,
"integration_id": 435,
"remote_id": "2595649057"
}
]
}
POST product sync
Body: {"bulk": [...]}; every key of an element is required:
| Field | Type | Required | Description |
|---|---|---|---|
product_id |
int | yes | Product ID in HugeProfit |
remote_id |
string | yes | Product ID in your system |
integration_id |
int | yes | Your integration |
A product has one link per integration: if it already exists, it is not changed (existing: true).
Response:
| Field | Description |
|---|---|
results[] |
Per element: product_id, success, message, sync_id, existing |
stats |
total, success, failed, existing, created |
A missing bulk or a missing key in an element — 400 for the whole request. An unknown product or integration —
success: false for that element only.
Example request
{
"bulk": [
{
"product_id": 8695,
"remote_id": "A-565",
"integration_id": 545
}
]
}
Example response
{
"success": true,
"results": [
{
"product_id": 8695,
"success": true,
"message": "Привязка успешно создана",
"sync_id": [],
"existing": false
}
],
"stats": {
"total": 1,
"success": 1,
"failed": 0,
"existing": 0,
"created": 1
}
}
DELETE product sync
Body: {"bulk": [...]}; every key of an element is required:
| Field | Type | Required | Description |
|---|---|---|---|
integration_id |
int | yes | Integration |
remote_id |
string | yes | Product ID in your system |
Response: message and deleted_items — the processed elements. Nothing found — 404 with
info.attempted_items; a missing or empty bulk or a missing key — 400.
Example request
{
"bulk": [
{
"remote_id": "A-565",
"integration_id": 545
}
]
}
Example response
{
"success": true,
"message": "Успешно удалено 1 записей.",
"deleted_items": [
{
"integration_id": 545,
"remote_id": "A-565"
}
]
}
Shipments
URL - /bapi/shipments
GET shipments
| Parameter | Type | Required | Description |
|---|---|---|---|
sid |
int | no | One shipment with its products. The other parameters are ignored |
date_from |
int | no | Delivered after, UNIX timestamp |
date_to |
int | no | Delivered before, UNIX timestamp |
status |
string | no | registration — being prepared, pending — on the way, complete — received |
warehouse_id |
int | no | Shipments to this warehouse |
limit |
int | no | Page size, up to 1000. Default 50 |
offset |
int | no | Offset. Default 0 |
The list is sorted by delivery date, newest first. Only shipments to warehouses available to the key are returned.
Errors: 400 for an invalid date or date_from not earlier than date_to, or limit over 1000; unknown sid —
404.
Response fields
| Field | Type | Description |
|---|---|---|
id |
int | Shipment ID |
name |
string | Name |
marketplace_id, marketplace_name |
int, string | Warehouse |
shipment_status, status_name |
string | Status: registration, pending, complete |
supplier_id |
int / null | Supplier, see Suppliers |
quantity |
number | Quantity of goods |
expected_quantity |
number | Expected quantity |
amount |
number | Amount of goods in the shipment currency |
received_amount |
number | Amount of the received goods |
currency, currency_rate |
string, number | Shipment currency ID and its rate |
fee_per_unit, fee_total |
number | Delivery cost per unit and in total |
delivered_date, created_at |
int | UNIX timestamps |
ttn, ttn_status |
string / null | Tracking number and its status |
comment |
string | Comment |
expenses_id |
int / null | First payment for the goods; all payments are in payments |
delivery_expenses_id |
int / null | Delivery payment |
payments |
array | All payments for the goods, oldest first, including deferred and partial ones (without the delivery payment) |
products |
array | Only with sid: products of the shipment |
expense_details, delivery_expense_details |
object | Only with sid: the expenses_id and delivery_expenses_id expenses, fields as in GET expenses |
payments[]:
| Field | Description |
|---|---|
expense_id |
Expense ID, see GET expenses |
date |
Payment date, UNIX timestamp |
amount |
Amount in the account currency |
account_id |
Account the payment was made from |
category_id |
Expense category |
name |
Expense name |
products[]:
| Field | Description |
|---|---|
product_id, product_name, product_sku |
Product, its name and article on the shipment warehouse |
quantity_shipped |
Quantity in the shipment |
quantity_received |
Quantity received |
purchase_price |
Unit price in the shipment currency |
amount |
purchase_price × quantity_shipped |
fee_per_unit |
Delivery cost per unit |
expiration_date |
Expiration date |
Example response
{
"success": true,
"data": [
{
"id": 11156,
"user_id": 11,
"marketplace_id": 8525,
"expenses_id": 1082,
"delivery_id": 9,
"amazon_shipment_id": null,
"shipment_status": "complete",
"fba_destination": null,
"fba_country": null,
"from_address": null,
"fee_total_units": null,
"fee_per_unit": 0.00,
"fee_total": 0.00,
"currency": "2",
"amount": 66000.00,
"quantity": 2000.00,
"delivered_date": 1744033768,
"comment": "",
"created_at": 1744033746,
"name": "Поставка 0 од. від 07.04.2025",
"expected_quantity": 2000.00,
"received_amount": 66000.00,
"supplier_id": null,
"delivery_expenses_id": null,
"responsible_user_id": null,
"currency_rate": 1.0000,
"ttn": "20451164735634",
"ttn_status": null,
"marketplace_name": "Тест поставки",
"status_name": "complete",
"payments": [
{
"expense_id": 1082,
"date": 1745830800,
"amount": 66000.00,
"account_id": 2,
"category_id": 11,
"name": "Оплата поставки"
}
]
}
]
}
Expenses
URL - /bapi/expenses
GET expenses
| Parameter | Type | Required | Description |
|---|---|---|---|
date_from |
int | no | Period start, UNIX timestamp. Without it — the last 31 days |
date_to |
int | no | Period end, UNIX timestamp, works together with date_from. Default — now |
category_id |
int | no | Expense category |
shipment_id |
int | no | Expenses (payments) of a shipment. Without date_from all of them are returned, regardless of date |
limit |
int | no | Page size, up to 5000. Default 500 |
offset |
int | no | Offset. Default 0 |
Newest first. Errors: limit can't be more than 5000, an invalid date or date_from not earlier than date_to,
non-numeric shipment_id — 400.
Response fields
| Field | Type | Description |
|---|---|---|
id |
int | Expense ID |
name |
string | Expense name |
amount |
number | Amount in the account currency |
account_id |
int | Account the expense is paid from |
balance |
number | Account balance after the expense |
category_id, category_name |
int, string | Category; the name is translated to the account language |
types |
int | 1 — one-time, 2 — planned |
marketplace_id |
int / null | Warehouse |
product_id |
int / null | Product |
shipment_id |
int / null | Shipment the expense pays for |
order_id |
int / null | Sale the expense belongs to |
comment |
string | Comment |
responsible_user_id |
int | Employee who created the expense |
created_at |
int | Expense date, UNIX timestamp |
Example response
{
"success": true,
"data": [
{
"id": 1082,
"user_id": 11,
"product_id": null,
"category_id": 11,
"marketplace_id": 8525,
"name": "Оплата поставки",
"amount": 66000.00,
"is_amazon": 0,
"comment": "",
"created_at": 1745830800,
"account_id": 2,
"balance": 11906109.66,
"types": 1,
"is_deleted": 0,
"responsible_user_id": 11,
"shipment_id": 11156,
"order_id": null,
"employer_id": null,
"note": null,
"category_name": "Поставка"
}
]
}
Productions
A production is a recipe set up in HugeProfit: components (products it consumes) and expenses → results (products it produces). Through the API you can read recipes and history and run a recipe.
GET productions
URL - /bapi/productions
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
int | no | One recipe |
category_id |
int | no | Production category (production_category in Reference) |
limit |
int | no | Page size, up to 1000. Default 100 |
offset |
int | no | Offset. Default 0 |
Errors: a non-numeric parameter — 400 (id must be an integer...), limit can not be more than 1000; unknown
id — 404 production not found.
Response fields
| Field | Type | Description |
|---|---|---|
id |
int | Recipe ID |
name |
string | Name |
status |
string | Recipe status |
category_id |
int / null | Production category |
result_product_id, result_marketplace_id |
int | Main result and its warehouse |
quantity |
number | Quantity of the main result per run |
amount |
number | Cost of one run |
created_at |
int | UNIX timestamp |
components |
array | Products the recipe consumes |
results |
array | Products the recipe produces |
expenses |
array | Expenses of the recipe |
In components[] and results[]: product_id, marketplace_id (warehouse), name, quantity per run,
amount — unit cost price.
Example response
{
"success": true,
"data": [
{
"id": 49,
"name": "Recipe 787",
"status": "created",
"category_id": null,
"amount": 20.0000,
"real_netprice": 0,
"result_product_id": 107511,
"result_marketplace_id": 8614,
"quantity": 1.0000,
"created_at": 1759744800,
"components": [
{"id": 115, "product_id": 107513, "marketplace_id": 8614, "name": "Raw", "quantity": 2.0000, "amount": 10.0000}
],
"results": [
{"id": 116, "product_id": 107511, "marketplace_id": 8614, "name": "Result", "quantity": 1.0000, "amount": 20.0000}
],
"expenses": []
}
]
}
POST run production
URL - /bapi/productions/run
Runs a recipe exactly as the Produce button in HugeProfit does: writes the components off their warehouses, adds the results to stock and records the recipe's expenses.
| Field | Type | Required | Description |
|---|---|---|---|
production_id |
int | yes | Recipe ID |
quantity |
number | yes | How many times to run the recipe, fractions allowed, > 0 |
account_id |
int | if the recipe has expenses | Account to pay the recipe's expenses from (accounts in Reference) |
Response data — the run:
| Field | Description |
|---|---|
id |
Run ID |
production_id |
Recipe |
product_id, marketplace_id |
Main result and its warehouse |
category_id |
Production category |
quantity |
How many times the recipe was run |
net_price |
Unit cost price of the result |
products_prices |
Cost of the components |
expenses_amount |
Amount of the expenses |
total |
Total cost |
created_at |
UNIX timestamp |
Example request
{
"production_id": 49,
"quantity": 2.5,
"account_id": 2
}
Example response
{
"success": true,
"data": {
"id": 812,
"production_id": 49,
"product_id": 107511,
"marketplace_id": 8614,
"category_id": null,
"quantity": 2.5000,
"net_price": 20.00,
"products_prices": 50.00,
"expenses_amount": 0.00,
"total": 50.00,
"created_at": 1759744800
}
}
If a component is short on a warehouse that doesn't allow negative stock, nothing is run and the response lists what is missing:
Example error: not enough stock
{
"success": false,
"error": "not enough stock",
"info": {
"shortages": [
{"product_id": 107513, "warehouse_id": 8614, "required": 120.0, "in_stock": 100.0}
]
}
}
Other errors (status 400): quantity missing or not positive, no account_id for a recipe with
expenses, a recipe without results. Unknown or deleted recipe — 404.
GET production history
URL - /bapi/productions/history
| Parameter | Type | Required | Description |
|---|---|---|---|
start |
int | no | Runs after, UNIX timestamp |
end |
int | no | Runs before, UNIX timestamp |
category_id |
int | no | Production category |
limit |
int | no | Page size, up to 1000. Default 100 |
offset |
int | no | Offset. Default 0 |
Returns runs in the same format as POST run production, newest first.
Write-off
URL - /bapi/write_off
POST write-off
Writes goods off a warehouse (damage, losses, own use) — like the Write-off document in HugeProfit, created and completed in one call.
| Field | Type | Required | Description |
|---|---|---|---|
warehouse_id |
int | yes | Warehouse to write off from |
category_id |
int | yes | Write-off category, write_off_category in Reference |
items |
array | yes | [{"product_id", "quantity"}], each product once, quantity > 0 |
comment |
string | no | Comment |
The amount is counted at the warehouse cost price.
Response data — the write-off: id, from_marketplace_id, category_id, status, amount, quantity,
comment, created_at and items[] with product_id, quantity_shipped (written off), quantity_was and
quantity_became (stock before and after).
Example request
{
"warehouse_id": 8614,
"category_id": 2,
"comment": "Damaged in transit",
"items": [
{"product_id": 107513, "quantity": 3}
]
}
Example response
{
"success": true,
"data": {
"id": 77,
"from_marketplace_id": 8614,
"category_id": 2,
"status": "completed",
"amount": 30.00,
"quantity": 3.0000,
"comment": "Damaged in transit",
"created_at": 1759744800,
"items": [
{"product_id": 107513, "quantity_shipped": 3.0000, "quantity_was": 100.00, "quantity_became": 97.00}
]
}
}
Not enough stock (on a warehouse without negative stock) — the same not enough stock error with
info.shortages as for a production run, nothing is written off. Empty items or not a list of
{product_id, quantity}, a repeated product or a quantity that isn't positive — 400; unknown category — 404.
Warehouses
URL - /bapi/warehouses
GET warehouses
Warehouses available to the API key; deleted ones are not returned.
| Parameter | Type | Required | Description |
|---|---|---|---|
limit |
int | no | Page size, up to 1000. Default 500 |
offset |
int | no | Offset. Default 0 |
data[]: id, name, w_type (1 — main, 2 — dropshipping, 3 — negative stock allowed), position
(order in the list), created_at (UNIX timestamp).
Example response
{
"success": true,
"data": [
{
"id": 456,
"name": "Amazon Bags",
"created_at": 1587382361.0,
"w_type": 3,
"position": 0
},
{
"id": 8471,
"name": "Show Room",
"created_at": 1674476253.0,
"w_type": 1,
"position": 0
}
]
}
Suppliers
URL - /bapi/suppliers
A supplier is {"id", "name", "phone", "address", "comment", "created_at", "sup_not_paid"}, where sup_not_paid is
the unpaid amount for the supplier's shipments.
GET suppliers
Retrieve all suppliers. No parameters.
Example response
{
"success": true,
"data": [
{
"id": 1,
"user_id": 11,
"name": "Best Supplier Ltd",
"phone": "+380991234567",
"address": "Kyiv, Ukraine",
"comment": "Main supplier",
"created_at": "2024-01-15 10:00:00",
"sup_not_paid": 15000.00
}
]
}
POST suppliers
Add a new supplier. If a supplier with the same name already exists, returns the existing one without creating a duplicate.
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | yes | Supplier name |
phone |
string | no | Phone number |
address |
string | no | Address |
comment |
string | no | Comment |
Response: id — ID of the supplier, data — the supplier list. Error: name is required.
Example request
{
"name": "Best Supplier Ltd",
"phone": "+380991234567",
"address": "Kyiv, Ukraine"
}
Example response
{
"success": true,
"id": 42,
"data": [
{
"id": 42,
"user_id": 11,
"name": "Best Supplier Ltd",
"phone": "+380991234567",
"address": "Kyiv, Ukraine",
"comment": "",
"created_at": "2024-01-15 10:00:00",
"sup_not_paid": 0.00
}
]
}