Measure & earn

Events & measurement

The SDK measures everything for you; you never send an event by hand. This page explains what each event means, which ones brands pay for, and how to listen to them in your own code.

The events

Every filled ad request gets a signed token. The SDK reports events against that token to POST /v1/event, and each event type counts at most once per ad, so a player who collects ten cans is one engagement, not ten.

EventBonus Round (takeover)Ambient prop
requestThe SDK asked for an ad. Counted whether or not it filled; fill rate is fills ÷ requests.
impressionThe round started on screen.The prop was first rendered on screen (any visible part, not hidden behind something).
viewableThe round (which fills the whole screen) was showing in a visible tab for 2 continuous seconds.The IAB/MRC in-game rule: at least 50% of the prop's pixels in view and not hidden, the visible prop at least 1.5% of the screen, a viewing angle of at most 55°, for 1 continuous second in a visible tab (2 seconds for video or animated surfaces).
startThe round began (sent with the impression).n/a
engagementThe player entered the round and touched at least one item.The player walked up to the prop (needs native mode, where the SDK knows the player's position).
completeThe round played to the end and the sponsored leaderboard showed.n/a
clickThe player clicked the brand's call to action.
rewardA rewarded round was completed and your onReward ran.n/a

What's billed

Brands choose how they pay. Only that one event type is billed for their ads; everything else is measured for reporting.

Bid strategyBilled onTypical use
vcpmviewable, priced per 1,000Awareness; ambient props
cpeengagement: a player who actually playedThe default for Bonus Rounds
cpcclick on the call to actionTraffic

Viewability

We follow the IAB / IAB Tech Lab / MRC Intrinsic In-Game Measurement Guidelines 2.0 (2022). The SDK measures in your game, and the ad server checks the measurement again before a viewable counts or bills. We say "aligned with IIG 2.0", not "accredited": no third party has audited us yet.

AdPixels in viewSize on screenViewing angleContinuous time
Ambient prop (billboard, statue, portal arch)≥ 50%≥ 1.5% of the screen≤ 55° on any axis1 second
Video or animated surface≥ 50%≥ 1.5% of the screen≤ 55° on any axis2 seconds
Bonus Round (full takeover)The round is the whole screen, so it's always 100% in view and face-on2 seconds, in a visible tab

Listening to SDK events

Use BonusRound.on(type, cb) to react in your game: duck your music, pause a timer, log to your own analytics.

BonusRound.on('start', (e) => { music.duck(); console.log('Bonus Round by', e.brand); });
BonusRound.on('end',   (e) => { music.unduck(); analytics.track('bonus_round', e); });
BonusRound.on('reward', (e) => console.log('reward granted', e));
TypeWhenPayload
attachattach() finished{ mode }
startA Bonus Round started{ format, trigger, brand, requestId, test }
endA Bonus Round ended (whatever started it){ filled, completed, score, trigger, requestId, brand }
rewardA rewarded round was completedthe same shape as end
ambientThe ambient prop was placed{ placed, kind, brand }
eventAny measurement event was reported{ type, value }

start and end also fire for interval rounds and portal rounds that your code didn't start, which makes them the right place to pause and resume game rules.

Reports

Your game's dashboard and GET /api/games/:id/stats?days=30 show requests, fills, fill rate, impressions, viewable impressions, engagements, clicks, earnings and eCPM, by day, by brand and by format. Money is in micros (1 USD = 1,000,000).

Live, the game:<id> event stream (GET /api/live/game:<id>, server-sent events) carries sdk_ping, status, test_ad and earning events as they happen.

Privacy

The SDK sets no cookies. In contextual-only mode it stores nothing at all and uses a random id that lives for one page load (s_…), only to cap how often the same player sees a round in that session. The ad server keeps only a daily-rotating hash of it, never puts it on events, and uses no user-level or behavioural signals. IP addresses are never stored.

Contextual-only mode is on when any of these is true:

Otherwise (you said No, and the game is rated Teen or above), the SDK keeps an anonymous player id (p_…) in localStorage for frequency caps. It isn't tied to an account, an email or a device fingerprint, and consent(false) deletes it. BonusRound.debug().privacy shows which mode a page is in, and why.