e-commerce event spec
The TracerKit data layer
A standardized, typed event schema. Push events onto window.tracerkitLayer and TracerKit consumes them for purchase and custom triggers, verification, and server-side forwarding to ad platforms. One implementation, every destination.
<script> window.tracerkitLayer = window.tracerkitLayer || []; </script>
- window.tracerkitLayer is a plain array with GTM-dataLayer-compatible push semantics. Initialize it with window.tracerkitLayer = window.tracerkitLayer || [] — order relative to the TracerKit snippet doesn't matter: pushes made before the loader boots are drained on boot; later pushes are processed as they happen.
- Push events at the moment they happen, on the page where they happen. In SPAs, push after the route settles.
- Numbers are JSON numbers. "129.97", "$129.97", and "1.299,97" are all invalid — value and price are decimals, quantity is an integer.
- currency is an uppercase ISO 4217 code and is required whenever value is present.
- Push purchase exactly once per order. TracerKit dedupes on order_id, but ad platforms are less forgiving — don't re-push on confirmation-page reloads.
- Unknown extra fields are ignored, so you can share one push with an existing GTM dataLayer implementation.
The shared Item shape used by every commerce event:
type Item = {
id: string; // SKU or product ID — stable across events
name: string;
price: number; // unit price, decimal
quantity: number; // integer ≥ 1
};the events
Five events, one funnel
Implement all five for a complete funnel; purchase alone is the minimum for revenue verification.
| Field | Type | Required | Notes |
|---|---|---|---|
| event | string | yes | Always "page_view". |
| page_location | string | no | Full URL. Defaults to location.href when omitted. |
| page_title | string | no | Defaults to document.title when omitted. |
<script>
window.tracerkitLayer = window.tracerkitLayer || [];
window.tracerkitLayer.push({
event: "page_view"
});
</script>| Field | Type | Required | Notes |
|---|---|---|---|
| event | string | yes | Always "view_item". |
| items | Item[] | yes | The product being viewed — usually a single item. |
| value | number | no | Price of the viewed item. |
| currency | string | no | ISO 4217 code, uppercase (USD, EUR, GBP…). Required whenever value is present. |
| items[].id | string | yes | SKU or product ID. Keep it stable across events so the funnel joins up. |
| items[].name | string | yes | Human-readable product name. |
| items[].price | number | yes | Unit price as a decimal number — no currency symbols, never a string. |
| items[].quantity | number | yes | Integer ≥ 1. |
<script>
window.tracerkitLayer = window.tracerkitLayer || [];
window.tracerkitLayer.push({
event: "view_item",
value: 39.99,
currency: "USD",
items: [{ id: "SKU-123", name: "Canvas Tote", price: 39.99, quantity: 1 }]
});
</script>| Field | Type | Required | Notes |
|---|---|---|---|
| event | string | yes | Always "add_to_cart". |
| items | Item[] | yes | The items just added; quantity is the amount added, not the cart total. |
| value | number | no | Value of the items added (price × quantity). |
| currency | string | no | ISO 4217 code, uppercase (USD, EUR, GBP…). Required whenever value is present. |
| items[].id | string | yes | SKU or product ID. Keep it stable across events so the funnel joins up. |
| items[].name | string | yes | Human-readable product name. |
| items[].price | number | yes | Unit price as a decimal number — no currency symbols, never a string. |
| items[].quantity | number | yes | Integer ≥ 1. |
<script>
window.tracerkitLayer = window.tracerkitLayer || [];
window.tracerkitLayer.push({
event: "add_to_cart",
value: 79.98,
currency: "USD",
items: [{ id: "SKU-123", name: "Canvas Tote", price: 39.99, quantity: 2 }]
});
</script>| Field | Type | Required | Notes |
|---|---|---|---|
| event | string | yes | Always "begin_checkout". |
| items | Item[] | yes | The full cart at checkout start. |
| value | number | no | Cart total at checkout start. |
| currency | string | no | ISO 4217 code, uppercase (USD, EUR, GBP…). Required whenever value is present. |
| items[].id | string | yes | SKU or product ID. Keep it stable across events so the funnel joins up. |
| items[].name | string | yes | Human-readable product name. |
| items[].price | number | yes | Unit price as a decimal number — no currency symbols, never a string. |
| items[].quantity | number | yes | Integer ≥ 1. |
<script>
window.tracerkitLayer = window.tracerkitLayer || [];
window.tracerkitLayer.push({
event: "begin_checkout",
value: 129.97,
currency: "USD",
items: [
{ id: "SKU-123", name: "Canvas Tote", price: 39.99, quantity: 2 },
{ id: "SKU-456", name: "Wool Beanie", price: 49.99, quantity: 1 }
]
});
</script>| Field | Type | Required | Notes |
|---|---|---|---|
| event | string | yes | Always "purchase". |
| order_id | string | yes | Unique per order — the dedup key. Never reuse across orders. |
| value | number | yes | Order total as a decimal number — never a string, no symbols or separators. |
| currency | string | yes | ISO 4217 code, uppercase (USD, EUR, GBP…). |
| items | Item[] | yes | Every line item in the order. |
| items[].id | string | yes | SKU or product ID. Keep it stable across events so the funnel joins up. |
| items[].name | string | yes | Human-readable product name. |
| items[].price | number | yes | Unit price as a decimal number — no currency symbols, never a string. |
| items[].quantity | number | yes | Integer ≥ 1. |
| string | no | OPTIONAL — enhanced matching only. Hashed in-browser (SHA-256) before use; the raw address never leaves the page. | |
| phone | string | no | OPTIONAL — enhanced matching only. E.164 format recommended (+15551234567). Hashed in-browser (SHA-256) before use. |
<script>
window.tracerkitLayer = window.tracerkitLayer || [];
window.tracerkitLayer.push({
event: "purchase",
order_id: "1001",
value: 129.97,
currency: "USD",
items: [
{ id: "SKU-123", name: "Canvas Tote", price: 39.99, quantity: 2 },
{ id: "SKU-456", name: "Wool Beanie", price: 49.99, quantity: 1 }
],
email: "jane@example.com", // optional — hashed in-browser
phone: "+15551234567" // optional — hashed in-browser
});
</script>email and phone on purchaseare optional. When provided they are consumed for enhanced matching only: hashed in-browser with SHA-256 before any transmission — the raw values never leave the page and never transit TracerKit's servers.
Provide them only under a consent state that permits marketing use.
Event names
| TracerKit event | Meta CAPI | GA4 | TikTok |
|---|---|---|---|
| page_view | PageView | page_view | Pageview |
| view_item | ViewContent | view_item | ViewContent |
| add_to_cart | AddToCart | add_to_cart | AddToCart |
| begin_checkout | InitiateCheckout | begin_checkout | InitiateCheckout |
| purchase | Purchase | purchase | CompletePayment |
Fields (purchase)
| TracerKit field | Meta CAPI | GA4 | TikTok |
|---|---|---|---|
| value | custom_data.value | params.value | properties.value |
| currency | custom_data.currency | params.currency | properties.currency |
| order_id | custom_data.order_id (dedup basis) | params.transaction_id | properties.order_id |
| items[].id | custom_data.contents[].id | items[].item_id | properties.contents[].content_id |
| items[].name | custom_data.content_name | items[].item_name | properties.contents[].content_name |
| items[].price | custom_data.contents[].item_price | items[].price | properties.contents[].price |
| items[].quantity | custom_data.contents[].quantity | items[].quantity | properties.contents[].quantity |
| email (hashed) | user_data.em | user_data.sha256_email_address | user.email |
| phone (hashed) | user_data.ph | user_data.sha256_phone_number | user.phone |
Prefer typed calls over hand-written pushes? The JS/React SDK (@tracerkit/js, @tracerkit/react) wraps this spec field-for-field — pushEvent, pushPurchase, identify, consent, with autocomplete.
Agents can read this spec as markdown at /docs/data-layer.md. The data layer is consumed by the TracerKit loader — install it first.