Summarize this documentation using AI
Overview
If you want Customer.io to reliably power cart recovery, repeat purchase, and reactivation, your SDK implementation has to do two things well: stitch identity correctly and send clean, decision-ready events. If you’re trying to map this into a real retention program (and avoid the usual “why didn’t this user enter the flow?” fire drills), book a strategy call and we’ll pressure-test your tracking plan against the campaigns you actually want to run.
Most D2C teams don’t fail because they “didn’t track enough.” They fail because they tracked the wrong moments, or they tracked them inconsistently across anonymous browsing, logged-in sessions, and post-purchase states—so segmentation and orchestration break the minute you scale spend or add channels.
How It Works
At a high level, the SDK’s job is to send two kinds of data into Customer.io: who the person is (identity + attributes) and what they did (events). Retention performance comes down to whether those events land on the right profile at the right time.
- Install the SDK in your mobile app (or web app if applicable) so you can send events directly from the client when key actions happen (viewed product, added to cart, started checkout, purchased, etc.).
- Create/update the person with stable identifiers and useful attributes (email, phone, customer_id, marketing opt-in flags, first_purchase_date, last_purchase_date). This is what segmentation runs on.
- Identify early, then re-identify when the ID becomes known. In practice, this is where most retention programs get messy: users browse anonymously, then log in or enter email at checkout. You want the anonymous activity to merge into the known profile so cart/browse flows don’t fragment.
- Track high-signal events with consistent schemas. Events trigger campaigns and populate conditional logic in Journeys. If your
add_to_cartevent sometimes sendsskuand sometimes sendsproduct_id, your dynamic content and branching will be brittle. - Customer.io builds profiles and timelines from your identify + event stream. Segments update as attributes/events change, and campaigns can trigger off those events in near real time.
Real D2C scenario: A shopper on iOS views two products, adds one to cart, then bounces. If you only identify after purchase, that cart event stays anonymous and your cart recovery never fires. If you identify when they submit email in checkout (or when they log in) and merge the anonymous activity, your cart recovery flow can send push within 30 minutes and email within 4 hours—using the exact SKU they abandoned.
Step-by-Step Setup
Before you touch code, decide what your retention program needs to do in the next 30–60 days (cart recovery, replenishment, winback). Then instrument only the events and attributes required to run those automations cleanly—otherwise you’ll ship noise and still miss the moments that matter.
- Create your Customer.io workspace and confirm your data model (what is your canonical user ID? do you treat email as an identifier or an attribute?).
- Install the Customer.io SDK (1.x) in your app using the platform guide (iOS/Android/React Native/Flutter/Expo). Do this in the app layer where you can reliably capture lifecycle events and user actions.
- Initialize the SDK at app start so it can queue events when offline and flush when connectivity returns. If initialization is delayed, you’ll lose early-session product discovery signals.
- Implement identity stitching:
- When the user is anonymous, allow the SDK to track anonymous activity (device-based).
- When you learn a stable identifier (login, email capture, account creation), call identify with your stable ID and set core attributes (email/phone, opt-in flags, locale, timezone if you have it).
- When a user logs out, reset/clear identity appropriately so the next user on the same device doesn’t inherit the previous profile’s events.
- Track retention-critical events with a strict schema. Start with:
product_viewed(product_id, sku, category, price, currency)add_to_cart(cart_id, product_id, sku, quantity, price)checkout_started(cart_id, cart_value, item_count)purchase_completed(order_id, revenue, currency, items[])
- Validate in Customer.io by checking a test user’s profile timeline: you should see identify updates and events in the right order, on the same person record.
- Build one “canary” campaign (e.g., cart recovery) to prove the loop end-to-end before instrumenting more events. In most retention programs, this catches 80% of tracking issues immediately.
When Should You Use This Feature
The SDK is the right tool whenever you need client-side truth: what the user did in the app, in the moment, tied to a real identity. That’s the foundation for retention automation that doesn’t rely on delayed server exports or brittle ETL.
- Cart recovery in mobile-first shopping where “add to cart” happens in-app and you want push/email/SMS triggered quickly with the exact items abandoned.
- Repeat purchase and replenishment when you need accurate purchase and product consumption signals to time reminders (e.g., 21–35 days after purchase for supplements, 45–60 for skincare).
- Reactivation when you want to detect “installed but inactive” or “browsed but didn’t purchase” cohorts and sequence offers/content without spamming recent buyers.
- Personalized product discovery where browse history should influence recommendations and category-based follow-ups (e.g., viewed running shoes twice → send education + social proof, not a generic promo).
Operational Considerations
Once the SDK is live, the work shifts from “can we send data?” to “can we trust it?” This is where segmentation, data flow, and orchestration realities determine whether you can scale beyond a couple of flows.
- Segmentation depends on stable identifiers: pick a canonical
customer_id(or equivalent) and stick to it. If you switch identifiers between app sessions, you’ll fragment profiles and undercount conversions. - Anonymous-to-known merge is non-negotiable: cart and browse flows often start anonymous. Make sure the moment you capture email/login, the prior activity attaches to the same person record you’ll message.
- Event naming and payload governance: treat event schemas like an API contract. Version changes break dynamic templates, conditional branches, and reporting.
- Source of truth for purchases: decide whether
purchase_completedis app-side, server-side, or both. Double-sending is common and will inflate revenue, trigger duplicate post-purchase flows, and corrupt holdouts. - Latency and ordering: mobile networks reorder/delay events. For journeys that depend on strict ordering (add_to_cart → checkout_started → purchase), add defensive logic (e.g., exit conditions on purchase, short delays before sending).
- Orchestration across channels: if push is app-side and email/SMS are profile-based, ensure consent attributes are updated before you trigger multi-channel sends—otherwise you’ll route users into a path they can’t receive.
Implementation Checklist
If you want this to survive real traffic (and not just your QA device), run this checklist before you declare the SDK “done.” It’s the difference between a flow that works in staging and one that drives incremental revenue.
- SDK installed and initialized on app start
- Single canonical user identifier defined and used consistently
identifycalled on login/account creation/email capture (not just after purchase)- Logout/reset behavior implemented to prevent cross-user contamination
- Core attributes set: email, phone (if used), timezone/locale, marketing consent flags
- Retention event set implemented: product_viewed, add_to_cart, checkout_started, purchase_completed
- Purchase event source-of-truth decided (and duplicates prevented)
- Test user timeline verified in Customer.io (events on the correct profile)
- One production campaign launched as an end-to-end validation (e.g., cart recovery)
Expert Implementation Tips
These are the small operator moves that prevent weeks of downstream pain when you start layering journeys, experiments, and personalization.
- Track “cart updated” not just “add to cart” if your cart is editable. Otherwise, your recovery message can show the wrong items or wrong quantities.
- Pass a stable
cart_idandorder_idso you can de-dupe and build clean exit criteria (e.g., exit cart flow if any event with order_id arrives). - Capture category affinity as an attribute derived from events (server-side or in your CDP) once it stabilizes. Segments built on “viewed category X 3+ times in 7 days” tend to outperform generic browse retargeting.
- Use short delays before first cart message (15–45 minutes) to absorb late purchase events and reduce “I already bought” complaints—especially on slower checkout flows.
- Instrument consent state changes as events (e.g.,
sms_opt_in,push_permission_granted) so you can trigger channel onboarding immediately and measure opt-in conversion.
Common Mistakes to Avoid
Most tracking issues don’t look like “no data.” They look like data that’s technically present but operationally unusable—wrong profile, wrong timing, wrong schema.
- Identifying too late (only after purchase). This strands high-value pre-purchase behavior on anonymous profiles and kills cart/browse recovery.
- Using email as the only identifier when users can change emails or use multiple addresses. If you have a true customer_id, use it.
- Double-sending purchases from both app and backend without de-duplication. This triggers duplicate post-purchase journeys and corrupts LTV reporting.
- Inconsistent event properties across platforms (iOS sends
productId, Android sendsproduct_id). Your templates and segments will silently fail. - Not handling logout/reset. Shared devices (tablets in-store, family iPads) will leak events into the wrong customer profile.
- Tracking everything, validating nothing. If you don’t verify a real user timeline end-to-end, you’ll discover issues only after a campaign underperforms.
Summary
If you want Customer.io to drive retention revenue, treat the SDK as your behavioral source of truth: install cleanly, identify early, and track a tight set of high-signal events with consistent schemas. Once identity stitching is solid, cart recovery and repeat purchase journeys become straightforward to orchestrate—and a lot easier to optimize.
Implement 1.x with Propel
If you’re already running Customer.io, the fastest path is usually: lock the identity plan, instrument the 4–6 events that power your core flows, then validate with one revenue-critical journey before expanding. If you want a second set of eyes on your SDK tracking and stitching (especially around anonymous merge and purchase de-dupe), book a strategy call—we’ll map your app events to the exact segments, exits, and messages your retention program needs.