Skip to content

Embedding

The sportsbook runs in an iframe on your page. The embed SDK creates the iframe, passes the launch token, sizes it, checks the origin of every message and gives you callbacks for what happens inside. It has no dependencies and weighs about 5 KB.

<div id="sportsbook"></div>
<script src="https://sportsbook.example.com/embed/v1.js"></script>
<script>
const sb = BookmakerSportsbook.mount('#sportsbook', {
url: 'https://sportsbook.example.com',
tenant: 'your-tenant',
launchToken: '<launch token from your server>', // omit for anonymous browsing
height: matchMedia('(max-width: 899px)').matches ? 'fill' : 'auto',
onLoginRequired: () => openYourLogin(),
onDepositRequested: () => openYourCashier(),
onBalanceChanged: ({ balance, currency }) => updateYourHeader(balance, currency),
onSessionExpired: () => fetchLaunchTokenFromYourServer(), // a string, a promise of one, or null
});
</script>

/embed/v1.js is the SDK for protocol version 1. It receives compatible fixes under the same URL and is served with Cache-Control: public, max-age=3600, stale-while-revalidate=86400 and Access-Control-Allow-Origin: *. Do not add an integrity attribute: the next compatible update would break it.

Option Type
url string Sportsbook base URL. Its origin is the only one the SDK talks to. Required.
tenant string Your tenant id. Required.
launchToken string From your server (Player sessions). Omit it and players browse anonymously.
path string First route, see deep links.
locale 'en' | 'pt-BR' Language; default the tenant’s.
height 'auto' | 'fill' Sizing mode. Default 'fill'.
minHeight number auto mode: height in px until the first resize event. Default 600.
scrollOffset number | false auto mode: when the player opens another sportsbook page while the top of the iframe is scrolled out of view, the SDK scrolls your page back to it, leaving this many pixels for your sticky header. Default 0; false turns it off.
title string Accessible name of the iframe. Default Sportsbook.
onReady, onLoginRequired, onDepositRequested, onBalanceChanged, onBetPlaced, onBetSettled, onRouteChange, onResize, onError function One callback per event, called with its payload.
onSessionExpired function Return a fresh launch token (or a promise of one) and the SDK sends set_launch_token; return null to leave the player logged out. One call at a time.
onEvent function (type, payload) for every event, after the specific callback.

A callback that throws is reported with console.error and does not stop the others.

Member
setLaunchToken(token) Log a player in, or replace an expired session, without reloading the iframe.
navigate(path) Go to a deep link.
setLocale(locale) en or pt-BR.
refreshBalance() Re-read the balance from your wallet, e.g. after a deposit in your cashier. The iframe answers with balance_changed.
logout() End the sportsbook session (call it when the player logs out of your site).
on(type, handler) Subscribe to one event type; returns an unsubscribe function.
ready Promise of the ready payload.
iframe, origin The iframe element and the sportsbook origin.
destroy() Remove the iframe and every listener.

Commands sent before the sportsbook is ready are queued and sent after ready.

Any page can frame the sportsbook and speak the postMessage protocol directly. Use the launchUrl returned by integration/sessions, or build the URL yourself:

