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.
Read the sections in the sidebar or download the integration reference. Last reviewed: 12 November 2026.
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.
<iframe src="RETURNED_GAME_URL" style="width:100%;height:100%;border:0" allow="autoplay; fullscreen" allowfullscreen></iframe>
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/providers
GET/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.
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.
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 · Credentials