Guides

Ads and rewarded ads

AdminUpdated Sep 22, 2026

Ads and rewarded ads

Your game never loads ad code itself. It asks for an ad with GameSDK.requestAd(). The Cool GPT Games page that hosts your game then fetches the ad, shows it in an overlay on top of your iframe, and tells your game how it went. Because of this, a game can't fake an impression, pick an ad network, or grant itself a reward that the ad server didn't confirm.

This guide covers:

  • the two kinds of ad you can request

  • the lifecycle events and how to pause around an ad

  • what a "rewarded" result guarantees

  • limits

  • how the visitor's consent and age answers change what's served

  • how ad revenue relates to creator earnings

For exact signatures, resolved values and failure modes, see GameSDK reference: ads, economy & tournaments.

Quick start

// A "watch an ad for an extra life" button.
continueButton.onclick = async function () {
  continueButton.disabled = true;
  const result = await GameSDK.requestAd("rewarded");
  continueButton.disabled = false;

  if (result && result.rewarded === true) {
    grantExtraLife();          // the ad server confirmed the reward
  } else {
    showMessage("No reward this time.");
  }
};

// Pause and mute while any ad is on screen.
GameSDK.on("adStarted", function () { pauseGame(); muteAudio(); });
GameSDK.on("adComplete", function () { resumeGame(); unmuteAudio(); });
GameSDK.on("adError", function (e) {
  if (e.reason !== "busy") { resumeGame(); unmuteAudio(); }  // "busy": another ad is still showing
});

Placements

requestAd(placement) accepts one argument. The SDK recognises exactly one value, "rewarded". Any other value, including no value, is sent as a "midroll" request.

You pass

What is requested

What the player sees

Needs a play session

Can grant a reward

"rewarded"

Rewarded ad

An "Advertisement" card over the game with a 5-second "Reward in Ns" countdown and a close (✕) button. The creative may be clickable and opens in a new tab.

No. It works from a menu before gameplay starts.

Yes, when the ad server confirms it

anything else ("midroll", "interstitial", undefined, …)

Midroll (interstitial) ad

An "Ad" overlay reading "Your game continues shortly…" for about 2 seconds

Yes. See Midroll needs a session.

Never. The result is always { rewarded: false }.

The platform also defines preroll and banner placements, but you can't request them from the game SDK. Site banners are placed around the player by the page, not by your game.

Midroll fill is not guaranteed and may be unavailable for long periods. Treat no_fill as a normal outcome, and never block progress on a midroll ad.

Midroll needs a session

A midroll request is sent through the Cool GPT Games API and tied to the current play session. The page starts that session when your game calls GameSDK.start() (or GameSDK.replay.ready()). If you request a midroll before either call, it fails right away: the promise resolves { error: "no_session" } and adError fires with { reason: "no_session" }.

Rewarded ads have no such requirement.

Lifecycle

Every requestAd call settles exactly once, with exactly one outcome: either adComplete or adError fires, never both. Along the way it may also fire adStarted. You subscribe to these events with GameSDK.on(name, callback):

Event

Payload

Fired when

adStarted

none

The ad overlay is now covering your game

adComplete

{ rewarded: boolean }

The ad finished or the player closed it

adError

{ reason: string }

No ad could be shown, or the request timed out

Sequences you will see

Situation

Events, in order

Promise resolves to

Rewarded, watched to the end, reward confirmed

adStartedadComplete {rewarded:true}

{ rewarded: true }

Rewarded, watched to the end, ad server declined the reward

adStartedadComplete {rewarded:false}

{ rewarded: false }

Rewarded, player closed it early (✕)

adStartedadComplete {rewarded:false}

{ rewarded: false }

Midroll shown

adStarted → (~2 s) → adComplete {rewarded:false}

{ rewarded: false }

No ad available

adError {reason:"no_fill"}

{ error: "no_fill" }

Midroll before GameSDK.start()

adError {reason:"no_session"}

{ error: "no_session" }

Visitor hasn't allowed ads

adError {reason:"no_consent"}

{ error: "no_consent" }

Another ad is already running

adError {reason:"busy"} (the running ad carries on)

{ error: "busy" }

No answer within 60 seconds

adError {reason:"timeout"} (fired by the SDK)

{ error: "timeout" }

Network or other failure

adError {reason:"error"}

{ error: "error" }

adStarted doesn't fire in any of the error cases, so you only need to pause from adStarted, not from the moment you call requestAd.

A busy answer is about the new request only. The ad that was already running still ends with its own adComplete or adError, so don't resume your game on a busy error.

Pausing and resuming around ads

The platform does not pause your game for you when an ad starts. Your game keeps running underneath the overlay. Pause gameplay, timers and audio on adStarted, and resume on adComplete or adError.

Separately, the SDK fires pause and resume when the browser tab is hidden or shown again. Those events come from tab visibility, not from ads. Handle them too, but don't rely on them for ads.

let adPaused = false;
GameSDK.on("adStarted", function () { adPaused = true; game.pause(); audio.mute(); });
function endAd() {
  if (!adPaused) return;          // nothing was paused (the ad never started)
  adPaused = false;
  game.resume(); audio.unmute();
}
GameSDK.on("adComplete", endAd);
GameSDK.on("adError", function (e) { if (e.reason !== "busy") endAd(); });

