Track Events with the Customer.io SDK (Retention-Grade Setup)

Customer.io partner logo

Table of Contents

Summarize this documentation using AI

This banner was added using fs-inject

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Overview

If you want Customer.io to drive real retention outcomes (cart recovery, replenishment, winback), you need clean, app-side events—not “best effort” analytics that breaks identity the moment someone logs in. Customer.io events are the behavioral backbone that decides who enters a flow, what message they see, and when they exit. If you’re running Customer.io and want an operator’s setup that holds up under real traffic, you can also book a strategy call to pressure-test your tracking plan before you scale spend and sends.

In most retention programs, the difference between “nice dashboards” and “revenue” is whether your SDK events are (1) consistently named, (2) tied to the right user identity, and (3) emitted at the right moment in the app.

How It Works

Customer.io’s SDK tracking is straightforward on paper: your app identifies a person, then sends events (with properties) as users browse, add to cart, and purchase. In practice, the mechanics that matter for retention are identity stitching and event timing—because that’s what determines whether the right person gets the right recovery or repeat-purchase message.

  • Identify first, then track. Your app calls an identify method with a stable customer identifier (your user ID). That’s what Customer.io uses to attach events and attributes to a single profile over time.
  • Track events with properties. Each meaningful action becomes an event name (e.g., product_viewed, added_to_cart, checkout_started, order_completed) plus properties (SKU, category, price, cart_value, currency, etc.). Properties are what make segmentation and personalization actually useful.
  • Anonymous-to-known stitching. Many shoppers browse anonymously, then log in or enter email at checkout. Your SDK needs to handle that transition so pre-login events don’t get stranded on an anonymous profile. If you don’t stitch, your “cart abandonment” flow quietly underperforms because the cart event happened before the user was identified.
  • Event triggers drive orchestration. In Customer.io, campaigns typically trigger off a specific event (“Added to Cart”) and then use follow-up conditions (“No Purchase in 2 hours”) to decide next steps. Bad tracking turns into wrong entries, duplicate entries, or missed exits.

Real D2C scenario: A shopper on iOS views a moisturizer, adds it to cart, gets distracted, then completes checkout later on desktop. If your SDK identifies the user only after purchase, your cart recovery never fires (or worse, fires after they bought). If you identify at email capture/login and stitch anonymous activity, Customer.io can suppress recovery the moment order_completed lands—protecting deliverability and margin.

Step-by-Step Setup

Before you write any code, align on the event plan and identity rules. The fastest way to create retention chaos is to “just start tracking” and then retrofit naming, dedupe, and stitching after workflows are live.

  1. Define your identity strategy.
    Pick a single, stable customer_id (your internal user ID) as the primary identifier. Decide when you’ll have it (account creation, login, email capture, checkout). Document what happens for guest checkout.
  2. Install the Customer.io SDK in your app.
    Add the appropriate SDK for your platform (iOS/Android/React Native/Flutter/etc.) and confirm the environment keys (dev vs prod). Don’t skip this: many teams accidentally send production events from staging builds.
  3. Initialize the SDK as early as possible.
    Initialize on app start so you don’t miss early funnel events like app_opened or product_viewed. Missing early events makes “discovery → cart → purchase” attribution messy inside Customer.io.
  4. Call identify immediately when you know who the user is.
    Trigger identify at login, account creation, and any point you capture email/phone in-app. Include key attributes you’ll segment on (email, phone, acquisition_source, first_order_date if known, etc.).
  5. Track high-signal commerce events with clean properties.
    Start with a minimal set that powers retention:
    • product_viewed: sku, product_name, category, price
    • added_to_cart: sku, quantity, cart_value, currency
    • checkout_started: cart_value, items (array if you support JSON), shipping_country
    • order_completed: order_id, revenue, discount, items, is_first_order
  6. Handle anonymous activity and merge it on identify.
    If your app supports anonymous browsing, ensure the SDK captures anonymous events and then merges them into the identified profile when the user logs in or submits email. This is where cart recovery wins are usually hiding.
  7. QA with real journeys, not just logs.
    Run a test: view product → add to cart → wait → purchase. Confirm (a) you enter the cart flow, (b) you exit on purchase, and (c) personalization renders correctly from event properties.

When Should You Use This Feature

SDK event tracking is the right move when retention depends on real-time, in-app behavior and you can’t afford delays or gaps from server-side batch jobs. Most D2C brands get the biggest lift when they use SDK events to tighten the “intent window” and stop messaging people who already converted.

  • Cart recovery with accurate suppression. Trigger off added_to_cart and suppress on order_completed—but only works if identity is stitched across sessions and devices.
  • Browse-to-buy follow-ups. If someone views the same category multiple times (e.g., “running socks”), SDK events let you build intent segments and send the right product discovery message without waiting for nightly syncs.
  • Replenishment and repeat purchase. Track order_completed with item-level properties so you can time replenishment off the SKU they actually bought, not a generic “last order date.”
  • Reactivation based on real engagement. Use app_opened or session_started to separate “email inactive” from “brand inactive.” That distinction prevents you from discounting people who are still browsing.

