Skip to Content
Integration guide

Add Maktub games to your site

You keep the player’s wallet. Maktub runs the games.

Connect your wallet, create a player session from your backend, and open the game in an iframe. The same integration works across the game catalog. No game SDK is required.

Before you start

Ask Maktub for your client ID, webhook secret and environment addresses. Register two public HTTPS URLs with us: your main wallet endpoint and your retry endpoint. Both use the same wallet and transaction records.

Address in the examplesPurpose
https://server.maktub.betYour backend calls the Maktub API.
https://play.maktub.betYour frontend opens the game.

Use the addresses confirmed for your environment. Keep the secret on your backend. Every session is opened in the player’s currency: send currency: { "code": "ZAR" } when creating it. Every wallet amount is in that currency. Non-USD bets (including free-bet placements) and credits may also carry usdRate, a reporting value; apply the received amount without conversion.

1. Connect your wallet

Implement the wallet webhook contract on both URLs. It receives balance queries, debits, credits and round-close notifications.

That page is the complete wallet specification: request fields, signature verification, exact HTTP responses and duplicate handling. Your database remains the source of truth for the player’s balance.

2. Create a session

When a logged-in player opens a game, call POST /session from your backend. Use the player ID from your authenticated session, not an arbitrary ID sent by the browser.

Example inside your existing authenticated backend handler:

const response = await fetch("https://server.maktub.bet/session", { method: "POST", headers: { "Content-Type": "application/json", "x-operator-secret": process.env.MAKTUB_WEBHOOK_SECRET, }, body: JSON.stringify({ clientId: process.env.MAKTUB_CLIENT_ID, userId: String(req.user.id), currency: { code: req.user.walletCurrency }, // e.g. "ZAR" }), }); if (response.status !== 200) { throw new Error("Could not create the game session"); } const session = await response.json(); const launchUrl = new URL(session.gameUrl); launchUrl.pathname = "/dice"; res.json({ launchUrl: launchUrl.toString() });

Maktub checks the player through your webhook before returning a session. Your wallet must recognize the player; a balance of zero is valid.

gameUrl already includes the Maktub token. Set its path to the chosen game and keep its query parameters. Share the resulting URL only with that player and keep it out of logs.

Need your own reference on the webhooks? See session references.

3. Show the game

Add an iframe to your page and set its src to the launchUrl returned by your backend:

<iframe id="maktub-game" title="Maktub game" style="width:100%;height:730px;border:0;display:block" allow="fullscreen; clipboard-write" ></iframe>
// launchUrl is the string received from your backend. const frame = document.getElementById("maktub-game"); frame.src = launchUrl;

The iframe handles gameplay, including WebSocket connections. If your site uses CSP, allow the Play origin in frame-src.

This fixed-size embed is enough to start. For automatic height changes on small screens, add the resize listener.

4. Test before going live

Open the Webhook Tester  with a disposable player holding 0.10–1.00 in your wallet’s currency. Enter your endpoint, secret, client ID, test player ID and the wallet’s currency code. Use your own session reference only if you supplied one when creating the session. Enter the retry endpoint registered during onboarding as well.

The tester runs 27 checks: 23 wallet checks and four retry checks, each with an explanation of failures. It moves money and attempts to restore the starting balance after every check. Keep this wallet idle elsewhere during the run. If recovery is required, reconcile its ledger before reusing it.

A zero-balance wallet runs four read-only diagnostics and skips 23 money checks. Passing those diagnostics does not validate debits or credits. The tester probes authentication independently and reports whether each endpoint requires HMAC, accepts the shared secret, or requires both.

Finally, open each game you plan to offer, play a test round and match its webhooks to your wallet ledger. A tester pass does not verify live delivery or game availability.

Add only what you need

If you need…Read…
Field types, errors or session renewalSessions
A different gameGame catalog
Colors, language or logosAppearance
Resize, loading or login messagesBrowser events
Promotional wagersFree bets