The paid ads attribution problem
Mobile app install ads are a major spend category, but measuring their ROI is broken. Without deep linking, you can't track what happens after someone installs your app from an ad.
What happens without deep links:
- 1.User clicks your ad on Facebook or Google. They're sent to app store to install.
- 2.App installs. User launches it for the first time.
- 3.They see your home screen. What were they supposed to do? The ad message is lost.
- 4.If they don't convert immediately, you can't track attribution. Did this ad drive the purchase, or was it another touchpoint?
- 5.You can't measure ROAS accurately. Ad spend increases, but ROI remains unclear.
Without deep links
- ✕Ad context lost when app installs
- ✕No attribution for post-install conversions
- ✕Can't measure true ROAS
- ✕Users see generic home screen, not ad-targeted content
With deferred deep links
- ✓Ad campaign context preserved through install
- ✓Track conversions directly attributed to ads
- ✓Measure accurate ROAS for each campaign
- ✓App opens to ad-specific content, boosting conversion
How deferred deep links solve paid ad attribution
Deferred deep links preserve campaign data and user context through the app install process, enabling accurate ROI measurement.
Step 1: Create campaign-specific deep links
Create unique Redirectly deep links for each ad campaign with UTM parameters and targeting data: https://myapp.redirectly.app/offer?utm_source=facebook&utm_campaign=summer_sale&offer_id=summer2024
Step 2: User clicks ad
User sees your ad on Facebook or Google Ads. They click and are sent to your app store listing. Redirectly captures the full deep link URL with all campaign parameters.
Step 3: App install
User installs your app from the store. The campaign data (UTM parameters, offer ID) is preserved in Redirectly's servers, associated with this user's device.
Step 4: SDK retrieves campaign context
When the app launches for the first time, the Redirectly SDK queries: "What campaign should this user see?" Redirectly responds with the full deep link, including campaign parameters and offer ID.
Step 5: Log attribution event
Your app logs an attribution event to your analytics and ad platform. The event includes the campaign source, campaign name, and other UTM parameters. Conversions are now attributed to the correct ad campaign.
Step 6: Measure ROAS
Track conversions (purchases, signups, etc.) attributed to each ad campaign. Calculate true ROAS by dividing revenue from ad-driven users by total ad spend. Optimize budgets based on data.
Facebook and Google Ads deep linking
Facebook Ads Integration
Facebook App Installs campaigns can include deep links in the "Deep Link" field or through app events. Use Redirectly to create campaign-specific deep links that preserve UTM parameters through install. Log conversion events with the campaign attribution data so Facebook can optimize future campaigns.
Google Ads Integration
Google App Campaigns automatically add GCLID (Google Click ID) to deep links for attribution. Combine GCLID with Redirectly's deferred deep linking to preserve campaign context through install. Send conversion events back to Google with GCLID for attribution.
UTM Parameter Preservation
Redirectly preserves all UTM parameters (source, medium, campaign, content, term) through the install process. Your app receives the exact same UTM parameters in the deferred deep link as were in the original ad click. This enables accurate multi-touch attribution and campaign analysis.
Attribution tracking implementation
Setup and initialization
Initialize Redirectly and your analytics platform:
import 'package:redirectly/redirectly.dart';
import 'package:firebase_analytics/firebase_analytics.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize Redirectly
await Redirectly.initialize(
apiKey: 'your_api_key_here',
);
// Initialize Firebase Analytics
FirebaseAnalytics analytics = FirebaseAnalytics.instance;
// Listen for deferred deep links from ads
Redirectly.onDeepLink.listen((link) {
_handleAdDeepLink(link, analytics);
});
runApp(const MyApp());
}Handle attribution deep links
Parse campaign parameters and log attribution events:
Future<void> _handleAdDeepLink(
RedirectlyLink link,
FirebaseAnalytics analytics,
) async {
// Extract UTM parameters
final utmSource = link.queryParameters['utm_source'];
final utmMedium = link.queryParameters['utm_medium'];
final utmCampaign = link.queryParameters['utm_campaign'];
final utmContent = link.queryParameters['utm_content'];
final gclid = link.queryParameters['gclid'];
// Log attribution event to analytics
await analytics.logEvent(
name: 'ad_attribution',
parameters: {
'utm_source': utmSource,
'utm_medium': utmMedium,
'utm_campaign': utmCampaign,
'utm_content': utmContent,
if (gclid != null) 'gclid': gclid,
},
);
// Store attribution data for later use
final prefs = await SharedPreferences.getInstance();
await prefs.setString('utm_campaign', utmCampaign ?? '');
await prefs.setString('utm_source', utmSource ?? '');
// Navigate to campaign-specific content
if (link.path == 'offer') {
final offerId = link.queryParameters['offer_id'];
// Navigate to offer screen
context.go('/offer?id=$offerId');
}
}Log conversion events
When a user converts, include attribution data in the event:
Future<void> _logPurchase(
double revenue,
String itemId,
FirebaseAnalytics analytics,
) async {
final prefs = await SharedPreferences.getInstance();
final utmCampaign = prefs.getString('utm_campaign') ?? 'direct';
final utmSource = prefs.getString('utm_source') ?? 'direct';
// Log purchase with attribution data
await analytics.logPurchase(
currency: 'USD',
value: revenue,
items: [
AnalyticsEventItem(
itemId: itemId,
itemName: 'Product Purchase',
price: revenue,
),
],
parameters: {
'utm_campaign': utmCampaign,
'utm_source': utmSource,
},
);
// Send event to ad platform for conversion tracking
_reportConversionToAdPlatform(
revenue: revenue,
campaign: utmCampaign,
);
}Report conversions back to ad platforms
Send conversion data back to Facebook and Google for ROAS calculation:
Future<void> _reportConversionToAdPlatform({
required double revenue,
required String campaign,
}) async {
const String facebookConversionUrl =
'https://graph.facebook.com/v18.0/$PIXEL_ID/events';
// Report to Facebook
final facebookPayload = {
'data': [
{
'event_name': 'Purchase',
'event_time': DateTime.now().millisecondsSinceEpoch ~/ 1000,
'currency': 'USD',
'value': revenue.toString(),
'event_source_url': 'https://myapp.example.com',
}
],
'access_token': 'YOUR_PIXEL_TOKEN',
};
try {
await http.post(
Uri.parse(facebookConversionUrl),
body: jsonEncode(facebookPayload),
headers: {'Content-Type': 'application/json'},
);
print('Conversion reported to Facebook');
} catch (e) {
print('Error reporting to Facebook: $e');
}
// Google Ads will receive conversion via Firebase if properly configured
}This implementation ensures:
- Campaign data preserved through app install via deferred deep links
- UTM parameters captured and stored for later use in conversion tracking
- Conversions attributed to the correct ad campaign with full context
- ROAS measured accurately by reporting conversions back to ad platforms
Next steps
Learn more about deferred deep linking and ad attribution:
Frequently asked questions
How does deferred deep linking improve ROAS?
By preserving campaign context through install, users land on relevant content instead of a generic home screen. This increases engagement and conversion rates. Additionally, you can accurately attribute conversions to the campaigns that drove them, allowing you to optimize budgets toward high-performing campaigns.
Does this work with Facebook and Google Ads simultaneously?
Yes. Use consistent UTM parameters across both platforms. Redirectly preserves all UTM data through install, and you can report conversions to both platforms. This gives you attribution data in both Facebook Ads Manager and Google Ads.
What if the user already has the app installed when they click the ad?
The deep link opens immediately in the app (not the app store). The user is taken directly to the campaign-specific content. Redirectly handles this seamlessly—no special configuration needed.
Can I track multi-touch attribution with deferred deep links?
Yes. Store attribution data from the first app launch, then append it to all subsequent conversion events. This shows the original campaign that drove the install, even if other touchpoints occur later.
Do I need to modify my ad campaigns to use this?
Minimally. Create Redirectly deep links with UTM parameters, then add those deep links to your ad campaigns. Facebook and Google Ads both support deep link fields. That's it—your existing ad setup works with deferred deep linking.
What happens if my server is down when the user installs?
Redirectly's servers are highly available (99.99% uptime). But if a timeout occurs, your app can still function—just without the deferred deep link data. Users would see your home screen instead of campaign-specific content.