
How to use RevenueCat and AppsFlyer to track subscription revenue by campaign
Connect RevenueCat and AppsFlyer for campaign-level subscription revenue attribution. Pair with journey experiments.
Campaign managers optimize CPI. Finance asks about CAC payback on subscription revenue. Your MMP attributes installs. RevenueCat records trials and renewals. The gap between those systems is usually onboarding: the screens where users decide whether to start a trial at all.
Connecting RevenueCat and AppsFlyer for subscription revenue by campaign is table stakes for growth teams. What most stacks still miss is step-level context: which campaign produced users who dropped on screen three versus users who reached the paywall and converted. This guide covers the integration architecture, event mapping, readout discipline, and how to pair attribution with journey experiments in Rheo.
Why install-level reporting is not enough
AppsFlyer excels at answering: which media source, campaign, and creative drove this install? RevenueCat excels at answering: did this user start a trial, convert to paid, and renew?
Neither tool, on its own, explains why a high-spend campaign underperforms on revenue:
| Signal | AppsFlyer | RevenueCat | Typical gap |
|---|---|---|---|
| Install attributed to campaign | Yes | Indirect | None |
| Trial start | Via S2S if configured | Yes | Event delay or mapping errors |
| Paid conversion | Via S2S if configured | Yes | Cohort lag |
| Drop-off on onboarding screen 4 | No | No | Black box |
| Paywall arrival rate by campaign | No | Partial | Needs funnel tooling |
A campaign with cheap installs and terrible onboarding completion looks profitable in the MMP until finance reviews trial starts per dollar spent. A expensive campaign that brings fewer installs but higher-intent users may be underfunded because CPI looks bad in isolation.
The fix is a three-layer model:
- AppsFlyer labels the session with acquisition context.
- Rheo (or equivalent journey layer) records step-level funnel performance with those labels attached.
- RevenueCat remains the billing source of truth; events flow back to AppsFlyer for UA reporting.
For AppsFlyer-specific funnel segmentation in Rheo, see Rheo + AppsFlyer: connecting acquisition to in-app funnel performance.
Architecture: how the three tools fit together
Rheo does not replace AppsFlyer or RevenueCat. Each product keeps its core job.
| Layer | Owner | Responsibility |
|---|---|---|
| Attribution | AppsFlyer | Install, re-engagement, campaign labels |
| Journey and experiments | Rheo | Onboarding graph, branches, step analytics |
| Billing and entitlements | RevenueCat | Products, offerings, purchase events |
| Paywall UI | RevenueCat (or your paywall integration) | Native paywall presentation triggered at a flow step |
Important: Rheo does not manage paywall UI. Your external integration (typically RevenueCat via react-native-purchases-ui) owns presentation, packages, and store transactions. Rheo orchestrates when users reach that surface and what happens next based on purchase outcomes.
Data flow on the device
- User installs from a paid campaign. AppsFlyer SDK records conversion data.
- Rheo SDK normalizes attribution into
sdkAttributes(for example,acquisition.media_source,acquisition.campaign). - User progresses through onboarding screens served by Rheo.
- Flow reaches a RevenueCat paywall node. RevenueCat presents the paywall and returns normalized outcomes:
purchase_completed,restore_completed,dismissed,failed. - Rheo records step events with session context, including acquisition dimensions.
- RevenueCat fires purchase events your app forwards to AppsFlyer via S2S postbacks (existing UA setup).
Live AppsFlyer callbacks override a device cache so decision nodes and analytics stay current without re-querying the MMP on every screen.
Server-to-server events for UA dashboards
Device SDKs are not sufficient for media buying automation at scale. Configure AppsFlyer S2S postbacks (or partner integrations) for subscription milestones:
| Event | Source | AppsFlyer use |
|---|---|---|
af_trial_started or custom | RevenueCat webhook → your backend → AppsFlyer | Optimize toward trials |
af_purchase / revenue | RevenueCat with price and currency | ROAS reporting |
af_subscribe | Renewal or first paid period | LTV modeling |
Map RevenueCat event names consistently. Document the mapping in your analytics runbook so growth and engineering do not maintain two conflicting schemas.
RevenueCat → AppsFlyer integration docs live in each vendor's dashboard. Rheo does not sit in that pipe; it enriches the pre-purchase journey so you know which campaigns fail before billing events fire.
Step-by-step setup checklist
Engineering prerequisites
- AppsFlyer SDK initialized in the host app with correct dev and prod keys.
- RevenueCat configured at app launch (
Purchases.configure). Entitlements and offerings created in the RevenueCat dashboard. - Rheo SDK integrated with stable
userIdfor consistent experiment bucketing. - AppsFlyer integration enabled in Rheo app settings → Integrations.
- RevenueCat integration enabled in Rheo with default offering id for paywall nodes.
Attribution hygiene
Campaign naming conventions matter more than most teams admit. If media buyers rename campaigns weekly, historical funnel segments break.
| Practice | Why |
|---|---|
| Stable campaign prefixes | Comparable Rheo cohorts over time |
| Document renames in UA tracker | Joins remain possible in warehouse |
| Separate test campaigns from production | QA traffic does not pollute readouts |
| Align SKAN and ATT strategy with funnel design | Denied tracking still needs usable paths |
Validate end to end
On a physical device (simulators are limited for real attribution):
- Install from a test campaign link.
- Confirm
acquisition.*keys appear in Rheo resolve preview or debug logs. - Complete onboarding and trigger the RevenueCat paywall.
- Start a sandbox trial.
- Verify trial event in RevenueCat, step funnel in Rheo, and postback in AppsFlyer within expected latency.
Latency between systems can be 15 minutes to several hours depending on S2S configuration. Do not debug campaign ROAS with five-minute refresh expectations.
Reading subscription revenue by campaign
Once data flows, build a recurring readout template.
Primary metrics by acquisition cohort
| Metric | Definition | Where to read |
|---|---|---|
| Installs | Attributed installs | AppsFlyer |
| Onboarding completion | Reached end of flow or paywall node | Rheo step funnel |
| Paywall arrival rate | % of starts that hit paywall step | Rheo |
| Trial start rate | Trials per install | RevenueCat, segmented by Rheo cohort |
| Trial-to-paid | Paid conversions per trial | RevenueCat |
| Revenue per install | Cumulative revenue / installs | Warehouse join or AppsFlyer ROAS |
Segment every metric by media_source and campaign at minimum. Add adset when creative testing is concentrated.
Diagnose campaign problems with step funnels
Aggregate trial rate alone hides fixable issues:
- Low paywall arrival, good trial rate among arrivals: onboarding problem. Fix screens before the paywall in Rheo.
- High paywall arrival, low trial rate: paywall or offer problem. Test in RevenueCat Experiments or your paywall tool; adjust journey handoff copy in Rheo.
- Good trial rate, poor trial-to-paid: activation or product value problem. Often outside first session; still note campaign skew.
Example: TikTok cohort reaches the paywall 22% of the time versus Facebook at 31%. Trial rate conditional on arrival is similar. The lever is onboarding narrative mismatch with short-form creative, not price. Ship a campaign-specific branch in Rheo without an App Store release.
Pair attribution with journey experiments
Campaign-level revenue tracking becomes actionable when you can change the journey by cohort and measure lift.
Experiment patterns that respect attribution
| Pattern | When to use | Risk |
|---|---|---|
| Global flow A/B test | Hypothesis applies to all traffic | Cleanest statistics |
Decision node by acquisition.media_source | Creative mismatch for one channel | Monitor sample size per arm |
| Holdout on legacy path | Leadership needs incrementality proof | Reduces power |
| Sequential tests | Low traffic | Slower but valid |
Do not run overlapping Rheo journey experiments and RevenueCat paywall experiments on the same users without a factorial design and enough traffic. Most mobile teams should serialize: fix onboarding for a campaign in Rheo, then test paywall template in RevenueCat once arrival rate stabilizes.
Primary metrics for combined readouts
Pick one primary metric per experiment:
- Trial starts per install when onboarding is the hypothesis.
- Revenue per install at D30 when paywall and pricing interact (longer runtime required).
- Paywall arrival rate when moving paywall timing earlier or later.
Guardrails: onboarding completion, permission grant rate, paywall dismiss rate, refund rate.
Common mistakes
| Mistake | Symptom | Fix |
|---|---|---|
Unstable userId | Users switch experiment arms | Persist ID across sessions |
| Missing S2S events | AppsFlyer ROAS flat while RevenueCat shows revenue | Fix webhook → postback pipe |
| Peeking daily | Stop tests early on noise | Pre-register runtime (14+ days) |
| Optimizing CPI only | Cheap installs, no trials | Add trial/start KPI to UA |
| Ignoring ATT deny paths | Blank acquisition fields on iOS | Branch flows for limited tracking |
Governance between growth, product, and engineering
| Role | Owns |
|---|---|
| Engineering | SDK versions, AppsFlyer init, RevenueCat configure, S2S mapping |
| Growth | Campaign naming, budget allocation, AppsFlyer dashboards |
| Product | Onboarding hypotheses, flow variants, experiment backlog |
| Analytics | Warehouse joins across MMP, Rheo, RevenueCat |
Weekly 30-minute sync: top three campaigns by spend, funnel cliff per campaign, one shipped experiment, one queued hypothesis.
What this stack does not solve automatically
- Causal lift still requires experiment discipline and adequate sample size.
- SKAN limitations on iOS compress signal; complement with modeled and consented cohorts.
- Paywall creative tests remain in RevenueCat or your paywall vendor, not Rheo.
- Rheo will not replace AppsFlyer reporting for media buyers.
It does close the loop between which campaign brought the user and which screen lost them before subscription revenue ever had a chance.
Summary
Track subscription revenue by campaign by keeping AppsFlyer as attribution source of truth, RevenueCat as billing source of truth, and Rheo as the journey microscope. Wire S2S events for UA automation, segment Rheo funnels by acquisition.* keys, and run journey experiments that move trial starts and revenue per install, not just installs.
Connect the integrations, baseline two weeks by campaign, then iterate onboarding where the data shows cliffs. Your MMP keeps the ledger; Rheo shows what happened between install and paywall.
Start for free and connect AppsFlyer to your first onboarding flow.