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.
- A Predictu operator account (created by Predictu staff via God Mode)
- Your operator
slugandoperator_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
Predictu staff creates your operator record in God Mode. You will receive:
| Field | Example | Description |
|---|---|---|
operator_id | a1b2c3d4-... | UUID identifying your operator. Used in all API calls and data scoping. |
slug | example-casino | URL-safe identifier. Passed as the operator query parameter in the iframe URL. |
api_key | sk_live_... | Secret API key for authenticating Operator Dashboard API requests. Keep this secure. |
s2s_callback_url | https://api.example.com/predictu/callback | Your backend endpoint that will receive S2S wallet callbacks from Predictu. |
Step 2: Configure Branding
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
In the Operator Dashboard, navigate to the Embed Config tab and add your site's origin to the whitelist:
https://www.example-casino.comThe origin must be an exact match including protocol and port (if non-standard). You can add multiple origins for staging and production environments:
| Origin | Environment |
|---|---|
https://www.example-casino.com | Production |
https://staging.example-casino.com | Staging |
http://localhost:3002 | Local development |
Step 4: Embed the Iframe
Add the Predictu iframe to your casino page. The URL format is:
https://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:
| Attribute | Value | Why |
|---|---|---|
sandbox | allow-scripts allow-same-origin allow-popups allow-forms | Enables JS execution, Supabase auth cookies, popup confirmations, and form submissions while blocking other capabilities. |
allow | clipboard-write | Lets the trading UI copy share links and referral codes to clipboard. |
loading | lazy | Defers iframe load until it enters the viewport (optional performance optimization). |
Step 5: Wire Up the PostMessage Bridge
The PostMessage bridge is how your casino shell communicates with the Predictu iframe. You need to:
- Send
predictu:initto authenticate the player and set their initial balance. - Listen for events from the iframe (ready, balance, trade, navigate).
- 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:
| Check | Expected Result | Troubleshoot |
|---|---|---|
| Iframe loads | You see the Predictu trading UI with your branding colors | Verify the operator slug is correct in the iframe URL |
predictu:ready received | Console logs "Predictu iframe is ready" | Check that your origin is in the whitelist and predictu:init was sent |
| Balance shows correctly | Player sees the balance you sent in predictu:init | Ensure balance is a number in dollars (not cents) |
| Player can trade | Clicking "Buy YES" opens the trade ticket, trade executes | Check browser console for PostMessage errors or CORS issues |
predictu:trade received | Console logs trade details after execution | Verify your message listener is checking the correct origin |
| Branding applied | UI matches your configured colors, logo visible | Open Operator Dashboard and verify branding was saved |
Next Steps
You now have a working prediction market integration. To go deeper:
