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

EventRequired properties
page_viewnone
view_productproduct_id, price, currency
add_to_cartproduct_id, price, currency, quantity
remove_from_cartproduct_id, price, currency, quantity
begin_checkoutcart_value, currency
purchaseorder_id, revenue, currency (+ items[])
refundorder_id, revenue, currency
identifydistinct_id (call riq.identify)
checkout_errorstep, field, message (all optional)
coupon_rejectedcode
payment_failedmethod, reason (optional)
out_of_stock_viewproduct_id
variant_unavailableproduct_id, variant
search_no_resultsquery
shipping_cost_viewedamount, currency
size_guide_openedproduct_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.