Troubleshooting
Common integration issues and how to resolve them
The most common issues operators hit during integration, and how to resolve them.
403 "Request blocked" / "Generated by cloudfront"
This is an IP whitelist issue, not a signature problem — the request never reached our API. Your server's outbound IP must match the address registered during onboarding. It usually means you're calling from a different IP than the one we have on file (a VPN, proxy, a teammate's machine, or a tool like Postman). Confirm you're calling from your registered outbound IP. See Security.
Game launch fails or the session expires immediately
The launch URL carries a one-time login token (OTL) that is single-use and short-lived (valid ~2 hours). Don't cache, persist, or reuse it as a permalink — once consumed it fails. Call /game/url to mint a fresh URL for each launch. (Within a running session, players can switch games via the in-game tracks overlay without re-launching.)
Common /game/url mistakes
- Wrong path —
/game/game/url(double/game/) instead of/game/url. - Sending
depositUrl: "undefined"(the string) — omit the field or sendnull. - Setting
partnerIdequal tooperatorId— they are different values (see Multi-brand).
Demo mode works but real-play doesn't
Demo/fun mode bypasses your /balance call entirely, so a broken /balance only surfaces in real play. If demo works but real-play fails, your /balance endpoint is the prime suspect — check for a 404, a malformed URL, or a request that isn't reaching you (unsigned/blocked). Use a fresh clientSessionId when retrying to avoid a cached bad session.
Testing signatures without our private key
Signing is one-directional: we sign every outbound callback (/balance, /bet, /win, /rollback) with our private key, and you verify it with the public key we share at onboarding. We can't share our private key — that would defeat verification. To test your verification logic:
- Point your tests at our staging environment, where every callback is signed correctly; or
- Bypass the signature check in your local mock/test configuration when you're simulating our callbacks yourself.
See Security for the verification details.
Stuck or pending rounds (a bet, but no win/rollback)
A round stuck in "pending" almost always means your /win or /rollback callback timed out or returned a non-200. Our /bet call has an ~8-second deadline; if /bet times out we automatically issue a /rollback, and we retry failed /win//rollback callbacks with exponential backoff. So:
- Keep your callback endpoints fast and always-200 (error states go in the JSON
statusfield, not the HTTP code — see Operator API). - If a round is still stuck after a few minutes, send us the round ID and we'll re-push the settlement.
- If we have no record of the round on our side, the bet never reached us (e.g. a momentary wallet-API timeout at placement) — there's nothing to settle, and any pending debit on your wallet for that transaction should be voided/rolled back.
Rollback retries look like new transactions
For /rollback, dedupe on referenceTransactionId — the original bet being refunded, which stays constant across retries. Do not dedupe on the per-request transactionId, which is unique for each rollback attempt. (This differs from /win, where transactionId is the dedup key.) The rollback payload has no amount field — look up the original bet by referenceTransactionId and refund that amount.