In-app Event Listeners (SDK): Make On-Device Behavior Usable for Retention

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 retention programs to feel timely (and not like batchy email blasts), your app has to tell Customer.io what a shopper actually did—on device, in the moment. In most retention programs, the difference between “nice dashboards” and “revenue-driving automations” comes down to whether your SDK event listeners are wired correctly and whether identity stitching is reliable. If you want a second set of eyes on the tracking plan before you ship, book a strategy call.

Think of in-app event listeners as the layer that turns taps, screens, and purchase intent into clean events you can segment on and trigger Journeys from—without waiting for server logs, and without guessing what happened inside the app.

How It Works

On the app side (iOS/Android/React Native/etc.), you initialize the Customer.io SDK and register listeners (or call track/identify in the right places) so key actions emit events to Customer.io. Those events land on the person profile, become available for segmentation, and can trigger campaigns (push, email, in-app) with the exact context that happened on device.

  • Install + initialize the SDK so the app can send events and manage device tokens for push.
  • Identify the user when you have a stable identifier (typically after login, account creation, or when an email/phone is captured). This is where identity stitching lives or dies.
  • Track events from real UI moments (screen views, add-to-cart, checkout started, payment failed, purchase completed) with consistent names and properties.
  • Handle anonymous-to-known merging so pre-login browsing/cart intent doesn’t get stranded on an anonymous profile.
  • Use event properties for precision (SKU, category, cart value, currency, variant, inventory status) so you can orchestrate smarter recovery and upsell flows.

D2C scenario: a shopper adds a “Vitamin D + K2” bundle to cart in your mobile app, gets distracted, and closes the app. If your SDK tracks cart_updated with cart contents and you identify them when they log in (or when they enter email at checkout), you can trigger a push within 30 minutes (“Your bundle is still in your cart”) and follow with email if they don’t convert—without relying on web-only tracking.

Step-by-Step Setup

Before you write code, align on the minimum retention event map you actually plan to use. In practice, teams over-track early, then nobody trusts the data. Start with the events that power cart recovery and repeat purchase, then expand.

  1. Install the Customer.io SDK for your platform (iOS/Android/React Native/Flutter/Expo).
    • Confirm the environment keys (site ID/API key or equivalent) are correct for dev vs prod.
    • Verify network calls are allowed (ATS/SSL/proxy rules) so events don’t silently fail.
  2. Initialize the SDK at app start.
    • Do this as early as possible in the app lifecycle so first-session behavior is captured.
    • Enable logging in dev builds so QA can validate events quickly.
  3. Decide your identity strategy (critical).
    • Pick a stable customer_id (internal user ID is best) and treat email/phone as attributes, not the primary key.
    • Define the exact moment you call identify(): login success, account creation, or “email captured” at checkout.
  4. Implement identify() with attributes you’ll segment on.
    • Examples: email, phone, country, timezone, marketing_opt_in, first_purchase_date.
    • Send only what you’ll use—attribute bloat makes segmentation messy and slower to debug.
  5. Track the retention-critical events with consistent naming.
    • Start with: product_viewed, add_to_cart, checkout_started, purchase_completed, payment_failed.
    • Include properties: sku, product_id, category, price, currency, quantity, cart_value, cart_items (array/JSON), order_id.
  6. Verify anonymous behavior merges into the known profile.
    • QA flow: open app fresh → browse → add to cart (anonymous) → log in → ensure pre-login events appear on the identified profile.
    • If you see duplicate profiles, fix the identify timing and the ID you’re using.
  7. Validate in Customer.io.
    • Check the person profile activity feed for event order and property payloads.
    • Build a quick segment like “Performed add_to_cart in last 1 day AND NOT purchase_completed” to confirm the events are usable for orchestration.

When Should You Use This Feature

