Operator Integration Guide

How to put RGS games on your casino site: list the games, launch them for a player, embed them in your page and settle bets and wins against your wallet. Building a game? See the game developer docs.

Overview

The RGS (Remote Gaming Server) hosts HTML5 casino games and decides every outcome on the server. Your site never runs game logic: it shows the game in a page (usually an iframe), and the RGS charges bets and pays wins through your wallet in real time. The player's money always stays with you.

How an operator site, its wallet and the RGS work together The operator portal in the player's browser shows the lobby, the game in an iframe and the history link. The portal server creates a wallet session token. The RGS serves the game catalogue, the launch API, the game pages, the game API and the player history, and calls the operator's wallet API to charge bets and pay wins. Operator Operator portal — player's browser Lobby game tiles with logos Game (iframe) page served by the RGS; balance comes from your wallet Account link to round history Operator backend Portal server players, sessions, lobby Wallet system player balances; implements /wallet/init · bet · win · rollback ① session token RGS — Remote Gaming Server Game catalogue GET /api/games Game pages /games/{id}/play.html Game API POST /api/rgs Player history /player/history Launch API POST /api/game-launch Rounds & settlement decides outcomes, records rounds, charges bets and pays wins ② catalogue ④ launch URL: token, currency, lang ⑤ load_game · play ⑦ history ③ optional, with rtpLevel ⑥ wallet API calls
  1. Your site lists the games from the RGS catalogue.
  2. The player picks a game; your site launches it with that player's session token, currency and language.
  3. The game loads in your page and talks to the RGS; the RGS checks the token with your wallet.
  4. Each round, the RGS debits the bet and credits the win on your wallet, with unique transaction ids.

Integration checklist

  1. Exchange keys with us: your wallet base URL and API key, and your launch pass key.
  2. Implement the wallet API.
  3. Pull the game catalogue and show the lobby logos.
  4. Launch games with a player session token, currency and lang.
  5. Embed the game page with the iframe settings below.
  6. Link players to their round history.
  7. Run the go-live tests.

Game catalogue

List the active games with GET https://rgsaws.cloudvlt.com/api/games:

{
  "status": "OK",
  "games": [
    {
      "game_id": "dd",
      "name": "Dice Duel",
      "category": { "id": "instant", "name": "Instant Win" },
      "rtp": "95.83",
      "min_bet": 0.1,
      "max_bet": 100,
      "volatility": null,
      "icon_url": "https://rgsaws.cloudvlt.com/games/dd/dd.png"
    }
  ]
}

icon_url is the 450×270 lobby logo for your game tiles. game_id is what you launch with. Cache the list; games are added when they are approved.

Launching a game

Direct launch URL

Open the game page with the player's session token from your wallet:

https://rgsaws.cloudvlt.com/games/{game_id}/play.html?token={player-session-token}&game_id={game_id}&currency=EUR&lang=en_US&device_id=web
Param Required Description
token yes Your player session token. The RGS sends it to your wallet (/wallet/init) to identify the player and balance.
game_id yes The game code from the catalogue; must match the path.
currency yes Player's currency, ISO 4217 — see currencies.
lang yes Player's language: en_US style or ISO 639-1 (en).
device_id no web or mobile.
lobby_url no Your lobby, URL-encoded, absolute http/https. Only with it the game shows a Home/Lobby button, which opens it in the whole window (target _top) — see Home/Lobby button.

Launch API (server to server)

Alternatively your server asks the RGS for the launch URL. Use this when you set an RTP level or a jurisdiction: they are sent here, never in the browser URL, so players can't change them:

POST https://rgsaws.cloudvlt.com/api/game-launch
Game-Launch-Pass-Key: {your pass key}
Content-Type: application/json

{
  "operatorId": "your-operator-id",
  "playerId": "player-123",
  "gameId": "dd",
  "currency": "EUR",
  "language": "en_US",
  "mode": "real",
  "device": "desktop",
  "sessionToken": "{player-session-token}",
  "rtpLevel": 94,
  "jurisdiction": "SE",
  "returnUrl": "https://your-casino.example/lobby"
}

