Summarize this documentation using AI
Overview
If you’re running Customer.io and want a reliable in-app channel for retention (not just “nice-to-have” UI popups), the SDK implementation is where most of the leverage—and most of the breakage—lives. If you want a second set of eyes on identity stitching and event design before you scale campaigns, book a strategy call.
In-app messages work best when they’re tied to real customer intent signals (viewed product, started checkout, order delivered) and when your app is consistently identifying users across sessions and devices. Otherwise, you end up showing the right message to the wrong person—or worse, spamming loyal buyers with “complete your purchase” prompts.
How It Works
In practice, in-app messaging is a three-part system: your app captures identity + events, Customer.io decides eligibility based on those signals, and your app renders the message when the SDK fetches it. The retention win comes from making those signals precise enough that messages feel like help, not ads.
- Identity is the foundation. Your app needs to call
identify(or equivalent) when a user logs in / creates an account so Customer.io can stitch behavior to a known person record. If you delay identify until “later,” you’ll lose the exact moments you want to target (like checkout start). - Anonymous → known stitching matters. Most D2C apps see browsing before login. You want anonymous activity captured, then merged into the known profile at login so “viewed_product” and “added_to_cart” don’t get orphaned.
- Events drive targeting and suppression. The SDK sends events (e.g.,
product_viewed,checkout_started,order_completed) with properties (SKU, cart value, category). Customer.io uses those events to trigger in-app messages or qualify audiences in segments. - The SDK controls display timing. The app typically checks for eligible messages during key moments (app open, screen view, post-purchase confirmation, etc.). If you only fetch on app open, you’ll miss high-intent screens where in-app performs best.
- Frequency and state prevent fatigue. You’ll usually combine Customer.io-side frequency rules with app-side guardrails (e.g., don’t show a modal twice in one session, don’t interrupt checkout screens).
Step-by-Step Setup
The goal here is simple: make sure every in-app impression is attributable to a real customer state, and every customer state is attributable to a single person profile. That means you set up the SDK, identify correctly, and instrument a small set of high-signal events before you build fancy message logic.
- Install the Customer.io SDK in your app.
Add the appropriate mobile SDK (iOS/Android/React Native/Flutter) and confirm the app can initialize with your workspace credentials. - Implement
identifyat the right moment.
Callidentify(userId)immediately after authentication (login/signup). Include core traits you’ll actually segment on (e.g.,email,phoneif collected,first_order_date,vip_tier,marketing_opt_in). - Handle anonymous users and merge on login.
Track pre-login browsing events as anonymous. When the user logs in, ensure the SDK merges anonymous activity into the identified profile (this is where many retention programs quietly lose attribution). - Track a retention-grade event taxonomy.
Start with a tight set of events you can trust:product_viewed(properties:sku,category,price)added_to_cart(properties:sku,qty,cart_value)checkout_started(properties:cart_value,items_count)order_completed(properties:order_id,revenue,items)order_delivered(if you have shipping events; this is gold for replenishment and review asks)
- Decide where in the app you’ll fetch/render messages.
Pick “moments” that map to intent: home screen after open, PDP afterproduct_viewed, cart screen, account screen, post-purchase screen. Avoid interrupting checkout unless the message is strictly helpful (e.g., “Need help? Chat” not “10% off”). - Validate end-to-end in Customer.io Activity Logs.
Confirm a test user’s identify call, events, and device association show up correctly. Then confirm the user qualifies for your in-app message audience and that the SDK actually displays it. - Launch with conservative frequency controls.
Start with low caps (e.g., once per day per message type) and loosen once you see conversion without increased churn/uninstalls.
When Should You Use This Feature
In-app messages shine when the customer is already in the app and you can influence the next click without relying on inbox placement. They’re especially effective for “micro-conversions” that lead to repeat purchase and higher LTV.
- Cart recovery while intent is still hot.
Scenario: A shopper adds a serum to cart (added_to_cart) but bounces. Next time they open the app within 24 hours, show a subtle in-app reminder on the home screen: “Your cart’s still here—checkout in 2 taps.” Suppress iforder_completedfires. - Second purchase acceleration.
Scenario: Afterorder_delivered, show an in-app message on the account page offering a “reorder” button or bundle upgrade—only to customers who bought once and haven’t purchased again in 21–30 days. - Product discovery based on browsing behavior.
If a customer triggersproduct_viewedin a category 3+ times but never adds to cart, use in-app to guide them: best-sellers, quiz, or “compare” flow. - Reactivation for lapsed app users.
When a user returns after 45+ days, in-app can act as the “welcome back” layer that pairs with push/email—without burning a discount on everyone.
Operational Considerations
Most teams don’t fail because they can’t create an in-app message—they fail because the underlying data isn’t consistent enough to target cleanly. Treat this like instrumentation work first, creative work second.
- Segmentation depends on event quality. If
checkout_startedfires inconsistently (or withoutcart_value), you can’t reliably target high-intent abandoners versus casual browsers. - Identity stitching is where attribution dies. If users browse anonymously and later log in, make sure that anonymous event stream merges into the known profile. Otherwise, your “viewed X but didn’t buy” segments undercount and your messages feel random.
- Decide “source of truth” for purchase events. In many D2C stacks, orders are more reliable from your backend or ecommerce system than the app. If your app fires
order_completedbut the backend later fails payment, you’ll suppress recovery messages incorrectly. - Orchestration with other channels matters. Coordinate in-app with push/email so customers don’t get hit with three recovery nudges in an hour. In most retention programs, we’ve seen better performance when in-app handles “on-site” intent and push/email handle “off-site” return.
- Message timing is a product decision. Don’t show modals on the first frame after app open. Use screen-based triggers or a short delay so you don’t tank session quality.
Implementation Checklist
Before you scale in-app beyond a couple of messages, lock in the basics below. It’s the difference between a channel you can trust and a channel you constantly babysit.
- SDK installed and initializing cleanly across environments (dev/stage/prod)
identifycalled immediately after login/signup with stable user ID- Anonymous browsing tracked and merged to known user on login
- Core retention events implemented:
product_viewed,added_to_cart,checkout_started,order_completed - Event properties standardized (SKU, category, cart_value, order_id) and not free-text
- Defined fetch/render points in the app (app open, PDP, cart, account, post-purchase)
- Suppression logic based on purchase events (no recovery prompts after purchase)
- Frequency caps set (per session and per day/week)
- QA plan: test users, event verification, message qualification verification
Expert Implementation Tips
Once the basics are in, the wins come from tightening targeting and reducing “message waste.” That’s where in-app stops being a generic banner tool and starts acting like a retention lever.
- Use “intent tiers” instead of one-size-fits-all. Treat
product_viewedas low intent,added_to_cartas medium, andcheckout_startedas high. Your in-app creative and aggressiveness should match that tier. - Prefer helpful UX over discounts. For cart recovery in-app, a “Resume checkout” CTA often beats “10% off” because the user is already present. Save discounts for off-site reactivation where friction is higher.
- Instrument “message shown” and “message clicked” events. If you can, track impression/click events from the app so you can build suppression like “don’t show this again if they dismissed twice.”
- Build guardrails for edge cases. If a user has 3 open carts across devices, decide which cart_value you trust. If your app supports guest checkout, decide how you handle identity when the email arrives later.
- QA on real devices, not just simulators. In practice, rendering and timing issues show up on older devices and spotty networks—exactly where your retention prompts can get annoying fast.
Common Mistakes to Avoid
These are the patterns that quietly drag performance down and make teams think “in-app doesn’t work for us,” when the real issue is tracking and orchestration.
- Identifying too late. If you only call
identifyafter a user reaches the account screen, you’ll miss the cart and checkout intent that drives most retention value. - Event name chaos. Mixing
AddToCart,added_to_cart, andcart_addacross platforms guarantees broken segments and inconsistent triggers. - No suppression after purchase. Nothing erodes trust faster than “Complete your purchase” after they already bought. Always suppress based on the most reliable purchase signal.
- Overusing modals. If every session starts with a full-screen takeover, customers learn to dismiss you. Use banners/tooltips where possible, save modals for high-value moments.
- Ignoring cross-channel collisions. If push sends “Come back to your cart” and in-app shows the same thing 5 minutes later, you’re not increasing conversion—you’re increasing annoyance.
Summary
If you want in-app messages to drive repeat purchase and recovery, treat the SDK layer like revenue infrastructure: identify early, track clean events, and suppress aggressively. Once identity and events are stable, Customer.io targeting becomes predictable—and that’s when you can scale without spamming.
Implement In App with Propel
If you’re already using Customer.io, the fastest path is usually tightening the SDK instrumentation first (identify + event schema), then rolling out 2–3 high-intent in-app plays (cart resume, reorder, post-delivery cross-sell) with clean suppression. If you want help pressure-testing your tracking plan and orchestration before you ship, book a strategy call.