// Tab visibility, independent of ads:
GameSDK.on("pause", function () { game.pause(); });
GameSDK.on("resume", function () { if (!adPaused) game.resume(); });

What "rewarded" guarantees

{ rewarded: true } means all of the following happened:

  1. A rewarded ad was fetched and shown to the player.

  2. The player left it open until the 5-second countdown reached zero.

  3. The page then redeemed the ad server's single-use reward token, and the ad server replied that the reward was granted.

rewarded is never true when the player closed the ad early, when no ad filled, or when the redemption call failed or was declined. Each ad's reward token can be redeemed only once.

What it does not guarantee:

  • It doesn't grant anything on its own. The platform sends no coins, XP or items for a rewarded ad. Your game decides what the reward is and grants it when it sees rewarded === true.

  • It isn't a server-side receipt your backend can check. The result is delivered to your game's JavaScript. Keep rewarded-ad rewards to in-game conveniences, such as an extra life, a hint or a continue. - It doesn't mean the player is signed in. Rewarded ads work for guests too.

Frequency and limits

Limit

Value

Effect on your game

One ad at a time

The page runs one ad at a time

Calling requestAd while an ad is running resolves { error: "busy" } straight away. The running ad isn't affected. Disable your ad button until the call settles.

Timeout

60 seconds

If the page doesn't finish the ad within 60 seconds (for example, the message was dropped), the promise resolves { error: "timeout" } and adError {reason:"timeout"} fires.

Messages to the page

30 SDK messages per second, across all SDK calls

Extra messages are silently dropped. A dropped requestAd resolves { error: "timeout" } after 60 seconds.

Ad requests and ad events

60 per minute per play session (or per game, when there's no session)

Each request logs several events, so a tight loop will be throttled and start failing with error.

There's no per-session cap on how many rewarded ads a player can watch, and no enforced minimum gap between midrolls today. Space midrolls out anyway, and only show them at natural breaks such as between levels or after a game over. Never show one during active play.

Consent and age

The site asks visitors for ad consent with a cookie banner. Personalised ads also require an age question ("Are you 13 or older?"). Your game can't read or change any of this. It only sees how it affects requestAd:

Visitor's state

What the game sees

Hasn't answered the consent banner yet, the banner couldn't load (for example, it was blocked), or ads were rejected

No ad is requested. adError {reason:"no_consent"} fires and the promise resolves { error: "no_consent" }.

Allowed ads but not personalised ads, or is under 13, or hasn't declared an age

Contextual (non-personalised) ads only. The game sees normal behaviour.

Allowed personalised ads and declared 13 or older

Personalised ads may be served. The game sees normal behaviour.

Game played through an embed on another website

Contextual ads only, because the host site owns consent there. The game sees normal behaviour.

In practice:

  • no_consent is common and expected, especially early in a visit before the banner is answered. The state is checked again on every requestAd call, so a later request can succeed once the visitor answers.

  • Don't nag. Don't loop on requestAd after no_consent, and don't tell the player to change their cookie settings to get a reward. Offer the reward another way, or just hide the button.

  • Personalisation doesn't change the API. Your code is identical whether an ad is personalised or contextual. Personalised serving is also switched off site-wide at times, in which case every ad is contextual.

Ads and creator revenue

Creators can earn a share of ad revenue from their games. Everything here is creator-side. Players never earn money from ads or from anything else on the platform.

How revenue is attributed:

  • Only server-recorded ad fills count. Revenue comes from the ad server's own record of a filled ad, never from anything your game reports. You can't inflate it from the client. - Only valid play sessions count. An ad fill is attributed to your game only when it happened inside a play session the platform treats as genuine play. Sessions flagged as abusive, and ad events with no play session (such as a rewarded ad watched from a menu before GameSDK.start()), aren't counted.

  • Revenue is aggregated daily per game, then split between you and the platform. Your dashboard shows the current creator revenue-share percentage, your lifetime, last-30-day and available earnings, and any pending payouts. - Payouts are made periodically to a verified payout account that you connect in your dashboard. They're subject to a minimum payout amount and a hold period for new creator accounts. Amounts below the minimum roll over. The minimum is shown in your dashboard.

Ad earnings are real money paid to creators. They're completely separate from coins, the platform's virtual currency. Coins you earn from item sales or tournament refunds aren't converted to ad earnings, and ad earnings aren't paid in coins. See In-game economy.

No specific earnings are promised. Revenue depends on fill, the visitor's consent state, geography, the ad network and play volume, and may be zero.

Best practices

  • Offer rewarded ads as an opt-in choice ("Watch an ad to continue?"). Never force a rewarded ad.

  • Show a midroll only at a natural break, never mid-action and never right after load.

  • Always handle no_fill, no_consent, no_session, timeout and error by moving on. The game must be fully playable with zero ads.

  • Disable the ad button while a request is pending, since only one ad can run at a time (a second request gets busy).

  • Grant rewards only on result.rewarded === true, not on adComplete alone and not on adStarted.

Related

Was this page helpful?
Ads and rewarded ads