Skip to content

Conventions

The same rules apply to every endpoint — learn them once.

Response envelope

Success:

{
  "success": true,
  "data": { /* object */ } ,
  "meta": { /* optional: pagination, balances, receipts */ }
}

data is either a single object or an array, depending on the endpoint. meta is present on list endpoints (pagination) and on writes that produce side data (a new account balance, a fiscal receipt, …).

Error:

{
  "success": false,
  "error": { "code": "validation_error", "message": "name is required",
             "details": { "field": "name" } }
}

code is a stable string (see Errors); message is human-readable; details is optional structured context. The HTTP status matches the error (4xx/5xx).

Data types

Type Rule Example
Money exact decimal string, never a float "1234.50"
Time ISO-8601, UTC "2026-07-20T08:28:59"
Quantity number (int when whole) 3, 1.5
Boolean real true/false (not 0/1) true
Missing value null (the internal 0/"" sentinels are normalised) null
Keys snake_case warehouse_id

Money is a string so you never lose precision to floating point. Parse it with a decimal type.

Pagination

List endpoints accept ?limit= and ?offset=:

curl "https://crm.h-profit.com/bapi-v2/products?limit=50&offset=100" \
  -H "Authorization: hp_live_your_key_here"
  • limit is clamped to each resource's maximum (defaults vary; e.g. products 100, sales up to 5000).
  • The meta block echoes the paging:
{ "meta": { "limit": 50, "offset": 100 } }

Page by increasing offset until you receive fewer than limit rows.

Fetching a whole list at once

Reference-style resources — suppliers, categories, product_sync — are paginated by default too, but you can pull the entire list in one request with ?all=1:

curl "https://crm.h-profit.com/bapi-v2/categories?all=1" \
  -H "Authorization: hp_live_your_key_here"

meta.limit comes back as null to signal that no cap was applied:

{ "meta": { "limit": null, "offset": 0, "total": 820 } }

Reach for ?all=1 when you need the full set locally (a category tree, a product→remote binding map); for large tables prefer normal paging. (categories?tree=1 also returns the whole set, already nested.)

HTTP methods

Method Meaning
GET read (list or single)
POST create (or a bulk action)
PUT update
DELETE delete

Request bodies are JSON (Content-Type: application/json). Filters for GET go in the query string; bodies for POST/PUT/DELETE go in JSON.

Rate limits

Each API key may make 120 requests per minute. The minute starts with the key's first request, and every request counts, including ones that fail. A composite /query counts as one request. Every response carries the current state:

Header Meaning
X-RateLimit-Limit requests allowed per minute
X-RateLimit-Remaining requests left in the current minute
X-RateLimit-Reset seconds until the counter resets

Over the limit the API answers 429 with code: rate_limited and a Retry-After header (seconds to wait). If your integration needs a higher limit, contact support.

CORS

All responses send permissive CORS headers (Access-Control-Allow-Origin: *) and answer OPTIONS preflight with 204, so the API can be called from a browser.

Localisation

Some values (category names, units) are localised to the key owner's account language, not the request. There is no per-request language switch.