Skip to main content

Tracker API Reference

Complete reference for the SealMetrics JavaScript tracker API.


Global Variables

The tracker exposes three identical global variables:

VariableDescription
sealmetricsRecommended (unique, no conflicts)
smShort form
_smBackup if others conflict

All three work identically:

sealmetrics.conv('purchase', 99.99);
sm.conv('purchase', 99.99);
_sm.conv('purchase', 99.99);

Methods

sealmetrics()

Track a pageview. Called automatically on page load and SPA navigation.

sealmetrics();
sealmetrics(options);
ParameterTypeRequiredDescription
optionsobjectNoConfiguration options
options.groupstringNoContent grouping for this page

Examples:

// Manual pageview (rarely needed)
sealmetrics();

// Pageview with content grouping
sealmetrics({ group: 'blog' });
sealmetrics({ group: 'product' });
sealmetrics({ group: 'checkout' });

When to call manually:

  • Rarely needed — pageviews are automatic
  • Use when you need to override the content group
  • Use for hash-based routing where automatic detection doesn't work

sealmetrics.conv()

Track a conversion (goal completion with monetary value).

sealmetrics.conv(type, amount);
sealmetrics.conv(type, amount, properties);
ParameterTypeRequiredDescription
typestringYesConversion type (e.g., 'purchase', 'lead', 'signup')
amountnumberNoMonetary value. Omit or use 0 for non-monetary conversions. Only sent when it is a number
propertiesobjectNoCustom key-value data

Examples:

// Simple purchase
sealmetrics.conv('purchase', 99.99);

// Purchase with properties
sealmetrics.conv('purchase', 149.99, {
currency: 'EUR',
payment_method: 'credit_card'
});

// Lead (no monetary value)
sealmetrics.conv('lead', 0, {
form_name: 'contact',
source: 'homepage'
});

// Subscription
sealmetrics.conv('subscription', 49, {
plan: 'pro_monthly',
currency: 'USD'
});

sealmetrics.micro()

Track a microconversion (user interaction or funnel step).

sealmetrics.micro(type);
sealmetrics.micro(type, properties);
ParameterTypeRequiredDescription
typestringYesEvent type (e.g., 'add_to_cart', 'video_play')
propertiesobjectNoCustom key-value data

Examples:

// Simple microconversion
sealmetrics.micro('add_to_cart');

// With properties
sealmetrics.micro('add_to_cart', {
product_id: 'SKU-123',
product_name: 'Blue Shoes',
price: '89.99'
});

// Video engagement
sealmetrics.micro('video_play', {
video_id: 'demo-2025',
video_title: 'Product Tour'
});

// Scroll depth
sealmetrics.micro('scroll_50');

Properties

Properties are key-value pairs attached to conversions and microconversions.

Data Types

All property values are transmitted as strings. Numbers and booleans are automatically converted:

// Both are equivalent
sealmetrics.conv('purchase', 99, { quantity: 3 });
sealmetrics.conv('purchase', 99, { quantity: '3' });

Common Properties

PropertyDescriptionExample
currencyISO 4217 currency code'EUR', 'USD'
product_idProduct SKU or ID'SKU-123'
product_nameProduct name'Blue Shoes'
categoryProduct category'footwear'
priceItem price'89.99'
quantityNumber of items'2'
payment_methodPayment type'credit_card'
couponDiscount code'SAVE10'
planSubscription plan'pro'
billing_cycleBilling frequency'monthly'

Property Limits

  • Maximum properties per event: No hard limit, but keep reasonable
  • Property name max length: 100 characters
  • Property value max length: 500 characters
  • Total request body max: 15 KB. The server reads at most 15 KB of the POST body; anything beyond that is silently ignored (the request still returns 204).

Content Grouping

Content grouping categorizes pages into sections for analysis.

Setting via URL Parameter

<script src="https://t.sealmetrics.com/t.js?id=YOUR_ID&group=blog" defer></script>
Group name format

