Tracker API Reference
Complete reference for the SealMetrics JavaScript tracker API.
Global Variables
The tracker exposes three identical global variables:
| Variable | Description |
|---|---|
sealmetrics | Recommended (unique, no conflicts) |
sm | Short form |
_sm | Backup 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);
| Parameter | Type | Required | Description |
|---|---|---|---|
options | object | No | Configuration options |
options.group | string | No | Content 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);
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Conversion type (e.g., 'purchase', 'lead', 'signup') |
amount | number | No | Monetary value. Omit or use 0 for non-monetary conversions. Only sent when it is a number |
properties | object | No | Custom 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);
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Event type (e.g., 'add_to_cart', 'video_play') |
properties | object | No | Custom 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
| Property | Description | Example |
|---|---|---|
currency | ISO 4217 currency code | 'EUR', 'USD' |
product_id | Product SKU or ID | 'SKU-123' |
product_name | Product name | 'Blue Shoes' |
category | Product category | 'footwear' |
price | Item price | '89.99' |
quantity | Number of items | '2' |
payment_method | Payment type | 'credit_card' |
coupon | Discount code | 'SAVE10' |
plan | Subscription plan | 'pro' |
billing_cycle | Billing 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>
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
| Group | Use Case |
|---|---|
blog | Blog posts, articles |
product | Product detail pages |
category | Category/listing pages |
cart | Shopping cart |
checkout | Checkout flow |
landing | Landing pages |
support | Help, documentation |
account | User 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"
}
| Field | Description |
|---|---|
a | Account ID |
s | Session ID (auto-generated) |
t | HMAC anti-spam token |
u | Current URL |
r | Referrer URL |
z | IANA timezone |
c | Timestamp (milliseconds) |
g | Content group (optional) |
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"
}
}
| Field | Description |
|---|---|
e | Event type |
v | Monetary value (optional — only present when amount is a number) |
x | Custom properties (optional) |
Microconversion Payload
Includes all pageview fields plus:
{
"e": "add_to_cart",
"m": true,
"x": {
"product_id": "SKU-123"
}
}
| Field | Description |
|---|---|
e | Event type |
m | Microconversion flag (true) |
x | Custom 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()popstateevent (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():
- sendBeacon (preferred): Works even when closing the tab
- 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:
| Property | Type | Description |
|---|---|---|
sealmetrics.sessionId | string | The fingerprint-based session ID for the current visitor |
sealmetrics.accountId | string | The account/site ID embedded in the served script |
sealmetrics.tz | string | The visitor's IANA timezone (e.g., 'Europe/Madrid') |
sealmetrics.autoMode | string | '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= value | Behavior |
|---|---|
missing / empty / 1 | Auto-pageview ON (default) |
0 | Auto-pageview OFF (manual mode) |
| any other value | Auto-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).
?auto=0If 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()andmicro()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 ID | Platform | Inferred source / medium |
|---|---|---|
gclid | Google Ads | google / cpc |
gbraid | Google Ads (iOS) | google / cpc |
wbraid | Google Ads (Web-to-App) | google / cpc |
fbclid | Meta / Facebook | facebook / social |
msclkid | Microsoft / Bing Ads | bing / cpc |
yclid | Yandex | yandex / cpc |
ttclid | TikTok | tiktok / cpc |
twclid | Twitter / X | twitter / cpc |
li_fat_id | linkedin / cpc | |
ScCid | Snapchat | snapchat / cpc |
rdt_cid | reddit / 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
| Specification | Value |
|---|---|
| Size (minified) | ~2,228 bytes |
| Size (gzipped) | ~1,227 bytes |
| Dependencies | None (vanilla JavaScript) |
| Browser Support | Chrome 60+, Firefox 55+, Safari 11.1+, Edge 79+ |
| ES Version | ES5 compatible |
| Cookies | None |
| localStorage | None |
| sessionStorage | None |
Related Documentation
- Installation - Setup guide
- Conversions - Detailed conversion tracking
- Microconversions - Event tracking
- SPA Support - Framework integrations