Install RecartIQ
Five minutes on any platform. Page views, sessions, devices and UTM attribution are automatic; commerce events need the calls below (or the Shopify connector, coming soon).
1. Add the snippet
<script async src="https://cdn.recartiq.com/r.js" data-key="pk_live_…"></script>
- Shopify: Online Store → Themes → Edit code → layout/theme.liquid, before
</head>. Product pages are detected automatically (view_product and out-of-stock). - WooCommerce: Appearance → Theme File Editor → header.php, or any "insert headers" plugin. Product pages are detected automatically.
- Everything else: the global header template. Works on any HTML page; single-page apps get a page_view on every route change.
Options: data-spa="false", data-autocapture="false", data-respect-dnt="false".
2. Send commerce events
riq.track("view_product", { product_id: "SKU-1", name: "Trail Jacket", category: "Outerwear", price: 129, currency: "USD" });
riq.track("add_to_cart", { product_id: "SKU-1", price: 129, currency: "USD", quantity: 1, cart_value: 129 });
riq.track("begin_checkout", { cart_value: 129, currency: "USD" });
riq.track("purchase", { order_id: "1001", revenue: 137.9, currency: "USD", shipping: 8.9,
items: [{ product_id: "SKU-1", price: 129, quantity: 1 }] });
riq.identify("customer-123", { email: "c@example.com" });No JavaScript? Annotate a button and the click is tracked:
<button data-riq-event="add_to_cart" data-riq-product-id="SKU-1" data-riq-price="129" data-riq-currency="USD">Add to cart</button>
3. Friction events (why shoppers leave)
Out-of-stock views, checkout and coupon errors, empty searches and size-guide opens are auto-captured on common themes. Send the rest where they happen:
riq.track("shipping_cost_viewed", { amount: 8.9, currency: "USD", cart_value: 129 });
riq.track("coupon_rejected", { code: "FALL10", reason: "expired" });
riq.track("payment_failed", { method: "card", reason: "declined" });Event reference
| Event | Required properties |
|---|---|
page_view | none |
view_product | product_id, price, currency |
add_to_cart | product_id, price, currency, quantity |
remove_from_cart | product_id, price, currency, quantity |
begin_checkout | cart_value, currency |
purchase | order_id, revenue, currency (+ items[]) |
refund | order_id, revenue, currency |
identify | distinct_id (call riq.identify) |
checkout_error | step, field, message (all optional) |
coupon_rejected | code |
payment_failed | method, reason (optional) |
out_of_stock_view | product_id |
variant_unavailable | product_id, variant |
search_no_results | query |
shipping_cost_viewed | amount, currency |
size_guide_opened | product_id |
Custom events: any name matching ^[a-z][a-z0-9_]*$ with free-form properties. Keys named password, card_number or cvv are dropped on arrival.
Server-side (HTTP API)
POST https://cdn.recartiq.com/api/v1/track
Authorization: Bearer pk_live_…
Content-Type: application/json
{ "batch": [
{ "event": "purchase", "insert_id": "<uuid>", "timestamp": "2026-09-11T10:12:03Z",
"distinct_id": "customer-123",
"properties": { "order_id": "1001", "revenue": 137.9, "currency": "USD" } }
] }Up to 100 events per request. Always send insert_id and timestamp so retries deduplicate. Timestamps older than 7 days are clamped.
Privacy
The snippet respects Do Not Track and Global Privacy Control by default, sets first-party cookies only, and never sends IP addresses or raw user agents to storage. Delete a customer's data with DELETE /api/v1/persons/:distinct_id or from Settings → Data.