Web Game SDK

Cross-origin game, monetized by the parent page

An HTML5 game runs inside a cross-origin iframe and calls window.EzGameSDK. The SDK talks to the parent page over a postMessage bridge inside sa.min.js; the parent — the ads.txt-approved domain — runs the auction and renders ad breaks, rewarded ads, and banners. The game never runs an auction itself. Break modals are confined to the game's play area, not the whole page.

How it fits together

The game is embedded from a different origin (www.ezojs.com). The parent bridge only accepts frames marked with the data-ez-game attribute, so unmarked iframes are ignored. On load the parent runs ezstandalone.showAds(), which injects the rewarded-ads pipeline the bridge delegates to. Inside the frame, the game calls init then requests breaks, rewarded ads, and banners — every call is proxied to the parent and answered over the bridge.
The game's own on-screen log shows the SDK side (responses and events arriving inside the iframe). The panel below shows the parent side.

View source on GitHub →

Docs: Ezoic Documentation

Game (cross-origin iframe)

Parent bridge log (messages received from the game iframe)

waiting for messages...

Minimal game-side usage

Runs inside the game frame (served from your game's origin)
<!-- Load the game SDK from your game's origin -->
<script src="https://www.ezojs.com/ezoic/gamesdk.js"></script>
<script>
  window.EzGameSDK = window.EzGameSDK || {};
  window.EzGameSDK.cmd = window.EzGameSDK.cmd || [];

  window.EzGameSDK.cmd.push(function () {
    // Detects environment and handshakes with the parent bridge.
    // breakCooldownSec is optional (default 5, max 3600, 0 disables the gate).
    EzGameSDK.init({ breakCooldownSec: 5 }).then(function () {
      // Interstitial before gameplay starts. Pause and mute in onStart.
      EzGameSDK.commercialBreak({ position: "preroll", onStart: pauseGame });
    });
  });

  // Between levels: format picks the demand.
  // 'auto' (default) = video ad with display fallback,
  // 'display' = display ad only, 'video' = video ad only (fails if no video fill).
  function onLevelComplete() {
    EzGameSDK.commercialBreak({ position: "midgame", format: "display", onStart: pauseGame })
      .then(function (r) { if (!r.success) { resumeGame(); } });
  }

  // Rewarded ad: must be user-opted-in (offer it as a choice, never auto-fire).
  // Grant the reward only when rewarded === true.
  function offerReward() {
    EzGameSDK.rewardedBreak({ rewardName: "extra_life", onStart: pauseGame })
      .then(function (r) { if (r.rewarded) { grantExtraLife(); } });
  }

  // Anchored banner. Ezoic offers every standard size fitting the box and
  // resolves only after the fill is confirmed.
  EzGameSDK.showBanner({ width: 320, height: 50, anchor: "bottom" });

  // Gameplay signals: suppress page-level interstitials during play.
  // EzGameSDK.gameplayStart() / EzGameSDK.gameplayStop()

  // Adblock detection:
  // EzGameSDK.hasAdBlock().then(function (blocked) { ... });
</script>

API reference

init(config?) — handshakes with the parent bridge and resolves {environment} (ezoic, local, or unavailable). Optional breakCooldownSec sets the minimum interval between ad breaks (default 5, clamped 0–3600, 0 disables). Only the SDK init can set it — games cannot override it per call.

commercialBreak(config?) — full-frame ad break confined to the game's play area. position: 'preroll' | 'midgame' (default). format: 'auto' (video with display fallback, default) | 'display' | 'video' (no fallback — resolves {success:false, error:'unfilled'} when no video demand fills). onStart fires right before the ad displays — pause and mute there. Resolves {success, error?, message?}; error codes include adCooldown, busy, unfilled, timeout, and internal.

rewardedBreak(config?) — user-opted-in rewarded ad. rewardName labels the reward for analytics. Resolves {success, rewarded, error?}; grant the reward only when rewarded === true (the user watched to completion).

showBanner(config?) / hideBanner() — anchored banner (width, height, anchor: 'top' | 'bottom'). The parent offers every standard ad size that fits the requested box and showBanner resolves only after fill confirmation, so {success:false} genuinely means no ad.

gameplayStart() / gameplayStop() — signal active play; the parent suppresses page-level interstitials while gameplay is active.

hasAdBlock() — resolves true when an ad blocker is detected (bridge-assisted on Ezoic pages, local heuristic elsewhere).