Summarize this documentation using AI
Overview
If your retention automations feel “random” (some users enter cart recovery, others don’t), it’s almost always a tracking and identity problem—not a copy problem. This guide translates Customer.io troubleshooting into the checks that actually protect repeat purchase, cart recovery, and reactivation performance—and if you want a second set of eyes on your data flow, you can book a strategy call.
In most retention programs we’ve seen, the break happens in one of three places: the app never sends the event, the event lands on the wrong profile (identity stitching), or the event arrives but can’t be used the way the workflow expects (wrong name, wrong properties, wrong timing).
How It Works
Customer.io’s SDKs (mobile and web) are basically your “source of truth pipe” into People profiles and Events. When tracking is healthy, a user’s device activity resolves to a single person, events arrive with consistent names/properties, and Journeys can trigger immediately and segment membership updates predictably.
- Identify is the anchor. The SDK starts with an anonymous device/profile. The moment you call
identifywith your stable customer identifier (email, customer_id, or your internal user id), Customer.io can stitch that activity to the right person going forward. - Events are what drive retention automation. Your cart recovery flow might key off
Added to CartandCheckout Started, while repeat purchase might rely onOrder Completedplus product/category properties. - Stitching determines whether triggers fire. If the user adds to cart anonymously and you only identify after purchase/login, you can end up with “ghost carts” that never enter abandonment because the cart events live on an anonymous profile.
- Timing matters more than teams expect. If your app queues events offline or batches them late, a “send 30 minutes after abandon” journey can misfire because the event lands hours later.
Step-by-Step Setup
When a workflow isn’t triggering, don’t start by rewriting the journey. Start by proving the SDK is sending the right calls, in the right order, tied to the right identity. This sequence is the fastest way to isolate the break.
- Confirm you’re using one stable identifier everywhere.
Pick a canonical ID strategy (e.g.,customer_idas the primary, email as an attribute). Make sure the SDKidentifyuses the same value your backend uses (and the same value you import customers with, if applicable). - Verify the identify call happens early enough.
On web: callidentifyimmediately after login/account creation (and ideally right after email capture if you support account-less checkout). On mobile: call it after auth state is known (app open + token refresh), not “sometime later.” - Reproduce the issue with a single test user.
Use a real flow: add an item to cart, start checkout, abandon, return, purchase. Keep it simple—one SKU, one device, one browser/app install. - Check the person profile in Customer.io.
Look for: multiple profiles for the same human, missing device association, or events landing on an anonymous profile instead of the identified person. - Inspect the event payload shape.
Confirm the event name matches exactly what the Journey listens for (case, spaces, underscores). Confirm required properties exist (e.g.,cart_value,sku,currency,order_id). - Validate event timing.
Compare the timestamp you expect (when you tapped “Add to cart”) to when the event appears in Customer.io. If it’s delayed, your “wait until” and abandonment windows may need to account for batching/offline behavior. - Confirm subscription and channel readiness (only after data is right).
If events and identity are correct but messages still don’t send, then check suppression/unsubscribed status, push token registration, and channel configuration.
When Should You Use This Feature
Troubleshooting isn’t a one-off task—SDK tracking drifts over time as apps ship changes, analytics refactors happen, and checkout flows evolve. The highest leverage is running these checks right before you scale spend or launch a new retention program.
- Cart abandonment is underperforming. You’re getting traffic, but the abandonment audience is suspiciously small—or recovery messages go out to people who already purchased.
- Repeat purchase journeys feel inconsistent. Some customers get replenishment reminders, others never qualify because
Order Completeddoesn’t consistently include SKU/category or lands on a different profile. - Reactivation is missing “lapsed” customers. Your “no purchase in 90 days” segment doesn’t match finance numbers because purchase events aren’t consistently tied to the same identity across devices.
- You launched a new checkout or auth flow. Any change to login, guest checkout, or payment steps is a prime time for identify/event order to break.
Operational Considerations
In practice, tracking issues show up as segmentation problems and orchestration chaos: customers qualify for the wrong branch, exit conditions don’t work, and frequency controls can’t protect you. Treat SDK troubleshooting like a data contract between product and retention.
- Segmentation depends on deterministic event names and properties. If one app version sends
order_completedand another sendsOrder Completed, your “purchasers in last 30 days” segment will be wrong—and your winback will spam recent buyers. - Identity stitching needs a clear policy for anonymous activity. Decide whether you must merge anonymous cart activity into the identified profile. If you rely on cart recovery, you usually do—otherwise your highest-intent events never reach the person who can be messaged.
- Data flow latency changes journey logic. If mobile sends events late (offline queue), avoid tight windows like “send 15 minutes after abandon” unless you’ve measured delivery delay. Consider using “wait until purchase” exit conditions plus a longer buffer.
- Orchestration requires consistent purchase truth. If your backend also sends purchase events (common for accuracy), prevent duplicates by choosing one source of truth or deduping with
order_idas an idempotency key in your event design.
Implementation Checklist
Before you blame creative or offer strategy, run this checklist. It’s the quickest way to get back to reliable triggers and clean audiences.
- SDK installed and initialized once per app/session (no double-init)
identifycalled with a stable, consistent customer identifier- Anonymous-to-known stitching strategy defined (and tested with cart events)
- Event names standardized (exact casing/spelling) and documented
- Required event properties present for key programs (cart, checkout, purchase, product)
- Purchase events include
order_idfor dedupe and attribution - Event timestamps and arrival latency measured (especially mobile offline)
- Test user run-through validated in the Customer.io profile (events on the right person)
Expert Implementation Tips
These are the moves that keep retention stable when your app and site keep changing. They’re not fancy, but they prevent the “why did revenue drop?” fire drills.
- Track a single “source of truth” purchase event. If you can, send
Order Completedfrom the backend (webhook/server) for accuracy, and use the SDK for pre-purchase intent (viewed product, add to cart). Then dedupe withorder_id. - Make cart events stitchable. If you support guest checkout, capture email early and call
identifyas soon as you have it. That one change often doubles the reachable cart abandonment audience. - Version your event contract. Add an
app_versionproperty to SDK events. When a segment suddenly shrinks, you can quickly see if a specific release broke tracking. - Design properties around segmentation, not analytics vanity. For repeat purchase,
sku,product_type,subscription, andpurchase_countare usually more actionable than a giant nested payload no one uses in Journeys.
Common Mistakes to Avoid
Most teams don’t “miss” tracking entirely—they ship something that works for analytics dashboards but breaks retention triggers and identity resolution.
- Calling identify too late. If identify only happens after purchase, your abandonment and browse flows will always be under-attributed to real people.
- Letting event names drift across platforms. iOS sends
AddedToCart, web sendsAdded to Cart, Android sendsadd_to_cart. Now you’re maintaining three journeys or, worse, missing two-thirds of intent. - Not passing dedupe keys for purchases. Without
order_id, duplicate purchase events can prematurely exit journeys, inflate LTV reporting, and suppress customers from offers they should receive. - Debugging only in the journey. If you don’t confirm the person profile has the event, you’ll waste hours tweaking filters and delays when the real issue is upstream.
- Ignoring latency on mobile. Offline queues can turn “abandoned cart” into “post-purchase nag” unless your exit conditions and delays are designed for late-arriving events.
Summary
If your retention flows aren’t firing, treat it like a data integrity issue first: identity, event naming, properties, and timing. Once the SDK pipeline is clean, segmentation and orchestration become predictable—and your cart recovery, repeat purchase, and winback programs stop leaking revenue.
Implement Troubleshooting with Propel
When teams want this handled end-to-end, we usually start by mapping your SDK identify + event contract to the Journeys that drive revenue, then we validate it with a real cart-to-purchase run-through inside Customer.io. If you want help pressure-testing identity stitching, event latency, and dedupe so your automations trigger reliably, you can book a strategy call.