Operator integration kit

Launch Luiri Unity WebGL games inside an operator casino site while the operator keeps player wallet, deposits, withdrawals, KYC, and player account ownership.

Provider architecture

Backend-to-backend launch flow

The browser never receives the operator API secret. The operator backend signs the launch request, Luiri creates a short-lived token, and the iframe receives only that token. Unity only animates the game state; wallet operations always pass through Luiri and the operator wallet backend.

1Operator backend signs Launch API request
2Luiri validates API key, signature, domain, game status, and wallet mode
3Luiri calls operator balance endpoint and creates a short-lived token
4Operator website opens /play/{token} in an iframe
5Unity reads the token, fetches config from Luiri, and displays returned balance
6Round APIs debit, credit, or rollback through signed wallet callbacks
Machine-readable handoff

API contract and operator build scope

Give these assets to an operator backend team. They define exactly what the operator must call, what Luiri calls back, and which fields must be stored for reconciliation.

Backend launch routeOperator backend calls POST /api/v1/launch after player login.
Iframe host pageOperator frontend opens only the returned launchUrl or iframe HTML.
Wallet callbacksOperator exposes HTTPS balance, debit, credit, and rollback endpoints.
Idempotency ledgerOperator stores idempotencyKey, roundId, transactionId, and final balance.
ReconciliationOperator compares wallet ledger against Luiri sessions, rounds, and callback deliveries.
Error handlingOperator retries safely only when idempotency rules allow it.
POST /api/v1/launch

Launch a game session

Call this from the operator backend after the player is authenticated on the casino website. Luiri returns a launch URL and iframe HTML for a short-lived session token.

HMAC signedBackend onlyShort-lived tokenDomain allowlist checked
Request body
{
  "gameId": "jetx-cash",
  "operatorPlayerId": "player_10291",
  "currency": "INR",
  "locale": "en",
  "originDomain": "https://casino.example",
  "returnUrl": "https://casino.example/lobby"
}
Response
{
  "data": {
    "token": "lg_...",
    "launchUrl": "https://luirigaming.com/play/lg_...",
    "expiresAt": "2026-06-22T12:15:00.000Z",
    "iframe": "<iframe src=\"https://luirigaming.com/play/lg_...\" allow=\"fullscreen; autoplay; gamepad\"></iframe>"
  }
}
Node signed launch example
import crypto from "node:crypto";

const rawBody = JSON.stringify({
  gameId: "jetx-cash",
  operatorPlayerId: "player_10291",
  currency: "INR",
  locale: "en",
  originDomain: "https://casino.example"
});

const timestamp = Date.now().toString();
const signature = crypto
  .createHmac("sha256", process.env.LUIRI_API_SECRET)
  .update(`${timestamp}.${rawBody}`)
  .digest("hex");

const response = await fetch("https://luirigaming.com/api/v1/launch", {
  method: "POST",
  headers: {
    "content-type": "application/json",
    "x-luiri-key": process.env.LUIRI_API_KEY,
    "x-luiri-signature": `t=${timestamp},v1=${signature}`
  },
  body: rawBody
});
Downloadable helper

Node SDK for operator backend

Operators can use Luiri's small Node client to sign launch requests and verify wallet callback signatures without rewriting HMAC code in every casino backend.

SDK launch example
import {
  createIdempotencyKey,
  createLuiriClient
} from "https://luirigaming.com/sdk/luiri-node-client.mjs";

const luiri = createLuiriClient({
  apiKey: process.env.LUIRI_API_KEY,
  apiSecret: process.env.LUIRI_API_SECRET,
  baseUrl: "https://luirigaming.com"
});

const launch = await luiri.launchGame({
  gameId: "jetx-cash",
  operatorPlayerId: "player_10291",
  currency: "INR",
  originDomain: "https://casino.example"
}, {
  idempotencyKey: createIdempotencyKey({
    prefix: "launch",
    operatorPlayerId: "player_10291",
    sessionId: "entry",
    roundId: "initial",
    operation: "open"
  })
});

console.log(launch.iframe);
SDK wallet callback adapter
import {
  createInMemoryWalletStore,
  createWalletCallbackAdapter,
  readRawBody
} from "https://luirigaming.com/sdk/luiri-node-client.mjs";

const wallet = createInMemoryWalletStore({ initialBalance: 5000, currency: "INR" });
const adapter = createWalletCallbackAdapter({
  walletSecret: process.env.LUIRI_WALLET_SECRET,
  getBalance: (payload) => wallet.getBalance(payload),
  debit: (payload) => wallet.debit(payload),
  credit: (payload) => wallet.credit(payload),
  rollback: (payload) => wallet.rollback(payload)
});

// In an HTTP route:
const rawBody = await readRawBody(request);
const result = await adapter.handle({
  rawBody,
  signatureHeader: request.headers["x-luiri-wallet-signature"]
});

response.statusCode = result.status;
response.end(JSON.stringify(result.body));
Operator wallet

Balance, debit, credit, rollback

In live mode, the operator wallet is the source of truth. Luiri signs every wallet callback withx-luiri-wallet-signature and stores delivery attempts, round state, and audit history.