Operational Considerations

Event tracking is rarely the hard part—keeping it reliable through app releases, identity edge cases, and workflow complexity is. If you want Customer.io automations to stay stable, treat tracking like production infrastructure.

  • Segmentation depends on property consistency. Pick one schema for money fields (cart_value vs value, cents vs dollars) and never deviate. In practice, this tends to break when different engineers ship events from different screens.
  • Data flow: decide SDK vs server source of truth. Purchases often come from server/webhooks (more reliable), while browse/cart intent is best from the SDK (more immediate). Make sure you don’t double-send order_completed from both places unless you have a dedupe key like order_id.
  • Identity stitching is your retention multiplier. If you run guest checkout, decide how you’ll map email/phone capture to an existing profile. Without a plan, you’ll create duplicates and your frequency controls won’t work.
  • Orchestration reality: exits and suppression must be event-driven. Your cart flow should exit on order_completed. Your winback should exit on app_opened or product_viewed. That only works when those events fire reliably.
  • Release management. Version your tracking plan. When mobile ships a new build, re-QA the top 5 revenue flows (cart, browse, purchase, replenishment, winback) before rollout hits 100% of users.

Implementation Checklist

If you want a setup that’s easy to operate month after month, get the basics locked before you build your first “serious” recovery flow.

  • Stable primary identifier chosen (internal user ID) and documented
  • SDK installed in the correct app targets (prod vs staging separated)
  • identify called on login/account creation/email capture
  • Anonymous events captured and merged on identify (no stranded carts)
  • Core event set implemented: product_viewed, added_to_cart, checkout_started, order_completed
  • Event properties standardized (currency, value units, SKU naming)
  • Dedupe strategy for purchases (e.g., order_id)
  • QA: enter/exit logic validated in Customer.io with test profiles

Expert Implementation Tips

Most retention lift comes from a few unsexy details: when you identify, what you store on the event, and how you prevent duplicates. Nail those and your automations behave.

  • Identify earlier than you think. Add an email capture step (wishlist, back-in-stock, “save your cart”) and identify there. That’s how you recover carts that would otherwise stay anonymous.
  • Use item arrays for personalization. If your implementation supports JSON, pass an items array on cart/checkout/order events. It makes “Your cart is waiting” messages dramatically more relevant without extra data plumbing.
  • Send monetary values in a single format. Pick cents (integers) or dollars (decimals) and stick to it. Mixing formats is how you end up segmenting “cart_value > 100” and accidentally targeting half your buyers.
  • Prefer server truth for purchase; SDK for intent. Let the SDK drive added_to_cart and checkout_started. Confirm order_completed from your backend to avoid false positives from payment failures.
  • Build suppression segments as you implement. Create segments like “Purchased in last 24h” and “In cart recovery” early. They become your guardrails when you add more flows later.

Common Mistakes to Avoid

These are the mistakes that quietly burn revenue: they don’t crash anything, they just make your targeting wrong and your reporting untrustworthy.

  • Tracking events before identify with no merge plan. You’ll lose the highest-intent behavior (browse/cart) right before conversion.
  • Using email as the primary identifier. Emails change, get aliased, and create duplicates. Use a stable internal ID and store email as an attribute.
  • Double-sending purchases. If both SDK and backend send order_completed, you’ll trigger duplicate post-purchase and replenishment flows unless you dedupe by order_id.
  • Inconsistent naming. Added To Cart vs added_to_cart becomes two different triggers. Decide a naming convention (snake_case is common) and enforce it.
  • Forgetting exit criteria. Cart recovery without a purchase exit is how you end up emailing discounts to people who already bought.

Summary

If you want Customer.io to reliably drive retention, treat SDK event tracking like a production system: identify early, stitch anonymous behavior, and standardize event properties. Once those fundamentals are in place, cart recovery and repeat purchase flows become predictable—and easier to optimize.

Implement Track Events with Propel

If you’re already running Customer.io, the fastest path is usually: lock the identity rules, implement a minimal high-signal event set, then QA against your top revenue workflows (cart, post-purchase, replenishment, winback). If you want a second set of eyes on your SDK plan—especially anonymous-to-known stitching and purchase dedupe—you can book a strategy call and we’ll walk through what tends to break before it breaks in production.

Contact us

Get in touch

Our friendly team is always here to chat.

Here’s what we’ll dig into:

Where your lifecycle flows are underperforming and the revenue you’re missing

How AI-driven personalisation can move the needle on retention and LTV

Quick wins your team can action this quarter

Whether Propel AI is the right fit for your brand, stage, and stack