200 { "url": "https://rgsaws.cloudvlt.com/games/dd/play.html?token=…&game_id=dd&currency=EUR&lang=en_US&…" }
Field Required Meaning
operatorIdyesYour operator id, as agreed during onboarding
playerIdyesYour id for the player
gameIdyesThe game's code
currencyyesISO 4217 code; one of the game's currencies
languagenoe.g. en_US; one of the game's languages
modeyesreal (demo is declined)
deviceyesdesktop or mobile
sessionTokenyesYour wallet session token for the player; the RGS sends it back on every wallet call
rtpLevelnoThe RTP level for this session (a whole number, the RTP in percent): one of the game's rtpLevels from the game settings API. Empty: the game's defaultRtpLevel
jurisdictionnoThe player's jurisdiction code (e.g. SE, UK); decides which game features are allowed. Empty: your default, else Curaçao (CW)
returnUrlnoYour lobby, for the in-game Home button; absolute http(s) URL

rtpLevel is optional — see RTP levels. jurisdiction is optional — see jurisdictions. returnUrl is optional — see Home/Lobby button. Errors: 401 LOGIN_FAILED (bad pass key), 400 REQUEST_DECLINED (missing fields, unknown game, an rtpLevel the game does not have, an unknown or inactive jurisdiction, a returnUrl that is not an absolute http(s) URL).

Game settings API

Before launching, your server can read a game's settings as they apply to you: the bet range, the RTP levels its engine has (send one of them as rtpLevel), the default level, its max win and exposure, and its currencies and languages. Same authentication as the launch API.

GET https://rgsaws.cloudvlt.com/api/games/bj/settings

200 {
  "gameId": "bj",
  "name": "Blackjack",
  "enabled": true,
  "rtp": "99.50",
  "rtpLevels": [90, 91, 92, 93, 94, 95, 96, 97, 98, 99],
  "defaultRtpLevel": 94,
  "minBet": "1.00",
  "maxBet": "50.00",
  "maxWin": { "betMultiplier": "2.5", "maxExposure": "125.00", "perCurrency": { "EUR": "250000.00" } },
  "currencies": ["EUR", "USD"],
  "languages": ["en_US", "es_ES"],
  "freerounds": false
}
Field Meaning
enabledWhether the game is switched on for you
rtpThe game's RTP in percent for its default math
rtpLevelsThe RTP levels the game's engine has, ascending: the only values rtpLevel may take. Each game has its own
defaultRtpLevelThe level a launch without rtpLevel gets; null: the default math
minBet, maxBetYour bet range for the game
maxWin.betMultiplierA round never pays more than this multiple of its stake; null: no cap declared by the game
maxWin.maxExposureThe most one round can pay at maxBet
maxWin.perCurrencyYour absolute max win per currency, if agreed
currencies, languagesWhat the game supports for you
freeroundsWhether the game offers free rounds to you

rtpLevels is empty for a game with one math model. defaultRtpLevel is used when the launch sends none (null: the default math). maxExposure is the most one round can pay at maxBet; perCurrency holds your absolute caps per currency. Amounts are exact decimal strings. Errors: 401 LOGIN_FAILED, 404 GAME_NOT_FOUND.

Embedding the game

Game pages may be framed by any site. Give the iframe the full area and allow audio and full screen:

<iframe
  src="{launch url}"
  allow="autoplay; fullscreen"
  style="width: 100%; height: 100%; border: 0"
></iframe>
  • Games are responsive and work in portrait and landscape on phones; on mobile you can also open the launch URL full screen instead of framing it.
  • Don't cache or rewrite the launch URL — every launch needs a fresh, valid player token.
  • The balance shown in the game comes from your wallet; refresh your own balance display when the player closes the game.
  • If you set the iframe's sandbox attribute, include allow-top-navigation-by-user-activation so the Home/Lobby button can open your lobby.

Home/Lobby button

  • Without a returnUrl in the launch, games show no Home/Lobby button.
  • With a returnUrl, the game's Home/Lobby button opens it in the full browser window (target _top): your lobby replaces the whole page, not just the game's iframe.
  • returnUrl must be an absolute http/https URL; anything else is refused with 400 REQUEST_DECLINED.

