Rheo CLI is live. Let your agents be your growth engine.

Learn more
Rheo flow canvas branching onboarding paths for ATT grant and deny outcomes
Engineering

ATT permission flows: branch on grant vs deny without losing users

Technical guide to branching onboarding flows on ATT authorization status, and keeping attribution sane when users opt out.

App Tracking Transparency (ATT) is not a single dialog. It is a branch in your onboarding graph. Users who tap "Allow" and users who tap "Ask App Not to Track" need different next steps, different analytics expectations, and different messaging if you want to keep them engaged.

Teams that fire the system prompt and continue as if nothing happened lose users on the awkward silence after denial and poison attribution data by treating opted-out users like fully tracked installs.

This guide covers ATT states, pre-prompt design, branch logic in Rheo, MMP behavior when tracking is denied, and a practical testing matrix.

ATT states you must handle

On iOS, ATTrackingManager.trackingAuthorizationStatus returns one of:

StatusMeaningUser experience
notDeterminedNo prompt shown yetYou may request authorization
restrictedParental / device policyNo IDFA; treat like denied
deniedUser opted outNo IDFA for cross-app tracking
authorizedUser allowed trackingIDFA available subject to rules

Your flow must branch on the result after the system dialog, not only on whether you intended to show it.

Common mistake: Branching only on notDetermined → prompt → next screen, without reading the updated status after the callback. Denied users land on a path that assumes attribution works.

Pre-prompt to system dialog flow

Apple requires the system ATT dialog. You may show a pre-prompt (your own screen) explaining why you ask, but you cannot replicate the system UI or gate app access on tracking consent.

Recommended sequence:

  1. Context screen (optional pre-prompt): Plain language benefit ("Help us measure which campaigns bring subscribers so we can improve the app"). No manipulative dark patterns.
  2. Trigger system dialog from native code when user taps Continue (not on app launch without context).
  3. Read final status in the completion handler.
  4. Branch flow in Rheo based on trait or SDK-reported status.

Timing: Show ATT after value is established, not on first launch second zero. Apps that prompt before explaining see lower opt-in rates in industry benchmarks (Adjust, AppsFlyer reports commonly cite roughly 25–35% aggregate opt-in, higher with good pre-prompt timing and copy).

Rheo supports system permission moments in flows, including ATT, and routes users to different screens based on grant vs deny without app updates when copy or order changes.

Branch logic in the canvas

Think in three paths:

Pre-prompt (optional)

 System ATT dialog
    ↙     ↘
Granted   Denied / Restricted
    ↓           ↓
Path A        Path B

Path A (granted): Continue standard onboarding. MMP SDKs receive IDFA per their integration. No special user-facing message required.

Path B (denied):

  • Acknowledge nothing is wrong ("You can change this anytime in Settings").
  • Continue onboarding with full product value visible.
  • Avoid guilt copy or repeated prompts in the same session.
  • Optionally show a shorter path to signup if analytics are less critical for that cohort.

Path B is not a dead end. Users who deny tracking are still customers. Onboarding completion and trial rate for denied users should be monitored separately.

Trait-based routing

Pass ATT status into Rheo customer traits from your app:

// Conceptual: after ATT callback
rheo.setCustomerAttributes({
  att_status: status === 'authorized' ? 'granted' : 'denied',
});

In the canvas, decision nodes route on att_status. Growth can change branch screens remotely.

Rheo flow canvas with screens connected in the visual editor

MMP handling when denied

Mobile measurement partners (AppsFlyer, Adjust, etc.) use SKAdNetwork and probabilistic methods when IDFA is unavailable.

Engineering checklist:

  • MMP SDK initialized per their ATT guidance (some delay IDFA read until after prompt).
  • Conversion values configured for SKAdNetwork postbacks.
  • Deep links and campaign parameters still work for deterministic matching when possible.
  • Internal analytics (Rheo step events, product analytics) do not depend on IDFA.

Do not: Hide paywall or core features because user denied ATT. That violates spirit of user choice and hurts conversion.

Do: Accept that campaign-level ROAS reporting is coarser for opted-out users. Finance should expect blended reporting, not user-level journeys for 100% of installs.

Rheo integrates with MMPs for acquisition context; step funnels show in-app behavior regardless of ATT outcome.

Testing matrix