https://sportsbook.example.com/?tenant=<tenant>&launch=<launchToken>&path=/live&locale=pt-BR&height=fill&origin=https%3A%2F%2Fwww.your-site.example
Parameter
tenant Required. Also tells the server which frame-ancestors to send.
launch The single-use launch token. Removed from the iframe’s address at once.
path First route (deep links). An invalid path is ignored and reported with an error event.
locale en or pt-BR.
height auto or fill (default). In auto the page must not depend on the viewport height, so tell the sportsbook.
origin Your page’s origin. Browsers without location.ancestorOrigins (Firefox) use it, or the Referer, to know who the parent is. It is checked against your allowed origins like any other.
token Deprecated: the session token itself in the URL. Still accepted for existing integrations; use launch.
<iframe id="sb" title="Sportsbook" style="width: 100%; height: 100%; border: 0"
src="https://sportsbook.example.com/?tenant=your-tenant&launch=lt_…&origin=https%3A%2F%2Fwww.your-site.example"></iframe>
<script>
const SB = 'https://sportsbook.example.com';
const frame = document.getElementById('sb');
window.addEventListener('message', (e) => {
// only our iframe, only the sportsbook origin, only protocol v1
if (e.source !== frame.contentWindow || e.origin !== SB) return;
const m = e.data;
if (!m || m.source !== 'bookmaker-sportsbook' || m.v !== 1) return;
if (m.type === 'login_required') openYourLogin();
if (m.type === 'balance_changed') updateYourHeader(m.payload.balance, m.payload.currency);
});
function send(type, payload = {}) {
// always the exact sportsbook origin, never '*'
frame.contentWindow.postMessage({ source: 'bookmaker-host', v: 1, type, payload }, SB);
}
// e.g. after your login: send('set_launch_token', { launchToken });
</script>
auto fill
Height The iframe grows to its content: the SDK sets it from every resize event. The iframe fills its container (height: 100%); give the container a height.
Scrolling Your page scrolls; the iframe has no scrollbar. The sportsbook scrolls inside the iframe.
Best for Desktop pages with your header and footer around the sportsbook. Phones and app-like layouts.
Sticky parts The sportsbook header and bet slip scroll away with the page. Header, bet slip and bottom navigation stay in view.
/* fill: the sportsbook takes the screen below your header */
#sportsbook { height: calc(100dvh - var(--your-header-height)); }

On screens narrower than 900 px the sportsbook switches to its mobile layout: a bottom navigation bar and a bottom-sheet bet slip, both fixed to the bottom of the iframe’s viewport. In auto mode that viewport is as tall as the whole sportsbook, so they would sit far below the screen. Use fill on phones, sized with dvh so the browser’s toolbars are accounted for. The reference operator chooses per device:

height: matchMedia('(max-width: 899px)').matches ? 'fill' : 'auto',
Path Opens
/ Home: live now and featured coupons
/live, /live/{sportId} In-play, all sports or one (football, basketball, tennis)
/sport/{sportId} A sport’s competitions and events
/competition/{competitionId} One competition, e.g. /competition/br-serie-a
/event/{eventId} An event with all its markets
/my-bets The player’s open and settled bets (anonymous players: login_required)

Open one at launch with path, later with navigate(path). The iframe reports every navigation with a route event ({path, title}); mirror it in your own URL to make sportsbook pages shareable, and pass it back as path on the next load:

onRouteChange: ({ path, title }) => {
const url = new URL(location.href);
url.searchParams.set('sb', path);
history.replaceState(null, '', url);
document.title = `${title} · Your Casino`;
},
path: new URLSearchParams(location.search).get('sb') ?? undefined,

en and pt-BR ship today. Pass locale at mount, or switch at any time with setLocale(); the sportsbook re-renders in place and keeps the route and the bet slip. Without either, it uses the tenant’s default locale.

Only your sites may frame the sportsbook and talk to it. List their exact origins (scheme, host and port, no path, no wildcards) in your tenant’s embedOrigins:

  • The API sends Content-Security-Policy: frame-ancestors 'self' <your origins> with every sportsbook page of your tenant ('self' alone when the list is empty), so browsers refuse to render it inside any other site.
  • The iframe reads the same list from GET /api/v1/config (tenant.embedOrigins), only accepts commands from a parent at one of those origins, and only posts events to that verified origin, never to '*'.
  • The sportsbook’s own origin is always allowed (for previews and these docs).

Set them in the back office under Configurações → Integração, or with the API (staff token):

PUT /api/v1/admin/tenant
Authorization: Bearer <staff token>
Content-Type: application/json
{"embedOrigins": ["https://www.your-casino.example", "https://m.your-casino.example"]}

If your site sends a Content Security Policy, allow the sportsbook origin for the script and the frame:

script-src 'self' https://sportsbook.example.com; frame-src https://sportsbook.example.com
In the sportsbook When embedded
Registration, login, account, deposits, withdrawals Hidden: they are yours.
Header balance Your wallet balance, labelled as such.
Deposit button Sends deposit_requested; open your cashier.
Log in button, Log in to bet, My Bets when anonymous Send login_required with a reason; open your login.
Session ends session_expired; no dialog inside the iframe.