Error reference
Every error the API answers with, and the codes your wallet answers us with.
Error body
A refusal from /v1 is a flat object. Branch on error and retryable, not on the status alone.
error
{
"error": "VALIDATION_FAILED",
"message": "One or more fields are invalid.",
"retryable": false,
"fields": [ { "field": "ttl_minutes", "message": "must be between 1 and 1440" } ] // filled on VALIDATION_FAILED only
}retryable: true means the outcome is unknown: repeat the call with the same ids. false is settled: the same call fails the same way.
API errors
| error | HTTP | Retry | Meaning | Your action |
|---|---|---|---|---|
| UNAUTHORIZED | 401 | see meaning | Signature headers missing, key unknown or revoked, digest does not match, or the timestamp is more than 5 minutes from our clock. Only the clock case answers retryable: true. | Check the three X-Agg-* headers and the signed payload with the signature tester; compare your clock with GET /v1/ping. |
| VALIDATION_FAILED | 422 | no | A field is missing, out of range or of the wrong JSON type, or the body is not valid JSON. Every broken field is listed in fields with the rule it broke; "body" when the JSON does not parse. | Fix the request. The same call fails the same way. |
| NOT_FOUND | 404 | no | No such session, grant, bonus campaign, transaction or round for your operator. | Check the id. Ids of another operator are never found. |
| GAME_UNAVAILABLE | 409 | no | The game is not in your window, whether or not it exists. | Refresh the catalogue from GET /v1/games and stop showing the game. |
| GAME_RESTRICTED_IN_COUNTRY | 409 | no | The game cannot be played in the player's country. | Hide the game for that player. GET /v1/games?country= leaves such games out in advance. |
| NO_DEMO | 409 | no | The game has no fun-play mode. | Show no demo button where has_demo is false. |
| PLAYER_BLOCKED | 409 | no | The aggregator has stopped this player. No session opens until the block is lifted. | Do not open games for the player; contact us if the block is unexpected. |
| FREE_SPINS_REFUSED | 409 | no | The game provider does not take grants, refused this one, or the games cannot be granted together. message carries the reason. | Read message. Grant the games separately; pick bet_amount from GET /v1/free-spins/bet-options. |
| BONUS_CAMPAIGN_REFUSED | 409 | no | The game provider behind the games does not take bonus campaigns, or refused this one: a campaign type, trigger or currency it does not take, or a player it would not accept. message carries the reason. | Read message. Check GET /v1/bonus-campaigns/options for the game and place the campaign again with what it lists, under a new reference. The same body fails the same way. |
| ADDRESS_NOT_ALLOWED | 403 | no | The request is signed correctly but comes from an address that is not on your allowlist. message names the address we saw. | Add the address or its network under Credentials in the operator portal, or call from a listed server. |
| VALIDATION_RUN_REFUSED | 409 | no | Sandbox only: a wallet test suite run is already going, or the 10 runs of the hour are used. message says which. | Wait for the run to finish, or for the hour to pass. |
| RATE_LIMITED | 429 | yes | Over the per-minute limit set for your operator. The window is a calendar minute; Retry-After gives the seconds until it restarts. | Wait the Retry-After seconds, then retry with the same ids. |
| UPSTREAM_UNAVAILABLE | 503 | yes | A service behind the API did not answer in time or answered with an error (HTTP 503), or something failed on our side (HTTP 500). The outcome is unknown. | Retry with the same ids and exponential backoff. Calls that create something are idempotent on the ids you send. |
Every refusal uses this body. A request whose JSON cannot be parsed is VALIDATION_FAILED with HTTP 422, and an unexpected fault on our side is UPSTREAM_UNAVAILABLE with HTTP 500.
Wallet errors (what you answer)
| error | HTTP | Retry | Meaning | Your action |
|---|---|---|---|---|
| INSUFFICIENT_FUNDS | 402 or 409 | no | The balance does not cover the bet. | Refuse the bet, change nothing. |
| BET_LIMIT | 403 or 409 | no | The stake breaks a limit you apply: responsible-gaming, per-bet or loss limit. | Refuse the bet. Any code containing LIMIT is read as a limit. |
| PLAYER_BLOCKED | 403 | no | The player is blocked or self-excluded on your side (SELF_EXCLUDED is accepted too). | Refuse bets. Still credit win and rollback: they settle money already staked. |
| PLAYER_NOT_FOUND | 404 | no | You have no player with this player_id. | Refuse. It points at a session opened with a wrong player_id. |
| CURRENCY_MISMATCH | 409 | no | The currency is not the player's wallet currency. | Refuse. Never convert: a session is one currency from open to close. |
| SESSION_CLOSED | 409 | no | You no longer accept bets on this session. | Refuse bets only. Wins and rollbacks may arrive after a session closes or expires and must be credited. |
| INVALID_SIGNATURE | 401 | no | X-Agg-Signature does not verify with the key named in X-Agg-Key-Id. | Refuse before parsing the body. During a key rotation accept either of your two keys. |
| VALIDATION_FAILED | 400 | no | A field you need is missing or malformed. | Refuse and tell us: the body is ours to fix. |
More on each, and what is not an error: Wallet errors.
