Summarize this documentation using AI
Overview
If you’re using Customer.io for retention, SDK package choices and config flags aren’t “engineering details” — they decide whether your cart recovery and repeat purchase journeys trigger on time, on the right user, with the right context. If you want a second set of eyes on your tracking plan before you ship (or before you migrate SDKs), book a strategy call and we’ll pressure-test identity stitching and event reliability.
In most retention programs, the biggest lift comes from getting three things consistently right: (1) the right package installed (so events actually send), (2) identity handled cleanly (so anonymous browsing becomes an identified customer), and (3) configuration aligned to how your app behaves in the real world (offline mode, backgrounding, ATT consent, etc.).
How It Works
Customer.io’s SDK “packages” are essentially the building blocks that determine what your app can track and how it communicates with Customer.io. Your configuration options then control behavior like batching, flushing, logging, and how the SDK treats anonymous vs identified users — which is the difference between a clean abandoned cart flow and a mess of duplicate profiles.
- Install the right SDK modules for your channels and data needs. Mobile/web SDKs typically separate core analytics/event capture from messaging-specific capabilities. If you plan to use push or in-app, your package selection needs to reflect that from day one.
- Initialize early, but identify at the right time. You generally initialize the SDK on app start so you capture sessions and pre-login behavior. You then call
identifyonly when you have a stable user identifier (login, account creation, or verified email capture), so browsing and cart events can be stitched to the eventual customer profile. - Track events with the properties your journeys actually need. The SDK will happily accept bare events like
Added to Cart, but retention performance comes from properties: SKU, product name, price, quantity, category, cart value, currency, and (critically) a cart/session identifier for deduping. - Configuration controls delivery guarantees. Batch size, flush interval, retry behavior, and offline queueing determine whether a “Checkout Started” event arrives in time to suppress an abandonment message. In practice, this tends to break when teams rely on default flush timing and the user closes the app right after tapping checkout.
Step-by-Step Setup
The goal here isn’t “SDK installed.” The goal is “events arrive quickly, identities merge cleanly, and downstream campaigns don’t misfire.” Use this sequence so you don’t end up reworking tracking after your first cart recovery launch.
- Choose packages based on your retention roadmap.
Confirm whether you need: core event tracking only, or event tracking + push + in-app. Make this decision with your channel plan in mind (e.g., cart recovery via push + email, winback via push). - Install the SDK packages in your app.
Add the relevant Customer.io SDK dependencies for your platform (iOS/Android/React Native/Flutter/Web). Keep versions aligned across platforms if you’re measuring cross-platform behavior. - Initialize the SDK at app start with environment-specific config.
Set credentials for the correct workspace/environment (dev vs prod). Turn on verbose logging in non-prod so you can validate identify + track calls without guessing. - Implement identity correctly: anonymous first, identify when stable.
- On app open: let the SDK create/maintain an anonymous user context so you can capture product views and cart building.
- On login/account creation: call
identify(userId)and include key attributes (email, phone if you have consent, first order date if known, acquisition source if you store it). - On logout: call the SDK’s reset/clear method so the next user doesn’t inherit the previous user’s device identity.
- Track the “money events” with retention-grade properties.
At minimum for D2C retention:Product Viewed(sku, product_id, name, category, price, currency)Added to Cart(sku/product_id, quantity, price, cart_id, cart_value)Checkout Started(cart_id, cart_value, items_count, payment_method if available)Order Completed(order_id, cart_id, revenue, currency, items, discount_code)
- Configure flush/batching so events arrive before your automations fire.
Tune flush behavior to your app UX. If users commonly background the app right after checkout, force a flush on key moments (checkout start, order complete) so suppression logic works. - Validate in Customer.io Activity Logs before you build journeys.
Pick a test device, run a full funnel (view → add → checkout → purchase), and confirm: event names, property keys, timestamps, and that the identified profile contains the anonymous pre-login events.
When Should You Use This Feature
Package selection and configuration options matter most when you’re relying on app-side behavior to drive retention — not just server-side order events. If your brand has meaningful mobile traffic, this is where a lot of incremental revenue hides.
- Cart recovery that actually suppresses on purchase. Example: a shopper adds a bundle to cart in-app, starts checkout, then completes purchase via Apple Pay. If your SDK doesn’t flush quickly, Customer.io may not receive
Order Completedin time and your “You left something behind” push fires anyway. - Product discovery loops based on real browsing. If you want “Back in stock” or “Still thinking about X?” flows, you need consistent
Product Viewedevents and stable product identifiers across app versions. - Reactivation based on app inactivity, not just email opens. App session tracking + last_seen/last_activity attributes are the backbone of winback segmentation that doesn’t over-message active buyers.
- Cross-device identity stitching. When a customer browses anonymously on mobile, then logs in later, SDK identity handling determines whether those anonymous events attach to the right profile (and whether your recommendations are relevant).
Operational Considerations
This is where retention programs usually get messy: the SDK is “working,” but segmentation and orchestration don’t behave because data arrives late, identities duplicate, or events don’t mean what marketing thinks they mean.
- Segmentation depends on stable naming and schemas. Lock event names and property keys early (snake_case vs camelCase,
product_idvssku). If you change them midstream, you’ll silently break segments like “Viewed category = skincare in last 7 days.” - Data flow timing impacts suppression and frequency controls. If purchases are tracked server-side but carts are tracked client-side, you can get race conditions. Align flush behavior and/or add short delays in journeys so the purchase event has time to arrive before an abandonment message.
- Anonymous → identified merging is the difference between personalization and spam. Make sure your identify call happens once you have a real user ID, and that logout resets identity. Otherwise, households sharing a tablet will contaminate each other’s profiles and trigger the wrong reactivation offers.
- Orchestration reality: not every event should trigger a message. Use SDK events to build intent signals, then gate with conditions (e.g., only send cart recovery if
cart_value> $40 and noOrder Completedfor thatcart_id).
Implementation Checklist
Before you tell the team “tracking is done,” run through this list. It catches the exact issues that lead to misfiring cart recovery and broken winback segments.
- SDK packages installed for the channels you plan to use (core + push/in-app as needed)
- Dev/prod environments separated (credentials, logging, endpoints)
identifycalled only when user ID is stable; attributes passed consistently- Logout/reset implemented to prevent cross-user contamination
- Key events implemented: Product Viewed, Added to Cart, Checkout Started, Order Completed
- Event properties include stable IDs (
product_id,cart_id,order_id) for dedupe and suppression - Flush behavior validated on “app background” and “app kill” scenarios
- Customer.io Activity Logs show correct ordering + identity stitching for a full test funnel
Expert Implementation Tips
These are the small operator moves that keep your retention machine from degrading over time as the app evolves.
- Force-flush on revenue-critical moments. Trigger an immediate flush after
Checkout StartedandOrder Completed. It’s the simplest way to reduce abandonment false positives. - Use a cart/session identifier everywhere. Pass
cart_idon add-to-cart, checkout, and purchase. Then your journey can suppress based on “purchase with same cart_id,” not just “any purchase,” which matters for multi-cart shoppers. - Version your schemas, not your event names. Keep
Added to Cartstable, addschema_versionas a property when you change payload shape. That keeps segments and reporting intact. - Don’t over-identify. If you call
identifywith an email before it’s verified (or before the user is truly logged in), you’ll create brittle profiles and increase duplicates. Wait for a reliable ID.
Common Mistakes to Avoid
Most tracking issues don’t show up as “errors.” They show up as lower conversion, higher unsubscribes, and support tickets about irrelevant messages.
- Relying on default flush timing. Events get stuck on-device when users background the app, leading to late triggers and broken suppression.
- Using unstable identifiers. Sending
product_namewithoutproduct_id, or using ephemeral cart tokens that change between screens, makes it impossible to dedupe or personalize reliably. - Not resetting identity on logout. This is a classic cause of “my wife got my winback coupon” type issues.
- Tracking purchases only client-side. If your app can drop events due to connectivity, you’ll undercount buyers and over-send winbacks. In practice, we prefer server-side as the source of truth for
Order Completed, with the SDK providing intent signals. - Event/property drift across platforms. iOS sends
productId, Android sendsproduct_id, web sendssku— your segments become Swiss cheese.
Summary
SDK packages and configuration decide whether Customer.io receives clean, timely events and whether anonymous browsing becomes usable retention data. If you’re building cart recovery, repeat purchase, or reactivation off app behavior, treat identity + flush behavior as revenue infrastructure. When it’s set up right, your journeys trigger faster, suppress correctly, and personalize without guesswork.
Implement Packages Options with Propel
If you’re rolling out Customer.io SDK tracking across iOS/Android/web (or cleaning up a legacy implementation), it helps to approach packages + config like an operator: define the events your retention program needs, lock the schema, then validate identity stitching end-to-end. We regularly do this alongside teams running Customer.io so the data feeding cart recovery and winback is dependable. If you want us to review your package selection, identify strategy, and event payloads, book a strategy call.