In-app event listeners matter when app behavior is the source of truth for intent. If you’re trying to run retention off Shopify orders alone, you’ll miss the “almost bought” moments that drive the biggest incremental lift.

  • App cart recovery when a shopper adds to cart or starts checkout but doesn’t purchase.
  • Browse-to-buy nudges when someone views the same category/SKU multiple times without adding to cart (great for replenishable or high-consideration products).
  • Reactivation based on in-app inactivity (e.g., no app_open + no product_viewed for 21 days) with a push-first approach.
  • Repeat purchase timing when you need accurate “purchase_completed” timestamps and items to drive replenishment, cross-sell, and post-purchase education.

Operational Considerations

Once events are flowing, the work shifts from “can we track it?” to “can we trust it enough to automate revenue?” That’s where naming conventions, payload discipline, and identity stitching become operational requirements—not engineering nice-to-haves.

  • Segmentation hygiene: standardize event names and property keys across iOS/Android so one segment works everywhere. If Android sends productId and iOS sends product_id, your segments will quietly undercount.
  • Data flow latency: app events should arrive fast enough to trigger near-real-time cart recovery. If you queue events offline, set expectations for delays and avoid “15 min push” promises you can’t keep.
  • Identity stitching realities: most retention programs break when identify happens too late (after purchase) or uses unstable IDs (email that changes, guest checkout tokens). Use a stable internal ID and merge anonymous activity as soon as you can.
  • Orchestration across channels: app-side events should drive push/in-app first, then email/SMS as fallback. This avoids over-emailing people who are still actively browsing in-app.
  • Event volume control: don’t fire product_viewed on every scroll impression. Track meaningful views (PDP opened, time on page threshold) so your “high intent” segments aren’t noisy.

Implementation Checklist

Use this as the “ready to automate” gate. If any of these are shaky, you’ll spend your time debugging segments instead of shipping revenue flows.

  • SDK installed and initialized in both dev and prod
  • identify() called with a stable primary ID (not just email)
  • Anonymous pre-login events successfully merge into the identified profile
  • Core events implemented: product_viewed, add_to_cart, checkout_started, purchase_completed
  • Event properties standardized across platforms (same keys, same types)
  • QA segment built in Customer.io to confirm eligibility logic (cart abandoners, non-buyers, etc.)
  • Push token/device registration verified (if you’re using push for recovery/reactivation)

Expert Implementation Tips

These are the small choices that keep your retention engine stable as you scale campaigns and add more triggers.

  • Track “cart state,” not just “add_to_cart.” A single cart_updated event with the full cart payload makes recovery logic cleaner than trying to reconstruct intent from multiple add/remove events.
  • Send a deterministic order payload on purchase. Include order_id and item array so you can dedupe, attribute, and build post-purchase cross-sell segments without stitching later.
  • Use a guardrail for rapid-fire events. For example, debounce product_viewed so you don’t trigger “viewed 3x” segments from accidental back-and-forth taps.
  • Align event taxonomy with how you’ll message. If your cart recovery creative depends on “category,” make sure category is a property on both view and cart events.

Common Mistakes to Avoid

Most issues aren’t “SDK bugs”—they’re tracking decisions that make segments unreliable or impossible to maintain.

  • Identifying with email as the primary key and later discovering you can’t reliably merge guest activity or handle email changes.
  • Firing purchase events from the app without dedupe when the server also sends purchase events—leading to double conversions and broken suppression logic.
  • Inconsistent property types (e.g., cart_value sometimes a number, sometimes a string), which breaks filters and liquid rendering.
  • Tracking too much too early and ending up with noisy “intent” segments that include everyone.
  • Waiting to QA until after campaigns are live—by then you’re debugging in production with real customers.

Summary

If your app is where buying intent happens, SDK event listeners are what make that intent actionable inside Customer.io. Get identity stitching right, keep events consistent, and your cart recovery + repeat purchase flows become faster, smarter, and easier to scale.

Implement In App Actions with Propel

Once events are clean, the next step is turning them into orchestration that actually holds up: push-first cart recovery, suppression logic that prevents over-messaging, and segments your team trusts. If you’re building that layer on top of Customer.io and want an operator’s POV on the tracking plan and automation design, book a strategy call.

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