Skip to main content
The Tracking Pixel is currently in alpha. APIs and behavior may change between releases.
Who is this for? Marketers and web developers who want passive tracking on marketing sites, landing pages, or web shops — no package install or build step required.
The Immutable Tracking Pixel is a lightweight JavaScript snippet that automatically captures page views, attribution signals, form submissions, and outbound link clicks. Paste it into your site’s <head> and it starts collecting — no build step or configuration required.

What You Need

Install the Snippet

Paste this into your site’s <head> tag:
<script>
(function(){
var w=window,i="__imtbl";
w[i]=w[i]||[];
w[i].push(["init",{"key":"YOUR_PUBLISHABLE_KEY","consent":"anonymous"}]);
var s=document.createElement("script");s.async=1;
s.src="https://cdn.immutable.com/pixel/v1/imtbl.js";
document.head.appendChild(s);
})();
</script>
Replace YOUR_PUBLISHABLE_KEY with your project’s publishable key from Hub.
This snippet sets consent to anonymous, which starts collecting anonymous device signals and page views immediately. If your site requires explicit cookie consent before any tracking, see Consent Modes below.
The script loads asynchronously and does not block page rendering. It’s under 10 KB gzipped.

Verify the Integration

Open your site with the snippet installed, then check the browser developer tools:
  1. Network tab: Look for a request to https://cdn.immutable.com/pixel/v1/imtbl.js (the pixel script loading)
  2. Network tab: Look for POST requests to https://api.immutable.com (events being sent). Events flush every 5 seconds or when 20 events accumulate.
  3. Console: Type window.__imtbl to inspect the command queue
If you see the script loading and POST requests firing, the pixel is working. The consent option controls what the pixel collects. The default is none, meaning the pixel loads but does not collect anything until consent is set. See the Data Dictionary for what is collected at each level. The pixel does not provide a consent UI. You are responsible for building the cookie banner or privacy prompt and calling window.__imtbl.push(['consent', level]) when the user makes a choice. To start with the pixel inert (recommended if you have a cookie consent banner):
<script>
(function(){
var w=window,i="__imtbl";
w[i]=w[i]||[];
w[i].push(["init",{"key":"YOUR_PUBLISHABLE_KEY"}]);
var s=document.createElement("script");s.async=1;
s.src="https://cdn.immutable.com/pixel/v1/imtbl.js";
document.head.appendChild(s);
})();
</script>
Then upgrade consent after the user interacts with your cookie banner:
// After user accepts analytics cookies
window.__imtbl.push(['consent', 'anonymous']);

// Or after user accepts marketing cookies
window.__imtbl.push(['consent', 'full']);

Automatic CMP Detection

If your site uses a Consent Management Platform (such as OneTrust or Cookiebot), the pixel can detect consent state automatically:
<script>
(function(){
var w=window,i="__imtbl";
w[i]=w[i]||[];
w[i].push(["init",{"key":"YOUR_PUBLISHABLE_KEY","consentMode":"auto"}]);
var s=document.createElement("script");s.async=1;
s.src="https://cdn.immutable.com/pixel/v1/imtbl.js";
document.head.appendChild(s);
})();
</script>
When consentMode is set to auto, the pixel starts in none and checks for these standards:
  1. Google Consent Mode v2: reads analytics_storage and ad_storage from window.dataLayer
  2. IAB TCF v2: reads purpose consents via window.__tcfapi
The pixel upgrades consent automatically when the CMP signals it, and continues listening for changes (e.g. when a user updates their cookie preferences).
consentMode and consent are mutually exclusive. Do not set both.
You can downgrade consent at any time. Downgrading to none purges any PII from the local event queue:
window.__imtbl.push(['consent', 'none']);

What the Pixel Tracks Automatically

Once consent is set to anonymous or higher, the pixel captures these events with no additional code:
EventWhen it firesWhat it captures
Page viewEvery page loadUTM parameters, click IDs (gclid, fbclid, ttclid, msclkid, dclid, li_fat_id), referrer, landing page, referral codes
Session startNew session beginsSession ID
Session endPage unloadSession ID, duration in seconds
Form submissionHTML form submitForm action, ID, name, field names. At full consent: SHA-256 hashed email.
Outbound link clickClick on external linkDestination URL, link text, element ID
Scroll depthScroll milestone reached (25%, 50%, 75%, 90%, 100%)Milestone depth, session ID. On above-the-fold pages: depth and above-fold flag after a 2-second dwell.

Cross-Subdomain Tracking

To track users across subdomains (e.g. www.example.com and shop.example.com), set the domain option:
window.__imtbl.push(["init",{"key":"YOUR_PUBLISHABLE_KEY","consent":"anonymous","domain":".example.com"}]);