Test ATT flows on real devices. Simulator behavior differs.

CaseStepsExpected branch
Fresh installPre-prompt → AllowGranted path
Fresh installPre-prompt → DenyDenied path
Re-prompt attemptSecond launch after denySkip pre-prompt; go denied path
Restricted deviceMDM profileRestricted path
No pre-promptDirect system dialogStill branch on result

QA tips:

  • Reset advertising identifier and reinstall for clean tests.
  • Document iOS version; ATT UI copy varies slightly.
  • Verify analytics events on both branches fire with correct properties.

Privacy copy in Info.plist

NSUserTrackingUsageDescription is required. It appears in the system dialog. Users see this string; marketing does not.

Weak: "We use tracking."
Stronger: "We use your data to measure ad performance and keep subscription prices fair."

Legal should review. The description must match actual data use.

Align pre-prompt copy with Info.plist promise. Contradictions erode trust and opt-in.

Implementation checklist

Product / growth

  • Decide pre-prompt vs direct system prompt.
  • Write branch screens for grant and deny.
  • Set success metrics per branch (completion, trial rate).
  • Cap re-prompt frequency.

Engineering

  • Request ATT only when status is notDetermined (unless re-entry logic intentional).
  • Update Rheo traits on status change.
  • Confirm MMP SDK order-of-operations with ATT.
  • Add automated UI tests where feasible.

Analytics

  • Segment funnels by att_status.
  • Report opt-in rate weekly.
  • Compare trial quality granted vs denied cohorts.

ATT branching is one permission in a longer onboarding story. Pair this guide with improving onboarding conversion for outcome metrics and step-level funnel analytics to verify denied users are not dropping disproportionately on the next screen.

Common implementation pitfalls

Pitfall 1: Prompt on cold launch. Users skip or deny without context. Always pair with a pre-prompt or delayed trigger.

Pitfall 2: Assuming MMP data is complete post-deny. Campaign dashboards will look different. Set stakeholder expectations early.

Pitfall 3: No denied-path content. A blank screen or instant home route feels broken. A single reassuring line plus continue button is enough.

Pitfall 4: Stale trait after Settings change. If user later enables tracking in Settings, refresh att_status on next app open.

Sample pre-prompt copy patterns

StyleExample line
Value exchange"Allow tracking so we can show you relevant offers and measure which features subscribers love."
Transparency"This helps us understand if our ads work. You can change your choice anytime in Settings."
Minimal"Help us measure app performance. Tap Continue to see Apple's privacy choice."

Test pre-prompt copy like any onboarding screen when traffic allows. Opt-in rate is your primary metric; completion on the next onboarding step is the guardrail.

Developer docs and Rheo canvas

For implementation details beyond this overview, see the Rheo developer documentation for permission layers and customer traits. Product teams can adjust branch screens in the canvas while engineering maintains the native ATT request and trait sync.

ATT is one node in a larger permission strategy. Push notifications, location, and HealthKit each deserve their own branch logic using the same pattern: explain, request, branch, continue with value.

Industry ATT opt-in rates vary by category and prompt timing. Track yours monthly. If you are below peer benchmarks, test pre-prompt placement before blaming ad creative or onboarding length.

Growth and engineering should review ATT funnels together monthly: opt-in rate, denied-path completion, and trial rate split by status. Disagreements about attribution are easier to resolve with shared dashboards than with anecdotal camp complaints.

Document your ATT flow version in release notes internally. When opt-in shifts after an iOS update, you will know which canvas version was live.

Denied users are often your largest cohort. Designing a respectful deny path is not edge-case polish. It is core onboarding UX.

FAQ

Should we show ATT on every platform?
ATT is iOS-specific. Android has different privacy settings. Use platform branches in Rheo.

Can we skip ATT for organic users?
Policy and MMP setup may still require consistent handling. Consult legal and your MMP docs before selective prompting.

Does Rheo store IDFA?
Rheo focuses on in-app flow analytics. Follow Rheo and MMP documentation for identifier handling in your stack.

Branch with intent, not hope

ATT permission flows succeed when grant and deny paths are first-class routes with tailored UX, sane MMP expectations, and step metrics that prove denied users still convert.

Start for free. Model ATT branches on the Rheo canvas, publish updates over the air, and keep users moving whether they opt in or out.