We were getting trials from Instagram ads. RevenueCat proved it. But Meta Ads Manager reported zero. The culprit isn't the ads — it's how Apple privacy (ATT) and SKAN carry the signal. This page explains it in five minutes.
Same users, same month. RevenueCat — our source of truth for subscriptions — counted hundreds of trial starts. Meta, which we pay to drive them, saw none of them.
The ads worked. The measurement didn't. Meta literally couldn't see the conversions it was paying for — so it couldn't optimise, and we couldn't trust the numbers.
Since iOS 14.5, every app must ask permission before it can track you across apps. That permission unlocks the IDFA — the device ad ID Meta historically used to match a trial back to the exact ad click.
Your data will be used to deliver personalised ads.
That's the trap: the old, identifier-based way of counting trials is dead on arrival for almost everyone we acquire.
SKAdNetwork (SKAN) is Apple's own attribution system. It needs no IDFA and no ATT permission — that's the entire point. Instead of identifying a person, the app sends Apple a tiny anonymous code, and Apple passes an aggregated result to Meta.
User taps your Instagram ad. Meta cryptographically signs the click.
App opens and sets a conversion value — a small code for what happened.
cv = trial startedApple waits a randomised 24–48h, strips all identity, then sends a postback.
anonymous · delayedMeta reads the conversion value via your schema and reports the trial.
The whole system hinges on that conversion value — and that's exactly where our problem lived.
The conversion value is decoded with a schema you configure in AppsFlyer. Ours only encoded “app installed.” So every postback Meta received said “install” — and nothing about trials. Flip the switch below to see what changed.
Same ads, same spend, same users. The only change is that the trial and direct subscription events now occupy a slot in the code — so Apple's postback can finally carry them, and Meta can finally count them.
Rebuilt the AppsFlyer conversion-value schema so a trial start and a direct subscription each map to a value Meta can read.
Turned on “Support anonymized users” so SKAN postbacks from the ~90% who decline ATT are retained instead of dropped.
The app now forwards media source & campaign into RevenueCat, so paid installs stop showing as “No Attribution.”
Because Apple anonymises and delays everything, conversions surface gradually — and only for installs that happen from now on. It will not backfill.
iOS users opt out of tracking, so the old way of counting trials is dead. SKAN is the privacy-safe replacement — but it only works if the trial event is written into its conversion-value code. Ours wasn't; now it is. Expect Meta's trial numbers to start climbing within a week, stay lower than RevenueCat, and get more reliable as volume grows.