Currencies & languages

Every game supports at least currencies EUR, USD and languages en_US, es_ES, ja_JP. Pass the player's currency and language on every launch; a value the RGS doesn't support falls back to EUR / en_US.

Supported currencies BRL, CNY, EUR, GBP, IDR, INR, JPY, KRW, MYR, PHP, THB, USD, VND
Supported languages cs_CZ, de_DE, en_US, es_ES, et_EE, fi_FI, fr_FR, id_ID, ja_JP, ko_KR, ms_MY, no_NO, pl_PL, pt_BR, ro_RO, ru_RU, sv_SE, sw_SW, th_TH, tr_TR, uk_UA, vi_VN, zh_CN, zh_TW

The currency the player is charged in is always the one your wallet returns for the session (/wallet/init); the currency parameter must match it. Amounts are shown in the currency's own format — its symbol, symbol position, separators and number of decimals, set per currency in the backoffice — whatever the language: €1,234.50, R$ 1.234,50, 5.000 ₫, ¥1,234.

RTP levels

Each game has a fixed set of return-to-player levels, one certified math model per level. Which levels a game offers is its developer's choice and is not limited to a range: a level is the RTP in percent as a whole number, for example 84, 87, 92 or 97 (new games have at least 96, 94, 92 and 90; blackjack has every level from 90 to 99). The levels differ from game to game because each game's engine has its own: read them per game as rtpLevels from the game settings API. Without a level the game plays its default math. The level comes from, in this order:

  1. Per player session, with rtpLevel in the launch API — the way to choose it yourself, per game.
  2. Per operator and game, set by us for your account in the RGS backoffice.
  3. Per game, set by us in the RGS backoffice — applies to all operators.

The game settings API shows the level a launch without rtpLevel gets as defaultRtpLevel (null: the default math).

The level must be one the game has. A level the game does not have is refused with 400 REQUEST_DECLINED and a message naming the game's levels, for example RTP level 91 does not exist for game dd. Available levels: 90, 94, 97; it is never rounded to a nearby level. The level is never part of the browser URL.

Jurisdictions

Send the player's jurisdiction as jurisdiction in the launch API. It decides which game features the player gets, for example no autoplay or no bonus buy. Codes are case-insensitive:

Code Differs from the defaults
CW Curaçao Nothing: everything allowed (also when no jurisdiction is given)
SE Sweden No autoplay, turbo, slam stop or bonus buy; 3 s minimum round; reality check every 60 minutes; session time and net position shown
UK United Kingdom No autoplay, turbo, slam stop, bonus buy or parallel play; 2.5 s minimum round; no celebrating wins of at most the stake; session time and net position shown
DE Germany No autoplay, turbo, bonus buy, jackpots or parallel play; €1.00 maximum stake; 5 s minimum round; RTP shown
GLI19 GLI-19 No autoplay
MT, GG, DK, GI, RO, PH Nothing yet (to be confirmed)
  • Without a jurisdiction, your default jurisdiction applies (set by us per operator); without one, Curaçao (CW, everything allowed).
  • A code we don't have, or one that is switched off, is refused with 400 REQUEST_DECLINED (Unknown or inactive jurisdiction: XX) — a typo never launches with everything allowed.
  • The jurisdiction is kept on our server for the player's session and is never part of the browser URL.
  • A stake limit (Germany: €1.00) also removes higher bet levels from the game, and higher bets are refused.
  • Rules are configuration on our side, not game code: ask us to add a jurisdiction or change its rules, and games follow without an update.

Free rounds

You can give a player free rounds on a game: a number of rounds at a fixed stake that you pay for. The player stakes nothing; each round plays like a paid round at that stake, and its win is paid to the player's balance through your wallet. Any wagering requirement is yours to apply; we keep none. A game offers free rounds when its freerounds is true in the game settings API.

Award free rounds

POST https://rgsaws.cloudvlt.com/api/free-rounds/assign
Authorization: Bearer <your API key>
Content-Type: application/json

