# IOP Global integration reference Reviewed 2026-11-12. Public documentation: https://docs.iop.global/docs Use the gateway host and credentials issued to your account. ## Introduction One IOP integration for Originals, casino games and sportsbook content available on your account. You keep the player balance; games settle through your HTTPS wallet webhook. Amounts are integer minor units with two decimal places of the currency in each wallet request: 100 = 1.00. Never assume every request is USD. Base URL Use the gateway base URL issued with your account. Stage and production have separate credentials. Examples use https://YOUR_GATEWAY_HOST; replace it before calling. Start with the Quickstart or download the integration reference. Last reviewed: 12 November 2026. ## How it works Your server requests a game launch from IOP. Embed the returned game URL in your site. IOP calls your wallet for balances, bets, wins and rollbacks. Your durable wallet ledger is authoritative for player funds. Use catalogue identifiers exactly as returned. IDs are opaque strings: do not infer a route, studio or game from their format. One round can have several money movements. Idempotency belongs to TransactionId, not to event_id. Game availability, native currency, free spins and billing depend on your account configuration and the individual game. ## Credentials Setting | Use | apiKey | Your server-side API key. Send it in the launch JSON body; catalogue and billing reads use the x-api-key header. Never expose it in browser code or a URL. | webhookUrl | Your public HTTPS wallet endpoint, registered in Integration → Config. It must be reachable before testing. | Wallet contract v2 | Implement rollback and have rollback support enabled before launching aggregated games. | Webhook signing secret | A separate per-account secret, provisioned with IOP when signing is enabled. It is not your apiKey. See Security. | Keep stage and production credentials separate. Request account activation and allowed content through your IOP manager. ## Launch a game POST/gw/launch Call from your backend. For real-money play, authenticate the player on your platform first. Field | Description | apiKey | Required account API key. | gameId | Required game ID from the account catalogue, unchanged. | login | Your stable player identifier, required for real-money play. | currency | Requested session currency, default USD. Support varies by game and account. Use the currency in each subsequent wallet request. | country | Player location as an ISO 3166-1 alpha-2 code, for example IN or DE. Also controls country-specific sportsbook presentation where configured. | ip | The player’s public IP address; supply their real public IPv4 address where required. Do not substitute your backend IP. | mobile | Boolean indicating mobile delivery. | token | Optional opaque session token echoed in wallet requests for correlation. It is not a substitute for callback authentication. | curl -X POST https://YOUR_GATEWAY_HOST/gw/launch -H 'Content-Type: application/json' -d '{"apiKey":"YOUR_API_KEY","gameId":"GAME_ID_FROM_CATALOG","login":"player-123","currency":"EUR","country":"DE","ip":"PLAYER_PUBLIC_IPV4","mobile":false,"token":"session-abc"}' On success, use launch_options.game_url. Originals can also return game limits and provably-fair seed information; these are not guaranteed for every game. ## Deliver the game Embed the returned URL. Preserve its query parameters; do not construct or rewrite the URL yourself. Test desktop and mobile, back navigation, reload and session expiry. Originals branding is configured in the backoffice. Do not put API keys into an iframe URL. ## Game catalog Use your account key in the x-api-key header for catalogue reads. Keep requests server-to-server. GET/gw/catalog/providersGET/gw/catalog/games Games can be filtered with providerId, search, page and country. Use provider IDs returned by the providers feed; follow the feed’s pagination. curl 'https://YOUR_GATEWAY_HOST/gw/catalog/games?country=DE&page=1' -H 'x-api-key: YOUR_API_KEY' Identifiers and artwork Keep IDs as strings and pass them unchanged into launches. Use the image URLs and provider logos returned by the feed, including their version parameters. Do not build image URLs from a studio name or strip query parameters. Refresh your cached catalogue after entitlement or artwork changes. The catalogue reflects account access when fetched. A subsequent launch can still fail because of current account status, currency, location, session validation or a temporary outage. Handle launch responses explicitly. Free spins Free spins require account activation and an eligible game/currency. The regular catalogue alone does not prove eligibility. Use POST /gw/freespins/games to read eligible games and POST /gw/freespins/bets with gameId and currency to read supported bet levels. Authenticate with x-api-key. Issuance, status and cancellation use /gw/freespins/grant, /gw/freespins/status and /gw/freespins/cancel, all POST. Coordinate the bonus-wallet contract and run the free-spin acceptance tests with IOP before issuing campaigns. Never turn an uncertain grant response into a new claim ID. ## Wallet webhook overview Host one HTTPS endpoint accepting JSON POST requests. Successful responses use HTTP 200 and {"status":"success","balance":250000,"currency":"EUR"}. Balance is a safe integer in the request’s currency. Action | Purpose | getBalance | Read the player’s current spendable balance in the requested currency. | processGameResult | Atomically debit betAmount and credit winAmount, recording TransactionId. | rollback | Reverse the referenced movement exactly once; required for aggregated games. | Durable processing The outline below is pseudocode, not a ready-to-run wallet. Use a database transaction, concurrency control and a unique idempotency constraint scoped to your IOP account and TransactionId. authenticate callback and validate action, player, currency and integer amounts begin database transaction reserve the account + TransactionId with a unique constraint if already committed: verify the same movement, return current balance without applying again lock the player's wallet for this currency for a new bet: validate funds before debit for a win: credit the stated amount even when another win exists in the round for a rollback: resolve and reverse the referenced movement only once persist the wallet movement, result and idempotency record atomically commit before returning success Do not use an in-memory Set for financial idempotency. A process restart, concurrent request or lost HTTP response must not cause a second debit or credit. ## getBalance Return the current spendable balance in the request currency. Balance reads can happen during play as well as launch. {"action":"getBalance","userId":"player-123","currency":"EUR","token":"session-abc","timestamp":1794484800000} {"status":"success","balance":250000,"currency":"EUR"} The optional currency in your response is an echo, not an instruction to convert. Never return a EUR balance for a USD request. ## processGameResult Each request is one settlement movement. A bet and win may arrive separately or together, and multiple wins may share a round. {"action":"processGameResult","userId":"player-123","currency":"EUR","betAmount":0,"winAmount":4500,"gameId":"GAME_ID_FROM_CALLBACK","event_id":"round-123","TransactionId":"credit-456","token":"session-abc"} {"status":"success","balance":254500,"currency":"EUR"} Apply winAmount − betAmount atomically. An insufficient-funds rejection must use {"status":"error","error":"Insufficient funds"}, without applying the rejected movement. Credit legitimate win-only and promotional payments even when no bet exists on that event. A zero-bet, zero-win call moves no money and settles open bets as lost, but does not close the event_id: later wins can still arrive. Do not reject a new payout just because an earlier payout was accepted. Deduplicate by TransactionId. A changed ID is not sufficient evidence of a new economic payout when reconciling a disputed retry; ask IOP to map the original movement before manual recovery. ## rollback Reverse a previous movement in its original currency. Rollback requests have their own TransactionId and may include originalTransactionId identifying the movement being reversed. {"action":"rollback","userId":"player-123","currency":"EUR","rollbackOf":"bet","betAmount":100,"event_id":"round-123","TransactionId":"rollback-789","originalTransactionId":"debit-123"} rollbackOf: "bet": refund the referenced betAmount. rollbackOf: "win": reverse the referenced winAmount. Record the reversal and idempotency result atomically. An identical retry must not reverse twice. If the original movement never applied, do not create a refund out of nothing. Record the resolved no-op so a delayed original cannot subsequently debit it. Do not silently clamp a reversal or report success for an amount you did not reverse. Resolve unsupported or ambiguous cases with IOP. A network timeout is not a rollback request. Do not invent a refund because an HTTP response was lost. ## Integration flow Your server -> IOP: POST /gw/launch IOP -> your wallet: getBalance IOP -> your server: launch_options.game_url Player opens the game IOP -> your wallet: processGameResult (bet) IOP -> your wallet: processGameResult (one or more wins, possibly later) IOP -> your wallet: rollback (when a movement must be reversed) Sportsbook events may settle hours or days after the bet. Retain round and transaction records independently of the browser session. A lost response can lead to redelivery: acknowledge an already committed TransactionId without applying it again. ## Money & settlement rules Rule | Requirement | Units | Integer minor units, two decimal places for every supported currency: 100 = 1.00, including currencies normally displayed without decimals. Reject malformed amounts rather than rounding. | Native currency | Originals settle in the session currency. Aggregated games use native currency only when enabled on the account and supported for that game. Other sessions may settle in USD. Always use the currency in each wallet request. | Minimum stake | Originals minimum is 0.10 of the session currency. Other games have their own limits. | event_id | Groups round activity; it is not a unique payout key or an instruction to reject later wins. | TransactionId | The settlement idempotency key. Persist it together with the balance change. | Timeout | An uncertain outcome: the wallet may have committed even though its reply was lost. Reconcile and deduplicate; reverse only on an explicit rollback. | Retention | Keep durable transaction and reversal records after the player session ends. Support late wins and sportsbook settlement. | ## Billing & limits Billing can use client fees or a legacy GGR allowance. Check which basis your account uses; a fee balance and a GGR limit are not interchangeable. For fee billing, available allowance is the posted USD balance plus credit, less pending fees. Rates follow your agreement and studio overrides. Pending fees consume allowance before monthly settlement. When blocking is enabled, exhaustion blocks new launches and bets; existing bets can still settle. GET/gw/billing/status Send x-api-key, no body and no query string. Read server-to-server and respect refreshAfterSeconds. Field | Meaning | basis | FEES or GGR; use the matching label. | usagePercent | Display value only. null means no confirmed figure, not zero usage. | reached / blocked | Use these exact flags rather than a rounded percentage to determine whether the billing restriction is active. | state | AVAILABLE, EXHAUSTED, UNAVAILABLE, PENDING, DISABLED or UNLIMITED. | usedCents / allowanceCents / availableCents | USD cents, possibly negative; null when not applicable. | lastCheckedAt | UTC timestamp of the confirmed figures. | Payments and credit changes are handled by your manager. Confirm refreshed status before assuming access has resumed. The endpoint remains readable while the account is suspended. ## Errors A launch failure uses an HTTP status and a JSON error response. Preserve the response code and request correlation ID when contacting support; redact API keys and tokens. HTTP | Typical cause | 400 | Invalid or missing fields, unsupported currency or malformed country. | 401 | Missing or invalid API key. | 403 | Account, billing, game entitlement or location restriction. | 409 | A prerequisite or request state conflict, including missing rollback support. | 5xx / timeout | Temporary or uncertain failure. Inspect the response and reconcile any money operation before attempting recovery. | Wallet success means the movement committed durably. Return the current balance on an identical committed retry. Non-200 responses, an error envelope or timeouts do not by themselves prove whether money moved. Never return success merely to stop retries. ## Performance & timeouts Wallet latency directly affects gameplay. Aim for responses under 200 ms and keep the wallet and its database close together. The normal gateway wallet timeout is up to five seconds, but individual integrations can have a shorter remaining budget. Do not treat five seconds as guaranteed processing time. Keep unrelated reporting, risk scans and third-party calls off the settlement path. Use bounded connection pools and database transactions. Concurrent duplicate callbacks and redelivery after a lost response must remain safe. Monitor latency, timeouts, rejected money movements and unresolved transactions separately from normal insufficient-funds responses. Alert on changes by account and action rather than relying only on a rolling failure percentage. ## Security Use HTTPS and keep API keys and webhook signing secrets on the server. Arrange egress-IP allowlisting with IOP where required; an unguessable webhook URL is not authentication. Optional HMAC webhook signing When signing is configured for your account, IOP sends X-IOP-Timestamp (Unix seconds) and X-IOP-Signature. The signature is: v1=hex(HMAC-SHA256(webhook_secret, timestamp + "." + raw_request_body)) Verify the exact raw bytes before JSON parsing, use a constant-time digest comparison and enforce an agreed timestamp tolerance. Keep your server clock synchronized. The per-account webhook secret is separate from apiKey. Coordinate activation before requiring signed callbacks, then reject missing or invalid signatures rather than downgrading to unsigned handling. Signature validation authenticates the sender; it does not replace durable TransactionId deduplication. Logs and support exports must redact credentials and player session tokens. ## Verification tests Scenario | Expected result | Winning and losing rounds | Wallet and IOP ledger totals agree exactly. | Concurrent identical TransactionId | One movement, both requests safely resolved. | Commit, then drop the HTTP response | Redelivery returns success without another balance change. | Two different wins in one event_id | Both legitimate payouts credited once. | Zero result followed by a late win | The late win is accepted once. | Win with no paid bet | Eligible promotional or free-round payment is credited. | Insufficient funds | Rejected movement changes no balance. | Rollback and duplicate rollback | Original movement reversed exactly once. | Rollback before delayed original | No unearned refund and no later debit of a cancelled movement. | EUR/native and USD fallback | Amounts and returned balance match each request currency. | Invalid signature / stale timestamp | Rejected before any balance change when signing is enabled. | Free spins | Eligibility, issuance, duplicate claim, expiry, payout and cancellation reconciled with the bonus wallet. | Long-running sportsbook event | Late settlement works after the browser session ends. | ## Go-live checklist Production credentials, gateway URL and HTTPS wallet registered. Content access, currencies and billing agreed for this account. Wallet signing and IP rules tested against the configured mode. Durable TransactionId uniqueness and atomic balance updates tested under concurrency and restarts. Multiple wins, late wins, zero results, rollbacks and uncertain responses reconciled. Rollback support enabled; optional free spins tested before issuing real campaigns. Catalogue images, desktop/mobile launch and player IP/country handling verified. Monitoring and a reconciliation procedure in place; no credentials in browser code or logs. Test rounds matched against the IOP transaction report before public traffic. ## Glossary Term | Meaning | Seamless wallet | The operator keeps player funds and processes game movements through its wallet webhook. | GGR | Gross gaming revenue: bets less wins. This is distinct from the client fees calculated under your agreement. | event_id | The round correlation identifier; several movements may belong to it. | TransactionId | The idempotency identifier for a settlement request. | Native currency | Settlement in the supported requested currency rather than a USD fallback. | Wallet contract v2 | Wallet balance and settlement handling plus rollback support. | ## FAQ Do all games settle in USD? No. Read currency from every wallet request. Native settlement depends on the account and game; do not infer it from what the player sees. Does a timeout mean the bet was refunded? No. A wallet may commit before the response is lost. Use durable transaction records and reconcile; only an explicit rollback requests reversal. Can more than one win arrive for a round? Yes. Deduplicate by TransactionId, not event_id, and retain the round for late payouts. Can I operate several brands? Each brand has its own account credentials, wallet configuration, content access and billing settings. Arrange onboarding with your IOP manager. Can I reuse a game image URL? Use catalogue artwork URLs as returned, including version parameters. Refresh the feed when artwork changes. Why can a listed game fail to launch? Check current entitlements, billing, currency, player location and the actual error response. A cached catalogue is not a guarantee of current launch availability. ## Changelog Date | Documentation update | 2026-11-12 | Clarified native currency, durable idempotency, late and multiple wins, timeout reconciliation, optional HMAC signing, fee billing, catalogue artwork and free-spin activation. Updated the downloadable integration reference. | Download integration reference · Request access