Errors

What an API error looks like, how to handle it and which errors are possible today.

An error returned by the application always has the same shape, on any endpoint and with any HTTP status.

{
  "error": {
    "code": "unknown_filter",
    "message": "Неизвестные параметры: verbose",
    "details": {
      "unknown": [
        "verbose"
      ],
      "allowed": [
        "page",
        "perPage",
        "sort",
        "dir"
      ]
    }
  }
}
FieldTypePresentDescription
errorobjectalwaysThe error itself. A successful response never has this field.
error.codestringunauthorized cookie_auth_not_allowed forbidden unknown_filter bad_body too_large not_found too_many_requests not_implemented internalalwaysError code. The client decides what to do by it. All codes are listed in the catalogue below.
error.messagestringalwaysExplanation for a person. The text is in Russian and may change: do not parse it in code.
error.detailsany valuenot alwaysDetails, if any. Their content depends on the code; for authentication errors it holds rule.

How to handle an error

  1. The HTTP status says whose fault it is. A 4xx status: the request must be fixed, retrying it unchanged gives the same response. A 5xx status: a failure on our side.
  2. error.code says what exactly is wrong.
  3. error.details.rule, if present, names the exact reason. Authentication errors differ by it.

Handle an unknown code by its HTTP status: new codes and rules may appear, and the changelog announces them.

The text in error.message is written for a person, in Russian, and may change. Do not parse it in code: branch on error.code and error.details.rule.

If the application is down entirely, a 502 or 504 response comes from the proxy in front of it, and such a response has no body in this shape. Do not parse it as JSON; treat it like any other 5xx.

Request ID

Every response, successful or not, has an X-Request-Id header. Save it together with the error in your log and quote it to support: it lets us find the request at once.

Error catalogue

These errors are common to all endpoints. Under each row you can expand an example response from a running server.

Authentication

HTTPCode and ruleWhen it happens and what to do
401unauthorized

There is no Authorization header, the key is malformed, no key has this public part, or the secret does not match. The response deliberately does not say which of the four happened.

Check that the header is sent and that the key is copied in full, without spaces or line breaks.

Example response
GET /api/v1/me

HTTP/1.1 401

{
  "error": {
    "code": "unauthorized",
    "message": "Ключ API не принят"
  }
}
401unauthorizedapi_key_revoked

The key is valid but has been revoked or replaced by regeneration. Revocation is final.

Get a new key from your administrator.

Example response
HTTP/1.1 401

{
  "error": {
    "code": "unauthorized",
    "message": "Ключ API отозван: получите новый",
    "details": {
      "rule": "api_key_revoked"
    }
  }
}
401unauthorizedapi_key_expired

The key is valid but has expired.

Get a new key from your administrator.

Example response
HTTP/1.1 401

{
  "error": {
    "code": "unauthorized",
    "message": "Срок ключа API истёк: получите новый",
    "details": {
      "rule": "api_key_expired"
    }
  }
}
401unauthorizedapi_key_disabled

The key is valid but an administrator has disabled it. A disabled key can be enabled again.

Ask your administrator to enable the key.

Example response
HTTP/1.1 401

{
  "error": {
    "code": "unauthorized",
    "message": "Ключ API выключен",
    "details": {
      "rule": "api_key_disabled"
    }
  }
}
401cookie_auth_not_allowed

The request came with a session cookie of the operator console. This happens when a request is copied from the browser's network panel.

Remove the cookie and send the API key in the Authorization header.

Example response
HTTP/1.1 401

{
  "error": {
    "code": "cookie_auth_not_allowed",
    "message": "API мерчанта не принимает сессию консоли: нужен ключ API"
  }
}
403forbiddenmerchant_not_active

The key is valid but the merchant is not active: not yet activated, disabled or archived.

Check the merchant's status with your administrator.

Example response
HTTP/1.1 403

{
  "error": {
    "code": "forbidden",
    "message": "Мерчант не в работе: запросы не принимаются",
    "details": {
      "rule": "merchant_not_active"
    }
  }
}
403forbiddenenvironment_closed

The key is valid and the merchant is active, but this key's environment is closed for the merchant.

Use a key of the other environment or ask your administrator to open this one.

Example response
HTTP/1.1 403

{
  "error": {
    "code": "forbidden",
    "message": "Боевой контур мерчанту закрыт",
    "details": {
      "rule": "environment_closed"
    }
  }
}

Request

HTTPCode and ruleWhen it happens and what to do
400unknown_filter

The URL has a parameter the endpoint does not have. An unknown parameter is never silently ignored: details.unknown names it.

Remove the parameter or fix its name.

Example response
GET /api/v1/me?verbose=1

HTTP/1.1 400

{
  "error": {
    "code": "unknown_filter",
    "message": "Неизвестные параметры: verbose",
    "details": {
      "unknown": [
        "verbose"
      ],
      "allowed": [
        "page",
        "perPage",
        "sort",
        "dir"
      ]
    }
  }
}
400bad_body

The request body could not be parsed as JSON.

Fix the request body.

Example response
HTTP/1.1 400

{
  "error": {
    "code": "bad_body",
    "message": "Тело запроса не разобралось"
  }
}
413too_large

The request body is larger than allowed.

Make the request body smaller.

Example response
HTTP/1.1 413

{
  "error": {
    "code": "too_large",
    "message": "Тело запроса больше разрешённого"
  }
}
404not_found

No such path: a typo in the path or the wrong HTTP method.

Check the path and the method against the reference.

Example response
GET /api/v1/unknown

HTTP/1.1 404

{
  "error": {
    "code": "not_found",
    "message": "Адрес не найден"
  }
}

Rate limit

HTTPCode and ruleWhen it happens and what to do
429too_many_requests

The rate limit for requests from one address has been exceeded.

Retry later: the RateLimit-Reset header says in how many seconds the count starts over.

Example response
HTTP/1.1 429

{
  "error": {
    "code": "too_many_requests",
    "message": "Слишком часто. Повторите позже.",
    "details": {
      "limit": 300,
      "windowSeconds": 60
    }
  }
}

Our side

HTTPCode and ruleWhen it happens and what to do
501not_implemented

The path is reserved for an endpoint that has not been released yet.

Do not use the path until it appears in the reference and in the changelog.

Example response
POST /api/v1/payments

HTTP/1.1 501

{
  "error": {
    "code": "not_implemented",
    "message": "Не реализовано: модуль merchant-api, фаза 1",
    "details": {
      "module": "merchant-api",
      "phase": "фаза 1",
      "why": "Создание платежа требует движка роутинга и адаптера провайдера, и ни того, ни другого нет. Ответ-заглушка с идентификатором платежа хуже отказа: касса казино сочтёт платёж принятым и будет ждать уведомления, которого никто не пришлёт."
    }
  }
}
500internal

A failure on our side. The cause is not disclosed; details.requestId holds the request ID.

Retry a read request later. If it keeps happening, give support the request ID.

Example response
HTTP/1.1 500

{
  "error": {
    "code": "internal",
    "message": "Внутренняя ошибка",
    "details": {
      "requestId": "00000000-0000-4000-8000-000000000000"
    }
  }
}

API v1 · built 2026-11-12 · release 9f884b9

The API reference is built from the server code: it never describes an endpoint that does not exist.