# Errors & limits

## HTTP status codes

| Code | Meaning | What to do |
|---|---|---|
| `200` | Success | |
| `400` | Bad request: missing parameter or wrong data type | Fix the request using `message` |
| `403` | Wrong API key, or not allowed to perform this action | Check the key and permissions; do not retry unchanged |
| `404` | Shop or record not found | Check the IDs in the path |
| `422` | Data fails business validation | Fix the data using `message` |
| `429` | Rate limit reached (code `106`) or too many wrong keys (code `109`) | Wait, then retry (see below) |
| `500`, `502`, `503`, `504` | Server error or temporary overload | Retry later with increasing waits |

## Error body

Errors return JSON with `success: false`:

```json
{
  "success": false,
  "message": "You have reached the limit of requests",
  "error_code": 106
}
```

| Field | Meaning |
|---|---|
| `success` | Always `false` for errors |
| `message` | Human-readable description; wording may change over time |
| `error_code` | Numeric error code, when provided. Handle errors in code with this field, not with `message` |
| `error` | Stable error name, when provided |
| `message_code` | POS business message code, when provided |
| `permission` | The missing permission when access is denied, when provided |

Common error codes:

| `error_code` | HTTP | Meaning |
|---|---|---|
| `105` | 403 | Invalid `api_key` |
| `106` | 429 | Rate limit reached |
| `109` | 429 | Too many wrong `api_key` attempts, locked for 5 minutes |

## Rate limits

Limits apply per endpoint (record IDs in the path do not count separately) and per:

- **Shop API key**: shop. All keys of the same shop share the quota.
- **Account API key**: account + shop.

| Request type | Limit |
|---|---|
| Reads (`GET`) | Under 30 requests per second |
| Writes (`POST`, `PUT`, `DELETE`) | Under 100 requests per second |
| `GET /shops/{SHOP_ID}/inventory_histories` | 3 requests per second |

Going over returns `429` with `error_code` `106`.

## Retries

- `429` and `5xx`: wait and retry with increasing delays (for example 1, 2, 4, 8 seconds) and stop after a few attempts. Honour the `Retry-After` header when present.
- Other `4xx`: fix the request; sending it again unchanged fails again.
- A write (`POST`) that failed with a network error or timeout: check whether the record was created before sending it again, to avoid duplicates.
- Large syncs: run sequentially or with few parallel workers, and prefer a large `page_size` over many small requests.
