Predictu
Getting Started

Quick Start

Get the Predictu prediction market experience embedded in your casino site in five steps. This guide walks you through operator setup, branding, origin whitelisting, iframe embedding, and PostMessage bridge wiring. The entire process takes under an hour.

Prerequisites. Before you begin, ensure you have:
  • A Predictu operator account (created by Predictu staff via God Mode)
  • Your operator slug and operator_id (provided during onboarding)
  • A web application where you can embed an <iframe>
  • HTTPS enabled on your site (required for cross-origin PostMessage in production)
  • A backend server to receive S2S wallet callbacks from Predictu

Step 1: Create Operator Account

1

Predictu staff creates your operator record in God Mode. You will receive:

FieldExampleDescription
operator_ida1b2c3d4-...UUID identifying your operator. Used in all API calls and data scoping.
slugexample-casinoURL-safe identifier. Passed as the operator query parameter in the iframe URL.
api_keysk_live_...Secret API key for authenticating Operator Dashboard API requests. Keep this secure.
s2s_callback_urlhttps://api.example.com/predictu/callbackYour backend endpoint that will receive S2S wallet callbacks from Predictu.
S2S setup required: You will also receive RSA key pair details for JWT verification. See the S2S Protocol docs for complete callback server setup instructions.

Step 2: Configure Branding

2

Log into the Operator Dashboard at predictu-operator.vercel.app and navigate to the Branding tab. Configure your casino's visual identity:

  • Colors - set 17 HSL color tokens (primary, accent, background, card, border, button-yes/no, etc.). All colors use the HSL format without the hsl() wrapper, e.g. "142 71% 45%".
  • Images - upload your logo, banner image, and favicon.
  • Border radius - set the global border radius (e.g. "0.75rem" for rounded, "0" for sharp corners).

The live preview panel shows your branding applied in real time. When satisfied, click Save to persist. The iframe app will pick up your branding immediately for all new sessions.

See the Operator Branding guide for the complete field reference and default values.

Step 3: Add Embed Origin

3

In the Operator Dashboard, navigate to the Embed Config tab and add your site's origin to the whitelist:

https://www.example-casino.com

The origin must be an exact match including protocol and port (if non-standard). You can add multiple origins for staging and production environments:

OriginEnvironment
https://www.example-casino.comProduction
https://staging.example-casino.comStaging
http://localhost:3002Local development
Security: The PostMessage bridge will silently drop messages from origins not in your whitelist. Always add your origin before testing the embed.

Step 4: Embed the Iframe

4

Add the Predictu iframe to your casino page. The URL format is:

GEThttps://app.predictu.com?embed=true&operator=<slug>

Full HTML embed code:

<iframe
  id="predictu-iframe"
  src="https://app.predictu.com?embed=true&operator=example-casino"
  style="width: 100%; height: 100vh; border: none;"
  sandbox="allow-scripts allow-same-origin allow-popups allow-forms"
  allow="clipboard-write"
  loading="lazy"
></iframe>

Key attributes:

AttributeValueWhy
sandboxallow-scripts allow-same-origin allow-popups allow-formsEnables JS execution, Supabase auth cookies, popup confirmations, and form submissions while blocking other capabilities.
allowclipboard-writeLets the trading UI copy share links and referral codes to clipboard.
loadinglazyDefers iframe load until it enters the viewport (optional performance optimization).

Step 5: Wire Up the PostMessage Bridge

5

The PostMessage bridge is how your casino shell communicates with the Predictu iframe. You need to:

  1. Send predictu:init to authenticate the player and set their initial balance.
  2. Listen for events from the iframe (ready, balance, trade, navigate).
  3. Optionally send deposit/withdraw commands to adjust balance from your side.

Here is the complete initialization code:

const PREDICTU_ORIGIN = "https://app.predictu.com";
const iframe = document.getElementById("predictu-iframe");

// ── Send init once iframe is ready ──────────────────────────
iframe.addEventListener("load", () => {
  iframe.contentWindow.postMessage({
    type: "predictu:init",
    user: {
      id: "player_12345",          // Your internal player ID
      displayName: "John Doe",
      email: "john@example.com",
    },
    balance: 500.00,               // Player's current balance in dollars
    operatorId: "a1b2c3d4-...",    // Your operator UUID
  }, PREDICTU_ORIGIN);
});

// ── Listen for events from the iframe ───────────────────────
window.addEventListener("message", (event) => {
  // IMPORTANT: Always validate the origin
  if (event.origin !== PREDICTU_ORIGIN) return;

  const { type, ...data } = event.data;
  if (!type || !type.startsWith("predictu:")) return;

  switch (type) {
    case "predictu:ready":
      console.log("Predictu iframe is ready and authenticated");
      break;

    case "predictu:balance":
      // Player's balance changed inside the iframe
      console.log("New balance:", data.balance);
      updateBalanceDisplay(data.balance);
      break;

    case "predictu:trade":
      // Player executed a trade
      console.log("Trade executed:", {
        side: data.side,           // "buy" or "sell"
        outcome: data.outcome,     // "yes" or "no"
        amount: data.amount,       // USD amount
        shares: data.shares,       // Number of shares
        executionPrice: data.executionPrice,
        marketTitle: data.marketTitle,
      });
      break;

    case "predictu:navigate":
      // Iframe route changed (optional - useful for deep linking)
      console.log("Iframe navigated to:", data.path);
      break;
  }
});

// ── Send deposit command (optional) ─────────────────────────
function depositToPredictu(amount) {
  iframe.contentWindow.postMessage({
    type: "predictu:deposit",
    amount: amount,  // dollars
  }, PREDICTU_ORIGIN);
}

// ── Send withdraw command (optional) ────────────────────────
function withdrawFromPredictu(amount) {
  iframe.contentWindow.postMessage({
    type: "predictu:withdraw",
    amount: amount,  // dollars
  }, PREDICTU_ORIGIN);
}

Verify Your Integration

After completing all five steps, verify the integration is working:

CheckExpected ResultTroubleshoot
Iframe loadsYou see the Predictu trading UI with your branding colorsVerify the operator slug is correct in the iframe URL
predictu:ready receivedConsole logs "Predictu iframe is ready"Check that your origin is in the whitelist and predictu:init was sent
Balance shows correctlyPlayer sees the balance you sent in predictu:initEnsure balance is a number in dollars (not cents)
Player can tradeClicking "Buy YES" opens the trade ticket, trade executesCheck browser console for PostMessage errors or CORS issues
predictu:trade receivedConsole logs trade details after executionVerify your message listener is checking the correct origin
Branding appliedUI matches your configured colors, logo visibleOpen Operator Dashboard and verify branding was saved

Next Steps

You now have a working prediction market integration. To go deeper:

1
Iframe Embedding - advanced embed options, responsive sizing, sandbox attributes, loading states.
2
PostMessage Bridge - complete message reference, origin validation, security considerations.
3
Operator Branding - full 17-token color system, HSL format, BrandingInjector internals.
4
S2S Protocol - if you want your backend to own player wallets, set up the server-to-server callback integration.
5
Risk Management - understand the 5-wall defence system and how to configure tier limits and circuit breakers.