When set via the group URL parameter, the value is validated against the regular expression ^[a-zA-Z0-9_-]{0,64}$ (letters, digits, _ and -, up to 64 characters). An invalid group value makes the /t.js request return HTTP 400 and the script is not served. The same constraint applies to the value passed to sealmetrics({ group }).

Setting via JavaScript

// Override default grouping
sealmetrics({ group: 'product' });

Common Groups

GroupUse Case
blogBlog posts, articles
productProduct detail pages
categoryCategory/listing pages
cartShopping cart
checkoutCheckout flow
landingLanding pages
supportHelp, documentation
accountUser account pages

Payload Specification

Pageview Payload

{
"a": "YOUR_ACCOUNT_ID",
"s": "1abc123def456",
"t": "hmac_token",
"u": "https://example.com/page?utm_source=google&utm_medium=cpc",
"r": "https://google.com/search",
"z": "Europe/Madrid",
"c": 1703001234567,
"g": "blog"
}
FieldDescription
aAccount ID
sSession ID (auto-generated)
tHMAC anti-spam token
uCurrent URL
rReferrer URL
zIANA timezone
cTimestamp (milliseconds)
gContent group (optional)
UTMs and click IDs are parsed server-side

The tracker does not send a separate parameters field. UTM tags (utm_source, utm_medium, …) and ad click IDs (gclid, fbclid, …) are extracted server-side from the current URL (u), so they must be present in the page URL for attribution to work.

Conversion Payload

Includes all pageview fields plus:

{
"e": "purchase",
"v": 149.99,
"x": {
"currency": "EUR"
}
}
FieldDescription
eEvent type
vMonetary value (optional — only present when amount is a number)
xCustom properties (optional)

Microconversion Payload

Includes all pageview fields plus:

{
"e": "add_to_cart",
"m": true,
"x": {
"product_id": "SKU-123"
}
}
FieldDescription
eEvent type
mMicroconversion flag (true)
xCustom properties

Session Identification

Session IDs are automatically generated using privacy-preserving browser characteristics. No cookies or personal data are used.


Automatic Behavior

Automatic Pageview

A pageview is tracked automatically when the script loads. You don't need to call sealmetrics() manually on page load.

SPA Navigation Detection

The tracker automatically detects Single Page Application navigation by intercepting:

  • history.pushState()
  • history.replaceState()
  • popstate event (browser back/forward)

Each URL change triggers a new pageview with the previous URL as the referrer.

Data Transmission

Events are sent using navigator.sendBeacon() with a fallback to fetch():

  1. sendBeacon (preferred): Works even when closing the tab
  2. fetch with keepalive: Fallback if sendBeacon fails

Events are sent as a POST with Content-Type: application/x-www-form-urlencoded. The JSON payload travels in the form field d (d=<json>). This avoids CORS preflight requests and WAF blocks.


Read-only Properties

Beyond the methods, the global object exposes a few read-only properties, useful for debugging or for forwarding the session ID to other systems:

PropertyTypeDescription
sealmetrics.sessionIdstringThe fingerprint-based session ID for the current visitor
sealmetrics.accountIdstringThe account/site ID embedded in the served script
sealmetrics.tzstringThe visitor's IANA timezone (e.g., 'Europe/Madrid')
sealmetrics.autoModestring'1' if the auto-pageview is enabled, '0' if loaded with ?auto=0
console.log(sealmetrics.sessionId); // "1abc123def456"
console.log(sealmetrics.autoMode); // "1"

Manual Pageview Mode (?auto=0)

By default the tracker fires the initial pageview as soon as the script runs. Loading the tracker with ?auto=0 keeps everything wired up (SPA listeners, conv(), micro()) but skips the automatic initial pageview — you are then responsible for firing it manually:

<script src="https://t.sealmetrics.com/t.js?id=YOUR_ID&auto=0" defer></script>
<script>
window.addEventListener('load', function () {
// Fire the pageview yourself, e.g. with a custom group after your dataLayer is ready
sealmetrics({ group: 'checkout' });
});
</script>
?auto= valueBehavior
missing / empty / 1Auto-pageview ON (default)
0Auto-pageview OFF (manual mode)
any other valueAuto-pageview ON (defensive default)