Content Security Policy

If your site enforces a Content-Security-Policy header, add these directives:
script-src: https://cdn.immutable.com
connect-src: https://api.immutable.com
For nonce-based CSP, add the nonce attribute to the inline <script> tag. The nonce covers the inline snippet only — the CDN-loaded script is authorized by the script-src directive above.
<script nonce="YOUR_NONCE">
(function(){
var w=window,i="__imtbl";
w[i]=w[i]||[];
w[i].push(["init",{"key":"YOUR_PUBLISHABLE_KEY","consent":"anonymous"}]);
var s=document.createElement("script");s.async=1;
s.src="https://cdn.immutable.com/pixel/v1/imtbl.js";
document.head.appendChild(s);
})();
</script>

Configuration

Init Options

Pass these options to the init command when initializing the pixel.
OptionTypeDefaultDescription
keystring(required)Your Immutable publishable API key from Hub
consent'none' | 'anonymous' | 'full''none'Initial consent level
consentMode'auto'undefinedEnable automatic CMP detection (Google Consent Mode v2, IAB TCF v2). Mutually exclusive with consent.
domainstringCurrent hostnameCookie domain scope. Set to .example.com for cross-subdomain tracking.
autocapture.formsbooleantrueAuto-capture HTML form submissions
autocapture.clicksbooleantrueAuto-capture outbound link clicks
autocapture.scrollbooleantrueAuto-capture scroll depth milestones
<script>
(function(){
var w=window,i="__imtbl";
w[i]=w[i]||[];
w[i].push(["init",{
  "key":"YOUR_PUBLISHABLE_KEY",
  "consent":"anonymous",
  "domain":".example.com",
  "autocapture":{"forms":true,"clicks":false}
}]);
var s=document.createElement("script");s.async=1;
s.src="https://cdn.immutable.com/pixel/v1/imtbl.js";
document.head.appendChild(s);
})();
</script>

Command Queue

All commands use the window.__imtbl.push() pattern. The command queue buffers calls made before the pixel script finishes loading, then replays them in order.
CommandArgumentsDescription
['init', options]Init options (see above)Initialize the pixel. Must be called exactly once.
['consent', level]'none' | 'anonymous' | 'full'Update the consent level at runtime. Downgrading to none purges PII from the local event queue.
['page', properties?]Record<string, unknown> (optional)Manually fire a page view with optional custom properties.
The pixel fires a page view automatically on load. Use the page command to manually trigger additional page views — for example, on virtual route changes:
window.__imtbl.push(['page', { section: 'pricing' }]);
Full SPA support with automatic route change detection is planned for a future release. For now, use manual page calls or the Web SDK for SPA route tracking.

Auto-Capture

By default, the pixel automatically captures form submissions and outbound link clicks. You can disable either or both:
// Disable form capture, keep click tracking
window.__imtbl.push(["init",{
  "key":"YOUR_PUBLISHABLE_KEY",
  "consent":"anonymous",
  "autocapture":{"forms":false,"clicks":true}
}]);

// Disable all auto-capture (only page views and sessions)
window.__imtbl.push(["init",{
  "key":"YOUR_PUBLISHABLE_KEY",
  "consent":"anonymous",
  "autocapture":{"forms":false,"clicks":false}
}]);

Event Delivery

  • Events are batched and flushed every 5 seconds or when 20 events accumulate, whichever comes first
  • The session_end event uses navigator.sendBeacon() to ensure delivery on page unload
  • All events include surface: "pixel" to distinguish them from Web SDK events in the pipeline

FAQ

Yes — they’re complementary, not alternatives. The Pixel handles passive capture (page views, attribution, form submissions, outbound clicks) with no code beyond the snippet. Add the Web SDK when you need custom events, user identity, or SPA route tracking.
The pixel uses first-party cookies and standard fetch() requests, which minimizes interference from ad blockers. First-party domain hosting further reduces this risk.
The pixel fires a page view on initial load only. For SPA route changes, use the Web SDK’s page() method. SPA support is planned for a future pixel release.
Under 10 KB gzipped. The script loads asynchronously and does not block page rendering.
Chrome 80+, Firefox 78+, Safari 14+, Edge 80+.
Use consentMode: 'auto' for automatic detection. Or manually call window.__imtbl.push(['consent', 'full']) from your CMP’s callback.

Next Steps

Data Dictionary

What the pixel collects at each consent level

REST API

Send events from your backend or game server

Web SDK

Typed SDK for SPAs, custom events, and user identity

API Keys

Manage your publishable and secret keys