LivePlay Bingo Integration Docs

Concepts

Vocabulary and conventions used throughout these docs

A short tour of terms you'll see repeated throughout the integration docs. Skim this once before diving in. Bingo-specific terms are introduced as plain English first.

How the game works (one paragraph)

Players join a room (a shared bingo game with multiple players in it at the same time). They buy one or more cards (each card is a numbered grid). Numbers are called over a live video stream by a human host (the host stream). Players match called numbers on their cards, and at the end of the round (one complete game in that room), winners get paid.

Some rooms also offer slot games inside the same iframe (rolling out; see Slots). Each slot spin is its own small round.

You don't need to understand any of the bingo math to integrate. You only need to know when a round started and ended, and how much money moved.

Players, rounds, and rooms

  • Room — a shared live game multiple players join at the same time. Each room runs back-to-back rounds.
  • Round — one bingo game from card purchase to result payout. A round belongs to exactly one room. Each round has a globally unique roundid. Treat it as an opaque string: most are UUIDs, but some carry a prefix (a slot spin is slots:<uuid>).
  • Spin — one play of a slot game. Every spin is its own round with its own roundid, one debit and one credit.
  • Card — one numbered grid a player has bought for a round. A player can hold several cards in one round.
  • Stake / wager — how much a player bets per card (bingo) or per spin (slots). Same thing, two words used interchangeably across the industry.
  • Side bet — an optional extra bet a player makes alongside their cards (e.g., "lucky line" — a small extra wager that pays out if the player matches numbers in a specific pattern). Independent from the main card win.
  • Settlement — the moment a round's outcome is finalised and money is paid out to winners. Your wallet endpoint sees this as a credit call.
  • Host stream — the live video of a human host calling balls. Embedded inside our iframe; you don't connect to it separately.

Each player has their own roundid, even when they share a room. Wallet calls are always per-player, never per-room. Two players in the same bingo room playing the same round will see two different roundid values in their wallet logs. Every slot spin gets its own roundid too. This is the most common source of confusion during integration — keep it in mind when reconciling wallet records.

Session

A session is one player's authorised window to play. Sessions are created when an aggregator (or you, if integrating directly) calls our /gamelauncher/play endpoint. Each session carries an operator, brand, currency, mode, and two IDs:

  • sessionid — our identifier for the session. We generate it.
  • externalsessionid — your identifier for the session (or your aggregator's). You generate it. While a launch code is still valid (10 minutes), calling /gamelauncher/play again with the same operator, externalsessionid and currency returns the same session and launch URL rather than creating a duplicate. After that, the same call creates a new session.

A session record lasts 24 hours. The lifetime is fixed at creation — there is no "keep-alive on activity". When it expires, the record is removed passively from our database. We do not currently signal the casino's wallet that a session ended.

When the iframe starts, the game swaps the launch code for a player token that lasts 1 hour. After that, a reload, a reconnect, or a slot spin needs a fresh launch URL.

The launch code embedded in the launch URL is much shorter-lived: 10 minutes. Request a fresh launch URL each time you start a player session.

Launch code

/gamelauncher/play returns a launch URL that contains a short-lived launchCode. The casino embeds this URL in an iframe. Our frontend exchanges the launch code for a player token, then loads the game. A launch code can be exchanged again while it is valid (for example if the iframe reloads during start-up), and expires after 10 minutes. Treat launch URLs as secret, and request a fresh one for every new player session.

Transaction

Every wallet operation (debit, credit, reverse) carries a unique transid (UUID); a retry reuses it. Transaction IDs are idempotency keys — calling twice with the same transid MUST produce the same result, not two effects. This matters because we retry credit and reverse on network failures (3 attempts with exponential backoff, and a reverse that still fails is resent in the background for a few hours).

Mode

mode is DEMO or REAL. We store it with the session, but today it does not change how the game behaves: a DEMO session still sends debit and credit calls to the wallet like a REAL one. For testing, launch against a test wallet or test player accounts.

Source of truth for round outcomes

This is important: both integration paths reconcile against a wallet record, but which wallet holds that record differs by path.

  • Aggregator path: the aggregator's wallet is the source of truth. When a player wins, we send a credit call to the aggregator. Their record of the credit is what your reporting reconciles against.
  • Direct integration path: the credit call we send to your wallet is the source of truth. Your record of that call is the authoritative outcome.

The iframe does not currently emit any lifecycle events to its parent window — there is no postMessage contract today. Rely on the wallet records.

Identifiers you'll provide

FieldPurpose
operatorYour operator identifier with us — assigned during onboarding
brandA sub-identity within your operator. Some operators run multiple brands (different sites, different markets); you can leave it equal to operator if you only have one
gamecodeWhich of our games you're launching (e.g., live-bingo)
externalsessionidYour session identifier. See Session for repeat calls
currencyA currency code configured for your game. Usually ISO 4217 (USD, EUR, GBP, ...), the international currency-code standard. Sweepstakes codes such as SC and GC work when configured
playeridYour stable identifier for the player
countryISO 3166 two-letter country code for the player. Stored for audit; we don't enforce geo rules from it
ipaddressPlayer's IP address. Stored for audit; we don't enforce geo rules from it

Money

By default, wallet amounts are sent as integer cents — the main currency unit times 100. There are no decimals or floats in the default wallet contract.

CurrencyMain unitWire amountExample
USD, EUR, GBPdollar / euro / poundmain × 100$1.00 → 100
Any other two-decimal currencymain unitmain × 1000.50 PLN → 50

Today only currencies whose minor unit is 1/100 of the main unit are fully supported. ISO 4217 currencies with a different minor unit (JPY: none; BHD: 1/1000; cryptocurrencies: variable) need per-operator handling on our side before go-live — talk to us during onboarding so we can map your currency to the correct wire convention. Without that mapping, amounts are still multiplied by 100 even for currencies where that is incorrect (for example, ¥150 would be sent as 15000).

The wallet adapter owns this conversion. Current direct integrations use this default integer-cents convention. If a future partner needs a different wire amount convention, we add that exception in the wallet adapter rather than in gameplay code.

Currency mismatch

A session is fixed to one currency for its entire lifetime. We do not convert between currencies. Debit and credit calls carry the session's currency. Custom integrations that require per-currency wallet lookup may also receive currency on balance and reverse calls. If the player's wallet doesn't actually hold that currency, your wallet can refuse the call with CURRENCY_MISMATCH. Today we treat that like any other refusal: the bet fails and the player sees a generic error. We don't end the session.

To avoid this, the casino is responsible for either:

  1. Picking a currency the player's wallet supports before launching, or
  2. Operating sub-wallets per currency on your side.

Field naming

All HTTP API fields (launcher API and direct-integration wallet endpoints) are lowercase, no separators — roundid, transid, sessionid, externalsessionid, playerid, gamecode, debitamount, creditamount, originaltransid, ipaddress. This matches the existing seamless-wallet conventions.

Auth

All endpoints (in both directions) use HTTP Basic Auth by default — that's a Authorization: Basic <base64(username:password)> header on every request. We issue credentials during onboarding. Rotate on request. For wallet calls to you, we can use HMAC signing instead (see Direct integration).

We identify your calls to us by the credentials we issue you. For our calls to your wallet (direct integrators only), we share our egress IP (the public IP our servers use when calling out to the internet) so you can allowlist it.

On this page