Integration guide
One hub, many landing domains. Register a domain in the admin, drop one script tag on the page, and every ad-lifecycle event lands in the dashboard within seconds.
1 · Install the tracker
Add to <head> with the public key from Admin → Sites.
<script async src="https://event.noomijum.com/sdk.js" data-key="YOUR_PUBLIC_KEY"></script>
The tracker auto-tracks page views, assigns a visitor id (1st-party localStorage) and a 30-minute session, buffers events and flushes them in batches with navigator.sendBeacon on unload.
2 · Tracker API
The tracker exposes a single global window.nx. Slots: top, anchor, interstitial, rewarded, prewarm.
// Ad lifecycle (Google Ad Manager)
nx.ad('ad_request', { slot: 'top', ad_unit: '/1234/top', size: '300x250' });
nx.ad('ad_filled', { slot: 'top', cpm_win: 2.45, cpm_start: 5.00, waterfall_step: 3,
attempts: 3, latency_ms: 820, advertiser_id: '55', prewarmed: false });
nx.ad('ad_nofill', { slot: 'top', attempts: 6, waterfall_step: 6, latency_ms: 1400 });
nx.ad('ad_viewable', { slot: 'top' });
nx.ad('ad_click', { slot: 'top' });
// Funnel & engagement
nx.track('step', { label: 'quiz_start' });
nx.track('cta_click', { label: 'see_results' });
nx.track('rewarded_granted',{ slot: 'rewarded', label: 'unlock_content' });
nx.track('outbound_click', { label: 'https://partner.example/offer' });
nx.track('error', { slot: 'top', label: 'gpt_timeout' });
// Utilities
nx.pageview(); // manual SPA page view (auto-tracked on history changes)
nx.flush(); // force-send the buffer
nx.debug(); // console.table of everything sent this session
nx.visitorId; // 1st-party visitor id
nx.sessionId(); // rolling 30-minute session id3 · HTTP ingest endpoint
Any client can post directly — no SDK required. CORS is open for registered domains.
POST https://event.noomijum.com/api/public/collect
Content-Type: application/json
{
"key": "YOUR_PUBLIC_KEY",
"events": [
{
"session_id": "s_71bc...",
"visitor_id": "v_9f3a...",
"client_ts": "2026-07-27T10:15:03.221Z",
"event_type": "ad_filled",
"page": "/lp/summer",
"referrer": "https://google.com/",
"utm_source": "google",
"slot": "top",
"ad_unit": "/1234/top",
"size": "300x250",
"cpm_start": 5.00,
"cpm_win": 2.45,
"waterfall_step": 3,
"attempts": 3,
"latency_ms": 820,
"prewarmed": false,
"label": null,
"value": null,
"meta": { "anything": "extra" }
}
]
}
204 No Content // accepted
400 { "error": "invalid_payload" }
403 { "error": "unknown_or_inactive_key" }
403 { "error": "origin_not_allowed" }
413 { "error": "payload_too_large" }
429 { "error": "rate_limited" }Up to 50 events per request, 128 KB max body. Requests are rate limited per key/IP. The server derives country, device, OS and browser; never send PII.
4 · Event types
| type | meaning | key fields |
|---|---|---|
| session_start | First hit of a new 30-min session | page, referrer, utm_* |
| pageview | Page or SPA view | page, referrer, utm_* |
| step | Funnel step reached | label |
| cta_click | In-page CTA click | label |
| ad_request | Slot requested from GAM | slot, ad_unit, size |
| ad_filled | Creative rendered (impression) | cpm_win, cpm_start, waterfall_step, attempts, latency_ms |
| ad_nofill | Waterfall exhausted | slot, attempts, waterfall_step, latency_ms |
| ad_viewable | Active view viewable | slot |
| ad_click | Creative click | slot |
| rewarded_granted | Reward unlocked | slot, label |
| outbound_click | Click to external offer | label (url) |
| error | Render / timeout / script error | slot, label |
5 · Health check
GET https://event.noomijum.com/api/public/health -> { "ok": true, "ts": "..." }6 · Adding a new domain
- Admin → Sites → Create site with the landing domain (e.g. newdomain.com).
- Copy the generated public key.
- Paste the script tag with that key on the landing page.
- Traffic appears in the dashboard and in the Sites comparison table immediately.