BalanceReturn current casino wallet balance before launch/config.
DebitDeduct bet when a round starts. Must be idempotent.
CreditAdd payout when a round settles with a win. Must be idempotent.
RollbackReverse a previously debited round if settlement fails.
ConfigGET /api/game/session/{token}/configUnity reads token config and current balance.
StartPOST /api/game/rounds/startLuiri debits bet amount before animation result.
SettlePOST /api/game/rounds/settleLuiri credits payout and records GGR/fee.
RollbackPOST /api/game/rounds/rollbackLuiri reverses started round debit after failure.
Balance request
{
  "operatorId": "op_...",
  "playerId": "player_10291",
  "currency": "INR",
  "test": false
}
Debit callback
{
  "transactionId": "wtx_debit_rnd_...",
  "idempotencyKey": "wallet:debit:rnd_...",
  "operatorId": "op_...",
  "playerId": "player_10291",
  "sessionId": "ses_...",
  "roundId": "rnd_...",
  "type": "debit",
  "amount": 100,
  "currency": "INR"
}
Wallet response
{
  "balance": 4900,
  "currency": "INR",
  "externalRef": "operator_wallet_txn_..."
}
Player balance

How the game shows casino wallet balance

When the iframe loads, Unity sends the token to Luiri. Luiri reads the launch session and returns the latest balance snapshot from the operator wallet. After debit, credit, or rollback, Luiri returns the updated balance to Unity so the in-game balance display stays synced.

Before launchLuiri calls balanceUrl for player_10291.
Round startLuiri calls debitUrl for the bet amount.
Round winLuiri calls creditUrl for the payout amount.
Round failureLuiri calls rollbackUrl for the same round.
Game UIUnity displays only the balance Luiri returns.
HMAC SHA-256

Request signing and domain rules

Launch requests use x-luiri-signature. Wallet callbacks usex-luiri-wallet-signature. Each signature covers the raw JSON body and timestamp. Launches are also blocked unless originDomain matches the operator allowlist.

TimestampSignature timestamp must be within the five-minute tolerance.
Raw bodySign the exact JSON string sent over the network.
Replay guardExact signed launch replay is rejected and logged.
Secret storageAPI secret and wallet secret must stay server-side only.
AllowlistoriginDomain is normalized and checked on every launch.
Signature format
timestamp = Date.now().toString()
signature = HMAC_SHA256(secret, timestamp + "." + rawBody)

x-luiri-signature: t={timestamp},v1={signature}
x-luiri-wallet-signature: t={timestamp},v1={signature}
Live readiness gate

Wallet certification is mandatory

Live launches are blocked until the latest wallet certification passed in live mode. Changing callback URLs or wallet secret invalidates the previous certification, so operators must rerun verification before requesting production approval.

Fresh windowCertification must be within the last 30 days.
Four checksBalance, debit, credit, and rollback must all pass.
Live modeTest-mode certification cannot unlock live launches.
Admin reviewLuiri admin approval recomputes the current checklist before activating the operator.
Launch guardThe signed Launch API still blocks live launch if certification becomes stale or invalid.
SDK certification helper
import {
  assertWalletCertificationPassed,
  summarizeWalletCertification
} from "https://luirigaming.com/sdk/luiri-node-client.mjs";

const report = await fetch("/api/operator/wallet-config/test", {
  method: "POST",
  credentials: "include"
}).then((response) => response.json());

const summary = summarizeWalletCertification(report.data);
console.log(summary.summary);

assertWalletCertificationPassed(report.data);
Operator sandbox

Acceptance test before production

In the operator portal, use /operator/sandbox to complete the external integration handoff. The sandbox page creates credentials, verifies signed wallet callbacks, generates a real iframe launch, and points the operator to reconciliation reports.

CredentialsCreate API key and store the one-time secret on the operator backend.
Wallet verifyRun balance, debit, credit, and rollback signed callback probes.
Iframe launchCreate a token, open /play/{token}, and verify the game reads config.
Round testPlay one loss, one win, and one rollback path in sandbox.
ReconcileMatch session, round, idempotency key, wallet transaction, and fee ledger rows.
API behavior

Status codes and retry rules

Operators should treat wallet callbacks as financial ledger operations. Retry only with the same idempotency key after a transport timeout, and never create a second debit or rollback for the same round.

200SuccessRequest accepted. Use returned session, round, balance, or iframe data.
400Validation/lifecycle blockedBad body, expired token, unavailable game, bad bet, failed wallet operation, or blocked live launch.
401Authentication failedMissing/invalid API key or HMAC signature.
404Token not foundLaunch session token is invalid or expired.
409Replay/conflictExact signed launch replay or conflicting wallet idempotency.
429Rate limitedOperator exceeded signed Launch API request window.
Production readiness

Go-live checklist

API keyCreate live key and keep secret only on operator backend.
DomainAdd production casino domain to the operator allowlist.
WalletConfigure HTTPS balance, debit, credit, and rollback endpoints.
VerificationRun fresh live-mode callback certification: balance, debit, credit, rollback must all pass.
Sandbox launchCreate a real sandbox iframe launch and play one loss, win, and rollback path.
LedgerReconcile operator wallet transactions by idempotency key and round ID.
ApprovalWait for Luiri admin approval; live launch is blocked until the readiness gate passes.