Developers
An HTTP status and a JSON body with the reason.
Authentication, permission and limit errors follow RFC 9457
(Content-Type: application/problem+json):
{
"type": "https://bm.consulting/en/developers/errors#forbidden_permission",
"title": "Forbidden",
"status": 403,
"detail": "This token does not grant sales:invoices.read.",
"code": "forbidden_permission",
"required_permission": "sales:invoices.read",
"error": "Forbidden"
} | Field | What it holds |
|---|---|
type | Link to the explanation of the error on this page. |
title · status | Name and HTTP status. |
detail | Human-readable explanation. It may change. |
code | Stable code to program against (table below). |
required_permission | On forbidden_permission: the permission the route requires. |
scope · window | On rate_limited: the level that hit the limit (token, acct or user) and the window (minute or month). |
error | Always present, kept for compatibility: the title, or the message on validation errors. |
Validation errors of each operation (400, 404, 409, 422) always carry
error with the reason; those raised by the API core also use the format above, with
code set to http_ plus the HTTP status.
code | HTTP | When |
|---|---|---|
unauthorized | 401 | The token is missing, unknown, disabled, revoked or expired. |
account_bound_not_allowed | 403 | The route does not accept tokens bound to a client account. |
forbidden_permission | 403 | The token lacks the route permission, given in required_permission. |
ip_not_allowed | 403 | The request does not come from an IP in the token allowlist. |
rate_limited | 429 | A per-minute limit or the monthly quota was reached; see window, scope and Retry-After. |
Program your integration against the HTTP status and the code field.
The detail and error texts are meant for people and may change.
| Status | Meaning | When it happens |
|---|---|---|
400 | Malformed request | A parameter or the body is not valid: invalid JSON, a date that is not ISO, a missing required field, a badly formatted amount. |
401 | Not authenticated | The token is missing, unknown, disabled, revoked or expired. |
403 | Forbidden | The token lacks the route permission (includes required_permission), the route does not accept account-bound tokens, the IP is not allowed or the resource belongs to another account. |
404 | Not found | The resource does not exist or belongs to another account. The API does not distinguish the two cases. |
409 | Conflict | The operation clashes with existing data; for example, a payout identifier that is already registered. |
422 | Unprocessable | The JSON is valid but a value breaks a business rule: an empty required field, an unknown reference. |
429 | Too many requests | A per-minute limit or the monthly quota of the token, account or user was reached. Includes Retry-After and the X-RateLimit-* headers. |
500 | Internal error | An unexpected BMC failure. Retry with a delay; if it persists, write to us. |
502 / 503 | Service unavailable | A service the operation depends on (for example document storage) is not responding. Retry with a delay. |
400, 404, 409 and 422: fix the request. Retrying it unchanged gives the same result.401: check that the token is still active and valid; otherwise create or rotate another (Authentication).403: add the permission shown in required_permission to the token (Permissions) or check the IP list.429: wait the seconds given in Retry-After (Rate limits).5xx: retry with growing delays and a maximum number of attempts.