Summarize this documentation using AI
Overview
If you’re running retention in Customer.io, deep links are one of those “small” implementation details that quietly decides whether push and SMS drive revenue or just generate opens. When the tap lands a shopper on the exact cart, PDP, or reorder screen, you cut friction and lift conversion—especially on cart recovery and replenishment.
If you want a second set of operator eyes on your SDK tracking + deep link routing (where most programs break in practice), you can book a strategy call and we’ll pressure-test your event map, identity stitching, and message handoff.
How It Works
Deep links are basically your “tap destination contract” between Customer.io messages and your app. Customer.io sends a message with a URL (or a payload value) and your mobile app decides what to do with it—open the cart screen, load a PDP, or jump into an authenticated account view.
- Message contains a destination: In push (and often SMS), you include a link like
myapp://cartor a universal link likehttps://brand.com/app/cart. The exact format depends on your app’s linking setup (custom scheme vs universal/app links). - OS routes the tap: iOS/Android decides whether to open the app directly (if installed) or fall back to web/app store (if not). Universal/App Links generally behave more reliably than custom schemes.
- Your app parses the link and routes: The app reads path + query params (e.g.,
?sku=,?cart_id=,?discount=) and navigates to the right screen. - Customer.io attribution depends on SDK identity + events: The deep link itself doesn’t “fix” attribution. You still need clean
identifycalls and post-click events (likeCheckout Started,Order Completed) so Customer.io can connect the tap to downstream revenue.
D2C scenario: A shopper abandons a cart in-app. Your push message says “Your cart’s waiting—checkout in 2 taps.” The deep link opens Cart with the items preloaded. If your app can’t resolve the cart (missing cart_id or identity mismatch), they land on Home, browse aimlessly, and your recovery rate tanks.
Step-by-Step Setup
Deep links are easy to “turn on” and surprisingly easy to get wrong operationally. The goal is: consistent link format, correct routing in-app, and clean identity stitching so taps and purchases tie back to the same person in Customer.io.
- Pick one deep link strategy and stick to it
- Preferred: Universal Links (iOS) + App Links (Android) with an
https://domain you control. - Fallback: Custom scheme (
myapp://) if you can’t support universal/app links yet. - Decide on a canonical pattern like
https://brand.com/app/cart,https://brand.com/app/pdp?sku=ABC,https://brand.com/app/reorder?order_id=123.
- Preferred: Universal Links (iOS) + App Links (Android) with an
- Implement app-side routing for each retention destination
- Map deep link paths to screens: cart, PDP, collection, reorder, loyalty, subscription portal, etc.
- Support query params that your retention program needs (examples:
sku,variant_id,cart_id,offer,utm_campaign). - Handle “not logged in” gracefully: store the intended destination, prompt login, then route post-auth.
- Make identity stitching non-negotiable in the SDK
- Call
identifyas soon as you have a stable customer identifier (email, customer_id). Don’t wait until checkout. - If you track pre-login behavior (browse, add-to-cart), keep it anonymous and then merge on login/signup so the cart recovery push hits the right profile.
- Ensure the same identifier is used across app + web + backend events (this is where duplicate profiles usually come from).
- Call
- Track the events that prove the deep link worked
- At minimum:
Deep Link Opened(withdestination),Product Viewed,Checkout Started,Order Completed. - Include properties that let you segment and debug:
message_id(if available),campaign_name,destination_path,sku,cart_value. - Fire events server-side for purchase when possible, then reconcile with app events. App-only purchase events tend to get dropped on flaky connections.
- At minimum:
- Wire the deep link into Customer.io messages
- In push: set the click action / URL to your deep link or universal link.
- In SMS: use a short link that resolves to your universal link (and falls back to web if the app isn’t installed).
- Keep the link format consistent across channels so your app routing logic stays simple.
- QA like an operator (not like a developer)
- Test: app installed vs not installed, logged in vs logged out, fresh install, expired cart, out-of-stock item.
- Confirm the person in Customer.io who clicked is the person who purchased (identity stitching check).
- Validate that your “success” event fires after routing (e.g.,
Cart Viewedwithin 10 seconds of click).
When Should You Use This Feature
Deep links matter most when your message is trying to close a loop—not just announce something. Anytime the customer needs to take a specific action, sending them to Home is basically a conversion tax.
- Cart recovery (high intent): Push/SMS opens directly to cart with items loaded; optionally apply an offer parameter that your app can redeem.
- Back-in-stock and price drop: Deep link to PDP with the correct variant selected, not just the product family.
- Replenishment / repeat purchase: Deep link to “Reorder” for the last purchased SKU or subscription management screen.
- Reactivation: Deep link to a curated collection or personalized “Recommended for you” feed to shorten time-to-value on the first session back.
Operational Considerations
Deep links look like a creative detail, but they behave like infrastructure. If your data model or orchestration is messy, deep links amplify the mess—wrong destination, wrong user, wrong offer, and suddenly you’re training customers not to click.
- Segmentation depends on event hygiene: If you want “clicked cart push but didn’t checkout,” you need reliable click +
Checkout Started/Order Completedevents tied to the same person. - Identity stitching is the difference between revenue and noise: In most retention programs, we’ve seen duplicate profiles cause “ghost” conversions—clicks on one profile, purchases on another. Fix this before you judge performance.
- Data flow timing matters: If purchase events arrive late (or only from the app), your cart recovery journey can keep sending nudges after someone already bought.
- Offer logic needs a single source of truth: If you pass
discount=10OFFin the deep link, your app must validate and apply it consistently. Otherwise support tickets spike (“your text said 10% off”). - Cross-channel orchestration: If SMS and push both deep link to cart, coordinate frequency caps so you don’t double-tap the same shopper with two identical prompts.
Implementation Checklist
Before you roll deep links into a revenue-critical flow (cart, replenishment, winback), make sure the basics are locked. This checklist is the fastest way to avoid the usual “it works on my phone” trap.
- Universal/App Links (or custom scheme) configured and tested on iOS + Android
- Canonical deep link patterns defined (paths + required query params)
- App routing implemented for cart, PDP, reorder, collection, and account states
identifycall happens reliably post-login/signup (and merges anonymous activity if you use it)- Events tracked:
Deep Link Opened,Cart Viewed/Product Viewed,Checkout Started,Order Completed - Purchase tracked server-side (preferred) or reconciled against app events
- QA matrix completed: installed/not installed, logged in/out, expired cart, OOS
- Customer.io messages use the same link format across push/SMS/email where relevant
Expert Implementation Tips
Once the basics work, the gains come from making deep links measurable and resilient. That’s what lets you scale journeys without guessing where the drop-off happens.
- Track destination-level performance: Log
destination=cartvsdestination=pdpon yourDeep Link Openedevent so you can see what actually converts. - Design for logged-out taps: Save the intended destination locally, complete auth, then route. Otherwise your “VIP early access” push becomes a dead end.
- Use stable identifiers in links: Prefer
sku/variant_id/order_idover fragile things like collection index positions. - Keep deep links channel-agnostic: The same URL should work from push, SMS, email, and even QR codes. Operationally, it reduces edge cases and QA time.
- Don’t rely on app-only purchase events for suppression: If you’re using “purchased” as an exit condition, server-side events prevent over-messaging when the app is backgrounded or offline.
Common Mistakes to Avoid
Most deep link failures aren’t dramatic—they’re subtle leaks that shave conversion off every send. Fix these early and your retention team stops arguing with analytics.
- Sending everyone to Home: It inflates clicks and kills downstream conversion, especially for cart recovery.
- Not handling logged-out state: Customers tap, hit a login wall, and never get back to the cart/PDP they were promised.
- Broken identity stitching: Click attributed to one profile, purchase recorded on another—then journeys keep firing after purchase.
- Missing required params: Deep link opens the right screen but can’t load the right cart/variant, so the shopper bounces.
- No QA on real-world conditions: Expired carts, out-of-stock variants, fresh installs, and OS-level link handling differences are where performance dies.
Summary
If you’re serious about cart recovery, replenishment, or winback, deep links are table stakes—because they remove the friction between intent and purchase. Get the SDK identity + event layer right, then treat deep links like a routing system you can measure and optimize.
Implement Deep Links with Propel
If you’re already sending push/SMS from Customer.io, the highest-leverage move is usually tightening the app-side pieces: consistent deep link patterns, clean identify behavior, and events that prove the tap actually led to checkout. In practice, this tends to break at the seams—anonymous-to-known merges, late purchase events, and “opened app” without a clear destination.
If you want help pressure-testing the implementation and turning it into a measurable retention lever (not just a dev ticket), book a strategy call.