Summarize this documentation using AI
Overview
If you’re migrating an older implementation to the current Customer.io SDK, the goal isn’t “upgrade the library”—it’s protecting your retention triggers (cart recovery, browse abandon, replenishment, winback) from quietly breaking because identity and event payloads drifted.
If you want a second set of eyes on the tracking plan before you ship (so you don’t lose attribution or double-fire events), you can book a strategy call and we’ll sanity-check the migration path like an operator would.
How It Works
SDK migrations usually go wrong in two places: identity stitching (who is this person?) and event parity (did the same behavioral signals still arrive with the same names/properties?). The Customer.io SDK sits app-side (web and/or mobile), collects device + user context, and sends identify and track calls into Customer.io so your segments and journeys keep evaluating correctly.
- Installation/upgrade changes the client behavior. Newer SDKs may change initialization patterns, consent handling, automatic device metadata collection, or how anonymous vs identified users are represented.
- Identity stitching is the backbone. In practice, retention programs depend on a clean handoff from anonymous browsing/app usage to an identified customer profile after login, email capture, or checkout. If your
identify()call timing changes, cart and browse recovery can fall apart. - Event parity keeps automations firing. Your journeys are usually keyed off specific events (e.g.,
Added to Cart,Checkout Started,Order Completed) and specific properties (SKU, price, category, cart_id). A migration that renames an event or drops a property won’t “error”—it’ll just stop matching segments. - Duplicate profiles happen during upgrades. If old code identified by email but new code identifies by an internal ID (or vice versa), you’ll create parallel people records. That’s how you end up sending winback to someone who purchased yesterday.
Step-by-Step Setup
Plan the migration like you’re protecting revenue, not like you’re updating dependencies. The cleanest path is: baseline what you send today, upgrade the SDK, then prove identity + event parity in a test environment before you roll out.
- Inventory your current tracking contract.
Pull a list of today’sidentifyfields and all events used in segments/journeys (names + required properties). If you don’t do this, you’ll only notice breakage when flows stop converting. - Decide your canonical identifier.
Pick the one ID that should represent a person long-term (commonly your internal customer ID). Keep email as an attribute, not the primary key, unless your system truly has no stable user ID. - Upgrade the SDK in a controlled environment.
Implement the new SDK version in staging (or behind a feature flag). Don’t ship directly to production without side-by-side validation. - Re-implement initialization + consent handling.
Make sure initialization happens once per app lifecycle (mobile) or page load (web SPA patterns vary). If you’re gating tracking behind consent, confirm you’re not callingtrack()before consent and then never replaying key events. - Implement
identify()at the right moment.
Callidentify()immediately after the app/site knows who the user is (login, account creation, email capture, or checkout). Include your canonical ID and set stable attributes (email, phone, timezone, acquisition source if you store it). - Handle anonymous-to-known stitching explicitly.
If your old version relied on implicit merging, confirm the new SDK still merges anonymous activity into the identified profile the way you expect. Test the exact flow: browse anonymously → add to cart → then log in/enter email → verify the cart event sits on the identified profile. - Recreate all critical
track()events with the same schema.
Keep event names consistent. Keep property keys consistent. If you must change names, plan a transition window where you send both old and new events and update journeys deliberately. - Validate in Customer.io Activity Logs.
For a test user, confirm: (a) one person profile, (b) correct identifiers/attributes, (c) events arriving with expected properties, (d) segment membership updates as expected. - Roll out gradually and monitor duplicates.
Use phased rollout (percentage-based release) and watch for spikes in new profiles, suppression anomalies, or sudden drops in journey entry rates.
When Should You Use This Feature
SDK migration work is worth doing when your retention program depends on app-side behavior—or when you’re seeing data quality issues that are already costing you sends and conversions. Most D2C brands don’t feel it until cart recovery or replenishment performance dips for “no reason.”
- You’re losing cart recovery triggers on mobile. Example: users add to cart in-app, then log in at checkout. If anonymous events aren’t merging, your “Added to Cart → no purchase in 1 hour” flow won’t catch them.
- You’re launching push/in-app and need clean device identity. Newer SDKs often handle device tokens and app lifecycle more reliably, which matters for winback and back-in-stock.
- You’re standardizing IDs across tools. If you’re aligning Customer.io with your data warehouse or ecommerce platform IDs, migration is the moment to stop identifying by email and start identifying by customer_id (while still storing email as an attribute).
- You’re fixing event drift. If “Product Viewed” means different things on web vs app, upgrading is a good forcing function to unify event names/properties so segments behave consistently.
Operational Considerations
Upgrading the SDK is easy; keeping your orchestration stable is the real work. Think through how segments, dedupe rules, and journey triggers behave when identity and event timing changes.
- Segmentation depends on property consistency. If your cart recovery segment checks
cart_totaland the new SDK sendstotal, you’ll silently under-include high-intent shoppers. - Data flow timing impacts journey entry. Mobile apps often queue events offline and flush later. If your new SDK flushes differently, your “send after 30 minutes” logic might fire late or not at all if you’re using tight windows.
- Orchestration needs dedupe guards. During migration, sending both old/new events can double-trigger flows unless you add idempotency (e.g., a journey attribute like
cart_recovery_started=truepercart_id). - Profile duplication is a deliverability and CX risk. Two profiles for one buyer means double emails, conflicting suppression states, and broken frequency caps.
- Cross-channel consistency matters. If email is triggered by server-side order events but push is triggered by SDK events, mismatched IDs cause “purchased” to land on one profile and “abandoned cart” on another.
Implementation Checklist
Before you call the migration “done,” you want proof that your highest-value retention automations still have the same inputs and the same audience membership.
- Document current
identify()fields and canonical person ID - List all journey/segment-critical events and required properties
- Upgrade SDK in staging or behind a feature flag
- Verify anonymous → identified merge using a real cart flow
- Confirm event names and property keys match the pre-migration schema
- Validate a test user in Activity Logs (single profile, correct events)
- Add temporary dedupe protections if dual-sending events
- Monitor journey entry rates and new-profile creation during rollout
Expert Implementation Tips
In most retention programs, we’ve seen migrations succeed when teams treat tracking like a product interface: versioned, tested, and monitored. The quickest wins come from tightening identity and making event payloads boringly consistent.
- Use a “tracking contract” doc. One page: event name, when it fires, required properties, and sample payload. Make engineering and marketing sign off before release.
- Prefer stable IDs over mutable identifiers. Email changes; customer_id doesn’t. Store email/phone as attributes and update them when they change.
- Send a cart_id and order_id everywhere. It makes dedupe and debugging dramatically easier, especially when users hop between devices.
- Instrument a migration QA journey. Create an internal-only journey that triggers on key events and pings Slack/email with the payload. You’ll catch missing properties within minutes.
- Plan a transition window if you must rename events. Dual-send for 1–2 weeks, update segments/journeys, then retire the old names. Don’t flip everything in one deploy.
Common Mistakes to Avoid
The painful failures aren’t dramatic—they’re silent. A week later, revenue from cart recovery is down 20% and everyone blames creative. It’s usually tracking.
- Changing the primary identifier during migration without a merge plan. This creates duplicate people and breaks suppression/frequency logic.
- Calling
identify()too late. If you only identify after purchase, you lose the entire pre-purchase behavioral trail that powers recovery flows. - Dropping “boring” properties. SKU, variant_id, price, and category are what make dynamic product blocks and personalized follow-ups work.
- Assuming web and app events are interchangeable. If web sends
Product Viewedand app sendsViewed Product, your “viewed but not purchased” segment becomes incomplete. - No rollout monitoring. If you don’t watch journey entry counts and profile creation rates during rollout, you’ll miss breakage until it’s expensive.
Summary
Migrating an older Customer.io SDK version is really an identity + event parity project. Nail those two, and your cart recovery, repeat purchase, and reactivation programs keep running without surprises.
If you’re changing identifiers or event schemas, treat it like a phased release with QA and monitoring—not a one-shot upgrade.
Implement Migrate Upgrade with Propel
If you’re mid-upgrade and want to pressure-test identity stitching and event parity before it hits revenue, we’ll review your SDK calls, event schema, and journey dependencies in the context of your retention program inside Customer.io.
Bring your current event list and one real scenario (like in-app cart abandonment after login) and book a strategy call—we’ll map the safest migration path and the checks that catch silent breakage.