Errors¶
Two directions, two sets of rules: the errors 19flip returns to you on launch-game, and the HTTP statuses your wallet should return to 19flip on callbacks.
Getting the second part right decides whether a player sees "insufficient funds" or "technical error", and whether money operations are retried.
Errors returned by 19flip¶
Response format¶
Every error from the operator API has the same JSON body:
{
"success": false,
"code": "GAME_UNAVAILABLE",
"traceback": "Xk3P9qLm2Z",
"detail": "Game block-boost is under maintenance",
"errors": null
}
| Field | Type | Description |
|---|---|---|
success |
boolean | Always false. |
code |
string | Stable machine-readable code (table below). Branch on this and on the HTTP status. |
traceback |
string | 10-character id of this error in our logs. Quote it when contacting 19flip support. |
detail |
string or null | Human-readable message. Wording may change; do not parse it. |
errors |
array or null | Only for request validation errors: [{"loc": ["body", "<field>"], "msg": "<message>"}]. Otherwise null. |
Codes¶
| HTTP | code |
Returned on launch-game when |
Retry? |
|---|---|---|---|
| 400 | REQUEST_ERROR |
Invalid body; unknown game_id; currency not supported or not allowed; RTP not allowed |
No – fix the request |
| 401 | AUTH_ERROR |
Api-Key missing or unknown |
No – check the key |
| 403 | IP_NOT_ALLOWED |
Caller IP not in your allowlist | No – ask 19flip to update the allowlist |
| 403 | OPERATOR_SUSPENDED |
Your account is suspended | No – contact 19flip |
| 403 | GAME_UNAVAILABLE |
Game disabled, under maintenance, not configured, or switched off for your account | Later (maintenance) |
| 403 | PLAYER_BLOCKED |
The player is blocked by 19flip (LIVE only) |
No |
| 502 | EXTERNAL_SERVICE_ERROR |
The game refused or could not open the session; detail starts with Game API error: |
Yes, if the game was unreachable; no, if the game refused (e.g. DEMO in Bingo Bongo) |
| 500 | UNKNOWN_ERROR |
Unexpected failure. Also returned for a wrong path or HTTP method (detail Not Found / Method Not Allowed) |
Yes, with backoff |
Other codes exist in the platform (INSUFFICIENT_FUNDS 402, BET_LIMIT_EXCEEDED 400, NOT_FOUND 404, FORBIDDEN 403, CONFLICT 409, TOO_MANY_REQUESTS 429). They are used between 19flip and its games and are not returned by launch-game.
The live banner endpoints use the same envelope. GET /api/operator/v1/banners can return AUTH_ERROR, IP_NOT_ALLOWED and OPERATOR_SUSPENDED as above. Both state endpoints return 404 NOT_FOUND for an unknown key, an unknown or disabled banner, or a currency you cannot use, and 400 REQUEST_ERROR for a currency that is not three letters. When the game is down, the state endpoints do not fail. They return 200 with "status": "unavailable".
The round history endpoints use the same envelope and the same AUTH_ERROR, IP_NOT_ALLOWED and OPERATOR_SUSPENDED codes. GET /api/operator/v1/rounds/{game_round_id} returns 404 NOT_FOUND for a round that does not exist or has not finished; a missing game_id or a bad parameter returns 400 REQUEST_ERROR.
The full list of launch-game conditions with example detail values is in Launch game.
What your wallet should return¶
Your answer to a wallet callback is interpreted by its HTTP status first:
| Situation | Your HTTP status | Body | What 19flip does |
|---|---|---|---|
Operation applied, or already applied under this idempotency_key |
200 |
Transaction or balance response | Success |
| Player cannot afford the bet (or a win rollback, if you refuse negative balances) | 402 |
{"error": "insufficient balance"} |
Final. The game is told INSUFFICIENT_FUNDS and can offer the player a top-up. Not retried. |
| Bad signature or API key | 401 |
{"error": "Invalid signature"} |
Final. Recorded as failed. Not retried. |
| Unknown player | 404 |
{"error": "player not found"} |
Final. Not retried. |
| Any other refusal (validation, player restricted, currency mismatch) | 400, 403, 409 or 422 |
{"error": "<reason>"} |
Final. Not retried. |
| You could not process the request and did not apply it (database down, dependency timeout) | 500 / 503 |
anything | Retried (up to 3 attempts in total), then outcome unknown |
| You are not sure whether you applied it | 500 / 503 |
anything | Same as above. Deduplication makes the retry safe. |
Rules:
- Use
402for insufficient funds. It is the only signal that reliably reaches the game as "insufficient funds". - Never answer
200with"status": "FAILED"to decline. 19flip passes a2xxto the game as a completed call, and some games treat any2xxas money moved. Declines must be4xx. - Never answer
4xxif you might have applied the operation.4xxmeans "definitely not applied" and is not retried. - Never answer
5xxfor a request you have refused on purpose. It will be retried three times and then escalated as an unknown outcome.
How 19flip reads a 4xx body¶
19flip takes the error text from the message field of your JSON body, else from error, else the whole body. Any 4xx is treated as insufficient funds when either:
- the status is
402, or - that text contains
insufficientorbalance(case-insensitive).
Keep the word balance out of other errors
A 404 with {"error": "Player balance not found"} or a 400 with {"message": "Invalid balance currency"} is classified as insufficient funds, and the player is told to top up. Word other refusals without balance or insufficient.
All other 4xx answers reach the game as a request error with the text Provider error (<status>): <text>.
Timeouts and 5xx¶
5xx, timeouts (10 s) and connection errors are retried: 3 attempts in total with 1 s and 2 s pauses. If all attempts fail, the game gets EXTERNAL_SERVICE_ERROR and 19flip records the operation as outcome unknown. See Idempotency & retries for how such operations are settled.
What the player sees¶
| Wallet answer | Typical game behaviour |
|---|---|
402 on /bet/debit |
"Not enough funds" message; no bet placed |
Other 4xx on /bet/debit |
Generic error; no bet placed |
5xx / timeout on /bet/debit after all retries |
Generic error; the bet's outcome is unknown until it is repeated, rolled back or resolved |
5xx / timeout on /win/credit after all retries |
Outcome unknown. Bingo Bongo keeps the win as owed and repeats it later with the same key; Block Boost and Mister Twister report an error in the round. The operation appears in 19flip's queue for manual resolution. |
4xx on /win/credit |
Treated as a final refusal. 19flip stores it under the idempotency_key and answers any repeat of that key itself, without calling you again. The player does not receive the win until it is settled manually (Bingo Bongo escalates such payouts to its staff). Never answer 4xx to a valid win. |