# API limits, pagination and errors

URL: https://bimpsoft.com/en/help/developers/api-limits/
Updated: 2026-11-06

> The Bimp API accepts up to 15 requests per second from one IP; the excess goes into a queue of 30 requests, and whatever does not fit gets a 429 response. Lists are paginated in three ways: offset/count, page/pageSize and the limit/lastId cursor. Errors have different shapes depending on the method.

## What the API request limit is

The maximum is 15 requests per second from one IP address. Requests over the limit are not rejected immediately but go into a queue of 30 requests and are processed in the following seconds. Requests that do not fit in the queue are returned with an HTTP 429 error.

For bulk exports, keep the rate below 15 requests per second and send requests sequentially rather than in several parallel streams from one IP.

## What to do with a 429 response

A 429 response means the limit was exceeded. Its body has this shape:

```json
{
  "success": false,
  "error": {
    "code": 429,
    "message": "<message>",
    "details": "<details>",
    "retryAfter": 1
  }
}
```

Wait for `error.retryAfter` and repeat the request. If 429 keeps recurring, increase the pause exponentially (1 s, 2 s, 4 s).

## What pagination types the API has

The API uses three types of pagination, depending on the method.

| Type | Parameters | Limits per specification | Where it is used |
|---|---|---|---|
| Offset | `pagination` object with `offset` and `count` in the `POST` body | `offset` from 0; `count` defaults to 10, maximum 100 | most `readList` and `readExternalIdsList` methods |
| Page | `page` and `pageSize` in the `GET` query string | `page` defaults to 1; `pageSize` defaults to 50, maximum 100 | `/org2/inventory/api-readList` |
| Cursor | `limit` and `lastId` in the `GET` query string | `limit` defaults to 50, maximum 200 | `/org2/inventory/api-readList/cursor`, `/org2/inventory/kits/api-readList/cursor` |

### Offset pagination

Pass `pagination` in the request body and increase `offset` by `count` until the response is shorter than `count`:

```bash
curl -X POST https://app.bimpsoft.com/org2/invoiceForCustomerPayment/api-readList \
  -H "access-token: <COMPANY_ACCESS_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"pagination": {"offset": 100, "count": 100}}'
```

For the maximum `count` value, see the reference for the specific method.

### Cursor pagination

Cursor pagination is intended for large sets (over 5000 items). The `orgId` and `warehouseId` parameters are required. In the first request do not pass `lastId`, and in the following ones use `data.next_cursor` from the previous response:

```bash
curl -G https://app.bimpsoft.com/org2/inventory/api-readList/cursor \
  -H "access-token: <COMPANY_ACCESS_TOKEN>" \
  --data-urlencode "orgId=<ORG_UUID>" \
  --data-urlencode "warehouseId=<WAREHOUSE_UUID>" \
  --data-urlencode "limit=200" \
  --data-urlencode "lastId=<NEXT_CURSOR>"
```

Response:

```json
{
  "success": true,
  "data": {
    "items": [
      { "productId": "<UUID>", "barcode": "", "article": "A-100", "quantity": 12, "reserved": 2, "available": 10, "batchId": null }
    ],
    "next_cursor": "<UUID>",
    "next_cursor_batch_id": null
  }
}
```

If `byBatches=true` is enabled, stock balances are split by batch; in that case pass `lastBatchId` from `next_cursor_batch_id` together with `lastId` (omit it if it is `null`). For exporting full stock balances, see [Exporting stock balances and prices to a website](https://bimpsoft.com/en/help/developers/sync-stock-and-prices/).

## What errors look like

The shape of the error body depends on the method, so handle the HTTP code first and then the body.

| Code | When | Body shape per specification |
|---|---|---|
| 422 | request validation error | `{"error": "...", "message": "...", "details": "..."}` (`error` and `message` are required) |
| 404 | object not found (for example, `/org2/inventory/api-read/{productHex}/stock`) | `{"status": "error", "message": "..."}` |
| 429 | request limit exceeded | `{"success": false, "error": {"code": 429, "message", "details", "retryAfter"}}` |

Successful responses look like `{"success": true, "data": ...}`. Some methods return `null` in `data` when the object does not exist (for example, `readByExternalId`).

## Common problems

**A bulk export periodically returns 429.** Cause: more than 15 requests per second from one IP were sent, and the queue of 30 requests filled up. Solution: send requests sequentially with a pause and retry after `retryAfter`.

**An offset export of a large list gets slower and slower.** Cause: deep pages of offset pagination are more expensive. Solution: for stock balances use the cursor method; for other lists narrow the selection with period filters.

## FAQ

**How many requests per second does the Bimp API allow?**

Up to 15 requests per second from one IP. The excess goes into a queue of 30 requests and is processed in the following seconds; requests that do not fit in the queue are returned with a 429 error.

**What should I do with a 429 response?**

Wait and repeat the request. The 429 response body contains the field error.retryAfter. After that, keep the request rate below 15 per second.

**Which pagination should I use to export all stock balances?**

Cursor pagination: GET /org2/inventory/api-readList/cursor. It is intended for large datasets and does not slow down on deep pages.
