Summarize this documentation using AI
Overview
If you’re running retention on Customer.io, the Track API is the workhorse that turns backend behavior (cart activity, purchases, subscription state) into triggers you can actually monetize. If you want a second set of eyes on event design and orchestration, you can book a strategy call—most issues we see are fixable once the data contract is tight.
In practice, Track succeeds or fails based on two things: (1) how consistently you identify people, and (2) whether your events are structured for segmentation and suppression (not just “we sent an event”).
How It Works
Track is a server-to-server (or trusted client-to-server) API that sends Customer.io two kinds of data: who a person is (identify) and what they did (track). Customer.io stores that data against a person profile, then you use it to build segments and trigger campaigns/workflows.
- Authentication: Track uses Basic Auth with your Site ID as the username and your API Key as the password. Most teams implement this in a backend service and rotate keys like any other credential.
- Core endpoints you’ll rely on:
- Identify a person to create/update attributes (email, phone, lifecycle flags, last_order_at, etc.).
- Track an event to record behavior (cart_updated, checkout_started, order_completed, subscription_canceled).
- Delete/suppress (less common day-to-day, but critical for privacy and deliverability hygiene).
- Data model reality: Customer.io keys everything off a customer_id (your stable internal ID). Email/phone should be attributes, not the primary identifier—otherwise merges and guest checkout edge cases get messy fast.
- Event payload structure: Events typically include a name plus a
dataobject. Thedataobject is what you’ll later filter on for segmentation and branching (e.g., cart_value, sku, category, discount_code, is_first_order).
A realistic D2C example: someone adds items to cart on mobile, then completes checkout on desktop. If both sessions identify to the same customer_id, your cart recovery flow can suppress correctly after purchase. If you identify by email sometimes and anonymous IDs other times, you’ll send “you forgot something” after they already bought—classic retention self-sabotage.
Step-by-Step Setup
Before you ship code, align internally on an event contract: names, required properties, and which system is the source of truth (Shopify, custom checkout, subscription platform). Then implement Track in a way that guarantees ordering and idempotency where it matters (especially around purchases).
- Pick the identifier strategy (don’t skip this).
Use a stable internalcustomer_id. If you support guest checkout, decide how/when you promote an anonymous session to a known customer and how you’ll reconcile histories. - Store Track credentials in your backend secrets manager.
Track uses Basic Auth (Site ID + API Key). Don’t embed keys in client apps unless you’re intentionally accepting that risk (most retention programs shouldn’t). - Implement Identify calls on “profile moments.”
Send Identify when a user creates an account, updates email/phone, opts into SMS, changes address, or when you compute derived fields (LTV, last_order_at, subscription_status). Make sure Identify is safe to call repeatedly. - Implement Track calls on “behavior moments.”
Standard retention events:product_viewed(includesku,category,price)cart_updated(includecart_id,cart_value,itemsarray)checkout_started(includecheckout_id,cart_value,shipping_country)order_completed(includeorder_id,revenue,items,is_first_order)
- Make purchase events idempotent.
Always send a stableorder_idand design your pipeline so retries don’t create duplicate “order_completed” events. Duplicate purchase events break post-purchase branching, replenishment timing, and LTV calculations. - Validate in code, not by eyeballing logs.
Add automated tests for required properties and types. In most retention programs, the bugs aren’t “API is down,” they’re “cart_value is a string in prod” and segmentation silently fails.
When Should You Use This Feature
Track is the right tool whenever retention decisions depend on real-time (or near real-time) behavior that your ecommerce platform doesn’t reliably expose via a native integration. It’s especially useful when you want tight suppression logic and clean branching in your workflows.
- Cart recovery with accurate suppression: Trigger on
checkout_startedorcart_updated, suppress iforder_completedarrives, and segment bycart_valueor category to personalize incentives. - Repeat purchase / replenishment: Use
order_completeditem data to start replenishment timers by SKU (e.g., 21 days for skincare serum, 45 days for supplements). - Reactivation: Track
site_visitorproduct_viewedfor lapsed customers and trigger a “still interested?” sequence only if they browse without purchasing. - Subscription risk and winback: Track
subscription_paused/subscription_canceledwith cancellation reasons, then branch messaging by reason (price vs. too much inventory vs. didn’t work).
Operational Considerations
Track implementations usually break not at the endpoint level, but in the messy middle: identity resolution, event ordering, and property consistency across services. Treat your event schema like a product—version it, review it, and keep it boring.
- Segmentation depends on property hygiene: If
categoryis sometimes “Skin Care” and sometimes “skincare,” you’ll build segments that miss revenue. Normalize enums server-side. - Event timing and orchestration: Cart recovery needs fast events; replenishment can tolerate delays. Don’t route everything through a batch ETL if you need a 30-minute abandon window.
- Source of truth conflicts: Orders might be created in Shopify, but refunds/cancellations might come from a different system. Decide which system emits
order_refundedand how that impacts suppression and LTV attributes. - Identity edge cases: Guest checkout + later account creation is where duplicate profiles come from. Plan a merge strategy around your internal
customer_idand only treat email as mutable metadata. - Backfill vs. real-time: If you backfill historical orders via Identify attributes (like
lifetime_orders), keep that separate from real-time Track events so you don’t accidentally trigger journeys on backfill.
Implementation Checklist
If you want Track to reliably drive revenue, ship the basics first (identity + purchase + cart), then expand. The checklist below is what we typically require before we trust downstream automation.
- Stable
customer_iddefined and used consistently across services - Basic Auth credentials stored and rotated securely
identifyimplemented for email/phone/consent and key derived attributes (last_order_at, subscription_status)order_completedevent includesorder_id,revenue,items, andis_first_order- Cart/checkout events include stable IDs (
cart_id/checkout_id) pluscart_valueanditems - Idempotency strategy for purchase events (dedupe by
order_id) - Property normalization (currency, category, SKU formats) enforced server-side
- Test events in staging and production with automated schema validation
- Documented mapping from events → segments → workflows (so changes don’t silently break automation)
Expert Implementation Tips
Once the basics are in, the biggest lift comes from sending the right properties so you can segment and suppress without hacks. Most teams under-send item-level data, then wonder why they can’t personalize without brittle Liquid logic.
- Always include an items array for cart and order events. At minimum:
sku,product_name,quantity,unit_price,category. This unlocks category-based abandon flows and post-purchase cross-sell without extra ETL. - Send consent as attributes, not events. For SMS/email compliance, keep
sms_opt_in=trueandemail_opt_in=trueon the profile so segments stay simple and auditable. - Use derived flags to simplify orchestration. Compute
is_vip,is_high_return_risk, orhas_active_subscriptionin your backend and send via Identify. It keeps workflow logic readable and reduces mistakes during iteration. - Design for suppression first. Every revenue flow should have an explicit “stop sending” condition powered by Track events (purchase, refund, cancellation). If you can’t suppress cleanly, you’ll burn list health and margin.
Common Mistakes to Avoid
The Track API itself is straightforward. The mistakes come from shipping “some events” without thinking through how those events behave under retries, edge cases, and multiple devices.
- Identifying users by email as the primary key. Email changes, guests don’t have it early, and you’ll end up with duplicate profiles and broken suppression.
- Missing stable IDs on key events. If
order_completeddoesn’t includeorder_id, you can’t dedupe—so retries inflate revenue and trigger the wrong journeys. - Inconsistent property types.
cart_valueas a string in one service and a number in another will quietly break filters and comparisons. - Backfill triggering live automation. If you replay historical purchases as Track events without guardrails, you’ll accidentally enroll half your customer base into post-purchase flows overnight.
- Over-instrumenting noisy events. Tracking every scroll/click creates volume without segmentation value. Prioritize events that map to revenue decisions.
Summary
If you need dependable cart recovery, repeat purchase timing, and reactivation triggers, Track is the cleanest way to get backend truth into Customer.io. Get identity right, make purchases idempotent, and treat event properties like segmentation infrastructure—not analytics exhaust.
Implement Track with Propel
If you’re already on Customer.io, the fastest wins usually come from tightening the event contract and suppression logic before you scale sends. If you want help pressure-testing your schema against real retention use cases (abandon, replenishment, winback), you can book a strategy call and we’ll walk through what to send, where it tends to break, and how to keep workflows stable as you iterate.