> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.wuzzlo.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.wuzzlo.com/_mcp/server.

# Integration quickstart

# Integration quickstart

An operator integrates in both directions:

| Direction         | Responsibility                                                                                                        |
| ----------------- | --------------------------------------------------------------------------------------------------------------------- |
| Operator → Wuzzlo | Sign requests and call Wuzzlo to list games, launch sessions, and reconcile transactions.                             |
| Wuzzlo → Operator | Receive Wuzzlo callbacks that authenticate players, read balances, debit bets, settle results, and perform rollbacks. |

The Sample Integrator in the Wuzzlo source repository is a reference operator. It demonstrates the protocol, but its demo users, administrative routes, configuration, and local conveniences are not production requirements.

## End-to-end flow

Send Wuzzlo your operator name, wallet base URLs, currency, RSA public key, callback paths, allowed source IPs, and funded staging test user. Wuzzlo returns an `operatorId`, staging and production API URLs, and the Wuzzlo public key.

Implement `POST /auth/login`, `POST /balance`, `POST /betrequest`, `POST /resultrequest`, and `POST /rollbackrequest` on an HTTPS service reachable by Wuzzlo.

Sign operator-to-Wuzzlo requests with the operator private key. Verify Wuzzlo-to-operator wallet callbacks with the Wuzzlo public key. Use RSA-SHA256 with PKCS#1 v1.5 padding over the exact UTF-8 request body.

Call `POST /api/operator/get-games-list`, select a `gameId`, then call `POST /api/operator/login` from the operator backend. Return the resulting `gameUrl` to the operator frontend and load it in an iframe. Use game ID `9000` to load the lobby.

Wuzzlo tests authentication, funded balance, debit, duplicate requests, settlement, rollback, invalid lifecycle transitions, insufficient funds, and invalid signatures. Production is enabled only after the staging checks pass.

## Environments

| Environment | Wuzzlo API                | Player UI                            |
| ----------- | ------------------------- | ------------------------------------ |
| Staging     | `https://vapi.wuzzlo.com` | `https://test.wuzzlo.com`            |
| Production  | `https://api.wuzzlo.com`  | Returned in the production `gameUrl` |

Keep environment credentials and keys separate. Never use staging keys, wallet URLs, test users, or operator IDs in production unless Wuzzlo explicitly assigned the same value.

## Launch example

Serialize the body once, sign those exact bytes, and send the same bytes:

```json
{
  "operatorId": "your-operator-id",
  "userId": "1001",
  "username": "Player 1001",
  "gameId": "9001",
  "currency": "INR",
  "clientIp": "203.0.113.10",
  "platformId": "desktop",
  "redirectUrl": "https://operator.example/games"
}
```

```http
POST /api/operator/login HTTP/1.1
Host: vapi.wuzzlo.com
Content-Type: application/json
Signature: <base64-rsa-sha256-signature>
X-Request-Id: launch-1001-20260716-001
```

A successful response has body status `0` and includes `gameUrl` and `expiresAtUtc`. Treat HTTP status and body status as separate values.

## Load the game in an iframe

After the operator backend creates the session, the operator frontend must set the returned `gameUrl` as the iframe `src`. Do not construct or modify this URL because it contains the Wuzzlo launch route and session information.

```html
<iframe
  id="wuzzlo-game"
  src="https://test.wuzzlo.com/your-operator/session-token/9001"
  title="Wuzzlo game"
  allow="fullscreen"
  allowfullscreen
  style="width: 100%; height: 100vh; border: 0"
></iframe>
```

In an application, assign the URL returned by your backend rather than placing a session URL in source code:

```js
const response = await fetch("/api/games/wuzzlo/launch", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ gameId: "9001" })
});

if (!response.ok) throw new Error("Unable to create Wuzzlo session");

const { gameUrl, expiresAtUtc } = await response.json();
document.querySelector("#wuzzlo-game").src = gameUrl;
```

The operator backend—not browser JavaScript—must call Wuzzlo and create the signature. The browser receives only the short-lived `gameUrl`. Create a fresh session when the URL expires, remove the iframe when the player closes the game, and make the container responsive for desktop and mobile layouts.

Treat `gameUrl` as sensitive session data. Do not persist it in analytics, browser logs, referrer-bearing links, or shared caches. Only embed URLs returned by the trusted operator backend.

Never generate signatures in browser code. The operator private key must remain in a protected server-side secret store.

## Production readiness checklist

* All wallet mutations are atomic and use decimal-safe arithmetic.
* `reqId` and `transactionId` records survive restarts and deployments.
* The operator verifies every signed callback before accessing or changing a wallet.
* The service returns the exact documented business status for every scenario.
* Timeouts and ambiguous results are reconciled instead of blindly repeated with new identifiers.
* Logs correlate `operatorId`, `userId`, `reqId`, `transactionId`, `roundId`, and `gameId` without recording private keys or session tokens.