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.
- Your site lists the games from the RGS catalogue.
- The player picks a game; your site launches it with that player's session token, currency and language.
- The game loads in your page and talks to the RGS; the RGS checks the token with your wallet.
- Each round, the RGS debits the bet and credits the win on your wallet, with unique transaction ids.
Integration checklist
- Exchange keys with us: your wallet base URL and API key, and your launch pass key.
- Implement the wallet API.
- Pull the game catalogue and show the lobby logos.
- Launch games with a player session token,
currencyandlang. - Embed the game page with the iframe settings below.
- Link players to their round history.
- 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}¤cy=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¤cy=EUR&lang=en_US&…" }
| Field | Required | Meaning |
|---|---|---|
operatorId | yes | Your operator id, as agreed during onboarding |
playerId | yes | Your id for the player |
gameId | yes | The game's code |
currency | yes | ISO 4217 code; one of the game's currencies |
language | no | e.g. en_US; one of the game's languages |
mode | yes | real (demo is declined) |
device | yes | desktop or mobile |
sessionToken | yes | Your wallet session token for the player; the RGS sends it back on every wallet call |
rtpLevel | no | The 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 |
jurisdiction | no | The player's jurisdiction code (e.g. SE, UK); decides which game features are allowed. Empty: your default, else Curaçao (CW) |
returnUrl | no | Your 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 |
|---|---|
enabled | Whether the game is switched on for you |
rtp | The game's RTP in percent for its default math |
rtpLevels | The RTP levels the game's engine has, ascending: the only values rtpLevel may take. Each game has its own |
defaultRtpLevel | The level a launch without rtpLevel gets; null: the default math |
minBet, maxBet | Your bet range for the game |
maxWin.betMultiplier | A round never pays more than this multiple of its stake; null: no cap declared by the game |
maxWin.maxExposure | The most one round can pay at maxBet |
maxWin.perCurrency | Your absolute max win per currency, if agreed |
currencies, languages | What the game supports for you |
freerounds | Whether 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
sandboxattribute, includeallow-top-navigation-by-user-activationso the Home/Lobby button can open your lobby.
Home/Lobby button
- Without a
returnUrlin 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. returnUrlmust be an absolutehttp/httpsURL; anything else is refused with400 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:
- Per player session, with
rtpLevelin the launch API — the way to choose it yourself, per game. - Per operator and game, set by us for your account in the RGS backoffice.
- 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
}
| Field | Required | Meaning |
|---|---|---|
player_external_id | yes | The 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_code | yes | A game with freerounds: true |
currency | yes | The player's currency, ISO 4217 |
bet_amount | yes | The stake of each free round, a decimal string with at most the currency's decimals |
total_rounds | yes | 1–1000 |
expires_at | no | When unplayed rounds lapse (a future date) |
max_win | no | The most the whole award may pay. Reaching it ends the award; its remaining rounds are forfeited |
rejectable | no | Whether 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"andbonus_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_idis 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
betandwincall; separate usesbetthenwin, withrollbackto cancel a bet that failed downstream. We agree the mode during onboarding. - Balances: a
success: truereply whosebalanceis not a decimal string in the session's currency and decimals is treated as an unknown outcome and retried. - Insufficient funds: return
success: falsewith anerror; 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.