{
  "player_external_id": "26USD-6af049848f2ef",
  "game_code": "dd",
  "currency": "USD",
  "bet_amount": "0.50",
  "total_rounds": 10,
  "expires_at": "2026-12-01T00:00:00+00:00",
  "max_win": "25.00",
  "rejectable": true
}
FieldRequiredMeaning
player_external_idyesThe player's id as your wallet knows it. The player does not need to have played on the RGS yet: the award waits for their first launch of the game
game_codeyesA game with freerounds: true
currencyyesThe player's currency, ISO 4217
bet_amountyesThe stake of each free round, a decimal string with at most the currency's decimals
total_roundsyes1–1000
expires_atnoWhen unplayed rounds lapse (a future date)
max_winnoThe most the whole award may pay. Reaching it ends the award; its remaining rounds are forfeited
rejectablenoWhether the player may decline the offer (default true)

The answer is 201 with the award (id, status: "offered", rounds_remaining, total_winnings, …). A game that cannot play free rounds, or invalid input, is refused with 422 and the reason. The award belongs to you: only your players get it. Follow an award with GET /api/free-rounds/{id}, a player's awards with GET /api/free-rounds/player?player_external_id=…, and the one a player has on a game with GET /api/free-rounds/check?player_external_id=…&game_code=…. On the platform, the same is a Free Rounds button on each player in the Players list.

What the player sees

  • The next time they open the game: an offer with the rounds, the stake, the expiry and the max win, to play now or (when rejectable) decline. While an award is offered or being played, real-money play of that game waits.
  • While playing: a counter with the rounds left and the free-round winnings, and the bet locked to the award's stake.
  • At the end: a summary of what the award paid. Free rounds are marked in the player's round history and replays.

How free rounds reach your wallet

  • No withdrawal. A free round never debits the player.
  • One deposit per paying or final round, a zero deposit for a losing round, with bonus_type: "FREE_ROUND" and bonus_ref (the award's reference) on the wallet API's win call. Book these as the cost of your promotion.
  • Deposits are retried until your wallet confirms them, like any win.

Seamless wallet API (direct integration)

For a direct integration you host these endpoints and the RGS calls them. Requests are JSON POSTs with Authorization: Bearer {api key}. Amounts are decimal strings in major units with exactly the game session's decimals, always with a currency: "1.00" EUR, "1000" JPY, "0.000000000000000001" ETH. Never floats, never cents. Balances in your replies are decimal strings too.

Endpoint Request Response
/wallet/init player_token, game_id player_id, external_id, player_name, currency, language, balance, game (min_bet, max_bet, bet_steps, default_bet, lines, rtp)
/wallet/player player_token player_id, external_id, currency
/wallet/balance player_token balance, currency, player_id
/wallet/betandwin player_token, bet, win, amount_format: "decimal", currency, transaction_id, game_session, game_id success, balance, currency, decimals, error?
/wallet/bet, /wallet/win player_token, amount, currency, transaction_id, game_session, game_id same as above
/wallet/rollback player_token, transaction_id, amount, currency same as above
  • Idempotency: transaction_id is unique per call. If you receive one you have already processed, return the original result without moving money again.
  • Modes: combined settles a round in one betandwin call; separate uses bet then win, with rollback to cancel a bet that failed downstream. We agree the mode during onboarding.
  • Balances: a success: true reply whose balance is not a decimal string in the session's currency and decimals is treated as an unknown outcome and retried.
  • Insufficient funds: return success: false with an error; the player is not charged and the round doesn't happen.
  • Respond within the agreed timeout (10 seconds by default).

Round history & replay

Link players to their own history page, scoped by their session token:

https://rgsaws.cloudvlt.com/player/history?token={player-session-token}

It lists the player's rounds with replay links that redraw each round exactly as played. Replay links are temporary signed URLs.

Testing & go-live

  • Try every game with play money in the sandbox lobby, including currency and language switching.
  • Against your test wallet, check: launch, a losing and a winning round, insufficient funds, a repeated transaction_id, a timeout followed by a retry, and the history page.
  • Check each required currency and language.
  • Monitor the RGS with GET https://rgsaws.cloudvlt.com/health.