SPA navigation listeners (pushState / replaceState / popstate) stay active in both modes; only the initial pageview is suppressed by ?auto=0.


Pre-load Queue (stub)

For integrations where the tracker may load after the first sealmetrics(...) call (e.g., Google Tag Manager with several tags, or deferred loading), inject this tiny fbq-style stub before the real library. It buffers calls in sealmetrics.q until the library boots, then replays them in FIFO order:

<script>
!function(w){w.sealmetrics=w.sealmetrics||function(){(w.sealmetrics.q=w.sealmetrics.q||[]).push(['pv',arguments])};w.sealmetrics.q=w.sealmetrics.q||[];w.sealmetrics.conv=w.sealmetrics.conv||function(){w.sealmetrics.q.push(['cv',arguments])};w.sealmetrics.micro=w.sealmetrics.micro||function(){w.sealmetrics.q.push(['mc',arguments])}}(window);
</script>
  • Each queued entry is [marker, arguments], where the marker is 'pv' (pageview), 'cv' (conversion) or 'mc' (microconversion). These markers are a stable, permanent contract.
  • The stub is idempotent (|| guards): pasting it twice is a no-op.
  • The queue is drained before the optional auto-pageview, so order is: queued calls (FIFO) → auto-pageview (if enabled).
Always pair the stub with ?auto=0

If you enqueue a pageview through the stub and leave the auto-pageview on, both will fire and you get two pageviews per session. The canonical pattern is the stub + ?auto=0, firing the pageview yourself from the queue.


Behavior Inside Iframes

The tracker checks whether it runs at the top level (window.self === window.top):

  • Top-level page: auto-pageview + SPA navigation listeners + conv() / micro() — everything works normally.
  • Inside an iframe (e.g., the Shopify Web Pixel sandbox): the tracker exposes conv() and micro() only. It does not fire an auto-pageview and does not install SPA navigation hooks.

This prevents duplicate pageviews when the tracker runs both on the real page and inside an embedded sandbox. In iframe contexts (Shopify), call sealmetrics.conv() / sealmetrics.micro() directly and do not inject the pre-load stub inside the iframe.


Automatically Detected Click IDs

Ad click IDs do not need any configuration. When present in the page URL, the server detects them and infers source/medium automatically:

Click IDPlatformInferred source / medium
gclidGoogle Adsgoogle / cpc
gbraidGoogle Ads (iOS)google / cpc
wbraidGoogle Ads (Web-to-App)google / cpc
fbclidMeta / Facebookfacebook / social
msclkidMicrosoft / Bing Adsbing / cpc
yclidYandexyandex / cpc
ttclidTikToktiktok / cpc
twclidTwitter / Xtwitter / cpc
li_fat_idLinkedInlinkedin / cpc
ScCidSnapchatsnapchat / cpc
rdt_cidRedditreddit / cpc

Explicit UTM parameters in the URL always take precedence over the values inferred from a click ID.


TypeScript Declarations

For TypeScript projects, add these declarations:

// types/sealmetrics.d.ts
interface SealmetricsOptions {
group?: string;
}

interface SealmetricsFunction {
(options?: SealmetricsOptions): void;
conv(type: string, amount?: number, properties?: Record<string, string>): void;
micro(type: string, properties?: Record<string, string>): void;
readonly sessionId: string;
readonly accountId: string;
readonly tz: string;
readonly autoMode: string;
}

declare global {
const sealmetrics: SealmetricsFunction | undefined;
const sm: SealmetricsFunction | undefined;
const _sm: SealmetricsFunction | undefined;
}

export {};

Technical Specifications

SpecificationValue
Size (minified)~2,228 bytes
Size (gzipped)~1,227 bytes
DependenciesNone (vanilla JavaScript)
Browser SupportChrome 60+, Firefox 55+, Safari 11.1+, Edge 79+
ES VersionES5 compatible
CookiesNone
localStorageNone
sessionStorageNone