Set Up In-App Messages (SDK) in Customer.io

Customer.io partner logo

Table of Contents

Summarize this documentation using AI

This banner was added using fs-inject

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Overview

If you want in-app to pull its weight in retention (not just “nice UI banners”), you need clean app-side tracking and consistent identity stitching into Customer.io. When teams struggle with in-app performance, it’s usually not the creative—it’s that the SDK isn’t identifying users at the right moment, events are missing key properties, or anonymous activity never gets merged.

If you want a second set of eyes on your tracking plan before you ship it, you can book a strategy call. In most retention programs, a 30-minute review catches the issues that would otherwise take weeks to diagnose in reporting.

How It Works

Customer.io in-app messaging is only as good as what your app tells it. The SDK collects device context, listens for your identify calls, and records events you track (like Viewed Product or Started Checkout). Customer.io then uses those people profiles + event history to decide who qualifies for an in-app message, when it should show, and how often.

  • SDK initialization: your app boots the Customer.io SDK with your workspace/site credentials so it can receive message definitions and report interaction.
  • Identity stitching: anonymous users can generate activity before login; once you call identify(userId), Customer.io can merge that anonymous activity into the known profile (assuming you’ve implemented it correctly and consistently).
  • Event tracking drives targeting: in-app eligibility usually depends on a recent event plus properties (e.g., Added to Cart with cart_value and sku).
  • Display logic happens in-app: Customer.io decides the audience and sends the payload; the SDK is responsible for rendering and tracking impressions/clicks/dismissals.

Real D2C scenario: A shopper adds a moisturizer to cart on mobile, gets distracted, then reopens the app later. If you track Added to Cart and App Opened, and you identify them as soon as they authenticate (or stitch anonymous-to-known correctly), you can show a targeted in-app message on next open: “Your cart’s waiting—free shipping ends tonight.” Without identity stitching, that message often never shows to the right person, or worse, shows to everyone.

Step-by-Step Setup

Before you build messages, lock down the data contract your app will send. In practice, teams move faster when engineering and retention agree on a small set of canonical events and properties first—then you wire the SDK once and reuse it across cart recovery, replenishment, and winback.

  1. Install the Customer.io SDK for your app platform
    Add the official Customer.io SDK for iOS/Android/React Native/Flutter/Web and initialize it at app start. Keep initialization early so the SDK can receive in-app definitions and attribute device context.
  2. Implement identify immediately after you know who the user is
    Call identify(userId) right after sign-in/sign-up (and after you refresh auth if your app supports silent login). Also send core attributes you’ll segment on: email (if available), phone (if available), country, language, marketing_opt_in, loyalty_tier.
  3. Handle anonymous users deliberately
    If your app allows browsing before login, track events anonymously and make sure you merge that activity once the user identifies. This is the difference between “cart recovery works” and “we only recover logged-in carts.”
  4. Track the retention events that actually drive in-app
    At minimum for D2C retention:
    • App Opened (or Session Started)
    • Viewed Product with sku, product_id, category, price
    • Added to Cart with sku, quantity, cart_value
    • Started Checkout with cart_value, num_items
    • Order Completed with order_id, revenue, items
    Keep naming consistent across platforms (iOS vs Android vs web) or your segments will silently fracture.
  5. Confirm events and identities in Customer.io before launching messages
    Use Customer.io’s activity/event views to verify:
    • events arrive with the expected properties
    • anonymous activity merges into the identified profile
    • device records exist for the user (important for mobile in-app delivery)
  6. Create your in-app message and target it with real conditions
    Start with one high-intent use case (cart recovery on app open). Target based on Added to Cart within X hours AND no Order Completed since that event. Add frequency caps so you don’t burn users.
  7. Instrument message interactions
    Make sure impressions, clicks, and dismissals are recorded. These become your suppression logic (e.g., don’t show again if dismissed) and your optimization loop.

When Should You Use This Feature

In-app works best when the user is already “in the buying environment” and you need to remove friction or increase intent. If you’re trying to resurrect someone who hasn’t opened the app in 45 days, email/SMS/push usually does the heavy lifting—and in-app becomes the landing experience once they return.

  • Cart recovery on next app open: show a reminder only if the cart is still active and the user hasn’t purchased.
  • Browse-to-buy nudges: if someone viewed the same product twice in 24 hours, show a message with social proof or a bundle option.
  • Post-purchase cross-sell: after Order Completed, show a “complete your routine” message on the next session (not immediately after checkout when they’re trying to leave).
  • Replenishment for consumables: use Order Completed + SKU-level expected replenishment window; show in-app when they open near day 25–35.
  • Reactivate lapsed app users once they return: if last order > 90 days and they open the app, show a “welcome back” offer—but only once, and only to high-LTV segments.

Operational Considerations

Most in-app programs break because the data looks “mostly right” but isn’t reliable enough to automate against. Treat SDK tracking like revenue infrastructure: define the contract, validate it, then build orchestration on top.

  • Segmentation depends on property hygiene: if cart_value is sometimes a string, sometimes a number, your “cart > $75” segment will be wrong. Normalize types and required fields.
  • Identity stitching is the unlock: if a user adds to cart anonymously then logs in, you need that cart event on the known profile or your cart recovery audience shrinks dramatically.
  • Event ordering matters: mobile networks are messy. If Order Completed arrives late, you can accidentally show a cart reminder after purchase. Mitigate with short delays, “has not purchased since…” logic, and server-side confirmation where possible.
  • Orchestration across channels: avoid double-tapping users with push + in-app + email for the same intent. In most retention programs, we’ve seen better results when in-app is the “on-site closer” and push/email are the “bring them back” layer.
  • Frequency and suppression rules: implement caps per message and global caps per day/session. Also suppress after dismissal or after the user completes the goal action.

Implementation Checklist

If you run through this list before launch, you’ll avoid the classic “it works on my phone” rollout. The goal is predictable targeting and clean measurement, not just messages rendering.

  • SDK initialized at app start on all platforms you support
  • identify(userId) fires on login/signup and after token refresh/silent login
  • Anonymous browsing events tracked and merged into the identified profile
  • Canonical event names standardized across iOS/Android/web
  • Required properties present and typed consistently (numbers as numbers, timestamps as timestamps)
  • Core commerce events implemented: view, add-to-cart, checkout, purchase
  • Message impression/click/dismiss tracked and visible in reporting
  • Segments validated with real users (not just test profiles)
  • Frequency caps + suppression rules defined (dismissed, purchased, converted)
  • Cross-channel rules documented (so push/email don’t collide with in-app)

Expert Implementation Tips

Once the basics are live, the biggest lift comes from tightening your identity and event schema so you can safely personalize and suppress. This is where in-app stops being “a banner tool” and starts being a conversion lever.

  • Send SKU-level context, not just totals: cart recovery performs better when you can reference the exact item and deep link back to the cart or PDP.
  • Delay slightly to avoid race conditions: for cart reminders on app open, a 5–30 second delay often prevents showing a message while the cart is still loading or right after a purchase event is about to arrive.
  • Use dismissals as intent signals: if a user dismisses twice, stop showing that message for 7–14 days and switch to a different angle (bundle, reviews, or replenishment timing).
  • Stitch identities with a single source of truth: pick one stable customer_id across app, web, and backend. If you bounce between email-based IDs and internal IDs, you’ll create duplicates and your targeting will drift.
  • QA with production-like behavior: test anonymous browse → add to cart → login → app reopen. That’s the path that exposes stitching failures.

Common Mistakes to Avoid

These are the issues that cause “in-app isn’t working” tickets—when the real problem is tracking, identity, or orchestration.

  • Identifying too late: if you only call identify after checkout, you lose most behavioral targeting opportunities.
  • Inconsistent event names across platforms: Added to Cart vs add_to_cart splits your audiences and wrecks reporting.
  • Missing properties needed for segmentation: if you don’t send cart_value or sku, you can’t prioritize high-value carts or personalize the message.
  • No suppression after purchase: nothing kills trust faster than “complete your purchase” after someone already paid.
  • Over-messaging: showing an in-app message every session trains users to ignore it. Cap aggressively and earn the impression.
  • Testing only with internal accounts: employee behavior doesn’t match real shoppers; validate with a small live cohort and watch event timelines.

Summary

If your SDK identity and events are clean, Customer.io in-app becomes a reliable conversion layer for cart recovery and repeat purchase. If identity stitching is shaky, you’ll spend your time chasing ghosts in segments and wondering why performance is inconsistent.

Prioritize: initialize early, identify immediately, track a tight commerce schema, and orchestrate with suppression across channels.

Implement Set Up In App with Propel

If you’re rolling out in-app as part of a broader retention program, the fastest path is usually: lock the event schema, validate identity stitching, then build 2–3 high-intent in-app plays (cart, replenishment, post-purchase cross-sell) on top of Customer.io. That sequencing avoids the common trap where messages ship before the data is trustworthy.

If you want help pressure-testing your SDK plan and the suppression/orchestration rules before launch, you can book a strategy call and we’ll review your identify timing, anonymous merge behavior, and the exact events/properties needed to hit your retention goals.

Contact us

Get in touch

Our friendly team is always here to chat.

Here’s what we’ll dig into:

Where your lifecycle flows are underperforming and the revenue you’re missing

How AI-driven personalisation can move the needle on retention and LTV

Quick wins your team can action this quarter

Whether Propel AI is the right fit for your brand, stage, and stack