Overview
Apple Search Ads provides a robust ecosystem for integrating with mobile measurement partners (MMPs), analytics platforms, and attribution frameworks. The platform's privacy-first approach, particularly with SKAdNetwork and the Search Ads Attribution API, enables conversion tracking while protecting user privacy in the post-iOS 14.5 era.
This guide covers all available integration options, from native Apple solutions to third-party partner integrations, helping you build a comprehensive measurement and optimization stack for your app campaigns.
Integration Capabilities
Native Apple Integrations
Apple Search Ads offers several native integration options that provide seamless data flow within the Apple ecosystem:
App Store Connect Integration
- Automatic campaign performance data syncing
- App Analytics integration for organic vs paid user comparison
- Custom product page variant testing with Search Ads traffic
- In-app event measurement and optimization
- App clip campaign tracking
Search Ads API
- Programmatic campaign management and reporting
- Automated bid adjustments based on performance
- Bulk campaign creation and editing
- Custom reporting with granular metrics
- Real-time performance monitoring
SKAdNetwork Framework
- Privacy-preserving conversion attribution for iOS 14.5+
- Conversion value schema (0-63) for in-app event mapping
- Timer-based postback windows (0-24 hours, 24-48 hours, 48-72 hours)
- Source app identifier for re-engagement campaigns
- Lockout window randomization for privacy
Search Ads Attribution API
- Client-side attribution token retrieval
- Deterministic attribution for consented users
- Keyword-level attribution data (when available)
- Campaign and ad group granularity
- Real-time install attribution
Platform Requirements
Access Levels
- Basic reporting: Search Ads account with read access
- Campaign management: Campaign manager role
- API integration: Admin or API Account Manager role
- App Analytics linking: App Store Connect admin or marketing role
Technical Prerequisites
- iOS app published on App Store
- Valid Apple Developer account
- App Store Connect access
- Xcode for SDK integration
- Server infrastructure for API calls (if using Search Ads API)
Mobile Measurement Partner Integrations
Overview
Mobile measurement partners provide unified attribution, analytics, and fraud prevention across all your marketing channels, including Apple Search Ads.
Supported MMPs
AppsFlyer
- Setup: Install AppsFlyer SDK, enable Search Ads attribution in dashboard
- Attribution Method: Search Ads Attribution API + SKAdNetwork
- Features:
- Unified dashboard for all ad networks
- Fraud protection and validation
- Deep linking and deferred deep linking
- Audience segmentation and retargeting
- ROI and LTV measurement
- Custom attribution windows
- Data Available: Campaign, ad group, keyword (when user consented)
- SKAdNetwork Support: Full conversion value management and postback handling
- Cost: Included in AppsFlyer subscription tiers
Adjust
- Setup: Integrate Adjust SDK, configure Search Ads in Adjust dashboard
- Attribution Method: Search Ads Attribution API + SKAdNetwork
- Features:
- Real-time attribution and analytics
- Fraud prevention suite
- Audience builder for retargeting
- Cohort analysis and retention tracking
- Revenue and LTV analytics
- Uninstall tracking
- Data Available: Campaign, ad group, keyword, creative set
- SKAdNetwork Support: Conversion value mapping and postback processing
- Cost: Based on monthly attributed installs
Singular
- Setup: Install Singular SDK, enable Search Ads in platform
- Attribution Method: Search Ads Attribution API + SKAdNetwork
- Features:
- Marketing analytics and attribution
- Cost aggregation across networks
- ROI reporting and analysis
- Fraud prevention
- Creative reporting
- ETL data pipeline
- Data Available: Full Search Ads hierarchy data
- SKAdNetwork Support: Advanced conversion value optimization
- Cost: Based on attributed conversions
Branch
- Setup: Integrate Branch SDK, configure Search Ads attribution
- Attribution Method: Search Ads Attribution API + SKAdNetwork
- Features:
- Deep linking across platforms
- Cross-platform attribution
- Web-to-app attribution
- Deferred deep linking
- Journey and funnel analytics
- People-based attribution
- Data Available: Campaign and ad group data with keyword when available
- SKAdNetwork Support: Conversion value schema management
- Cost: Free tier available, paid plans for advanced features
Kochava
- Setup: Install Kochava SDK, enable Apple Search Ads integration
- Attribution Method: Search Ads Attribution API + SKAdNetwork
- Features:
- Multi-touch attribution
- Fraud detection and prevention
- Audience targeting
- Deep linking
- Cost and ROI analytics
- Real-time reporting
- Data Available: Campaign, ad group, keyword attribution
- SKAdNetwork Support: Full postback handling and conversion value management
- Cost: Based on monthly attributed installs
MMP Integration Setup
Step 1: SDK Integration
// Example: AppsFlyer SDK initialization
import AppsFlyerLib
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
AppsFlyerLib.shared().appsFlyerDevKey = "YOUR_DEV_KEY"
AppsFlyerLib.shared().appleAppID = "YOUR_APPLE_APP_ID"
// Enable Search Ads attribution
AppsFlyerLib.shared().waitForATTUserAuthorization(timeoutInterval: 60)
return true
}
Step 2: Configure SKAdNetwork
- Add SKAdNetwork IDs to Info.plist
- Configure conversion value schema in MMP dashboard
- Map in-app events to conversion values (0-63 range)
- Set up postback URL endpoint
Step 3: Enable Search Ads Attribution API
// Retrieve Search Ads attribution token
import AdServices
func requestAttributionData() {
if #available(iOS 14.3, *) {
if let token = try? AAAttribution.attributionToken() {
// Send token to MMP or your server
AppsFlyerLib.shared().attributionToken = token
}
}
}
Step 4: Configure Postbacks
- Set up conversion event postback URLs
- Map Search Ads events to MMP event taxonomy
- Configure postback parameters (cost, revenue, custom dimensions)
- Test postback delivery with test campaigns
Analytics Platform Integrations
Firebase Analytics
Integration Method: Via MMP or direct implementation
- Setup: Install Firebase SDK, configure event tracking
- Attribution Flow: MMP attributes install → Sends data to Firebase
- Available Data: Campaign, ad group, source (limited by SKAdNetwork)
- Use Cases:
- Funnel analysis for Search Ads traffic
- Comparing user behavior by acquisition source
- LTV prediction models
- A/B testing with Search Ads cohorts
Configuration:
// Firebase with Search Ads attribution
import FirebaseAnalytics
// Log acquisition events
Analytics.logEvent("ad_campaign_attribution", parameters: [
"source": "apple_search_ads",
"campaign": campaignName,
"ad_group": adGroupName
])
Amplitude
Integration Method: Via MMP SDK integration or Events API
- Setup: Install Amplitude SDK alongside MMP SDK
- Attribution Flow: MMP attributes → Forwards to Amplitude
- Available Data: User properties from Search Ads campaigns
- Use Cases:
- Behavioral cohort analysis
- Product analytics by acquisition source
- Retention analysis
- User journey mapping
Configuration:
// Amplitude user properties from Search Ads
import Amplitude
let identify = AMPIdentify()
identify.set("acquisition_source", value: "apple_search_ads")
identify.set("campaign_name", value: campaignName)
identify.set("keyword", value: keyword) // When available
Amplitude.instance().identify(identify)
Mixpanel
Integration Method: Via MMP integration or Mixpanel SDK
- Setup: Install Mixpanel SDK, configure attribution via MMP
- Attribution Flow: MMP → Mixpanel via HTTP API or SDK
- Available Data: Super properties with campaign attribution
- Use Cases:
- Funnel conversion analysis
- Feature adoption by traffic source
- Retention cohorts
- Revenue analytics
Configuration:
// Mixpanel super properties for Search Ads users
import Mixpanel
Mixpanel.mainInstance().registerSuperProperties([
"acquisition_channel": "apple_search_ads",
"campaign": campaignName,
"ad_group": adGroupName
])
Google Analytics for Firebase
Integration Method: Via Firebase integration
- Setup: Enable Google Analytics in Firebase console
- Attribution Flow: Firebase SDK → Google Analytics
- Available Data: Limited by SKAdNetwork privacy requirements
- Use Cases:
- Cross-platform user journey tracking
- E-commerce conversion tracking
- Audience building for other channels
Attribution Framework Implementation
SKAdNetwork Setup
SKAdNetwork is Apple's privacy-preserving attribution framework, mandatory for iOS 14.5+ attribution.
Conversion Value Schema Design
Best practices for mapping in-app events to the 0-63 conversion value range:
Example Schema: E-commerce App
Values 0-9: Days since install (0=day 0, 9=day 9+)
Values 10-19: Purchase tiers (10=no purchase, 15=$1-50, 19=$100+)
Values 20-29: Session count (20=1 session, 29=10+ sessions)
Values 30-39: Reserved for future events
Example Schema: Gaming App
Values 0-19: Level progression (0=no progress, 19=level 20+)
Values 20-29: In-app purchase tiers
Values 30-39: Engagement score (sessions × time)
Values 40-63: Reserved
Implementation:
import StoreKit
// Update conversion value when key events occur
func updateConversionValue(for event: AppEvent) {
var conversionValue: Int = 0
switch event {
case .levelCompleted(let level):
conversionValue = min(level, 19)
case .purchase(let amount):
if amount >= 100 {
conversionValue = 29
} else if amount >= 50 {
conversionValue = 25
} else if amount > 0 {
conversionValue = 20
}
}
SKAdNetwork.updatePostbackConversionValue(conversionValue) { error in
if let error = error {
print("Error updating conversion value: \(error)")
}
}
}
Postback Handling:
- Set up server endpoint to receive SKAdNetwork postbacks
- Parse postback JSON for campaign ID and conversion value
- Map conversion value back to meaningful events
- Aggregate data for campaign optimization
Search Ads Attribution API
The Attribution API provides more granular attribution data for users who have granted permission.
Implementation:
import AdServices
class SearchAdsAttribution {
static func requestAttribution() {
if #available(iOS 14.3, *) {
do {
let token = try AAAttribution.attributionToken()
// Send token to your server
sendAttributionToken(token)
} catch {
print("Error getting attribution token: \(error)")
}
}
}
static func sendAttributionToken(_ token: String) {
// POST to Apple's attribution endpoint
let url = URL(string: "https://api-adservices.apple.com/api/v1/")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let body = ["token": token]
request.httpBody = try? JSONSerialization.data(withJSONObject: body)
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
// Process attribution data
if let attribution = try? JSONDecoder().decode(AttributionData.self, from: data) {
// Store or forward attribution data
print("Campaign: \(attribution.campaignId)")
print("Ad Group: \(attribution.adGroupId)")
print("Keyword: \(attribution.keyword ?? "not available")")
}
}
}.resume()
}
}
struct AttributionData: Codable {
let campaignId: Int
let adGroupId: Int
let keyword: String?
let attribution: Bool
}
Privacy Considerations:
- Keyword data only available when user granted ATT permission
- Campaign and ad group data available in limited form via SKAdNetwork
- Always respect user privacy choices
- Implement proper consent management
CRM and Marketing Automation Integrations
Salesforce Integration
Method: Via MMP offline conversion uploads or custom API integration
- Use Case: Track high-value app users through sales funnel
- Setup:
- Export Search Ads attribution data from MMP
- Match users by email or device ID (hashed)
- Upload as leads or contacts in Salesforce
- Track conversion to closed-won deals
- Attribution Loop: Measure CAC to LTV for Search Ads channels
HubSpot Integration
Method: Via MMP webhooks or HubSpot API
- Use Case: Marketing automation and lead nurturing for app users
- Setup:
- Configure MMP to send install events to HubSpot
- Create contact properties for attribution data
- Set up workflows for Search Ads users
- Build segments for targeted campaigns
- Benefits: Email nurturing, push notification targeting, multi-touch attribution
Custom CRM Integration
For custom CRM systems:
// Example: Sending attribution data to custom CRM
func sendToCRM(attributionData: AttributionData, userProfile: UserProfile) {
let crmPayload: [String: Any] = [
"user_id": userProfile.id,
"email": userProfile.email,
"acquisition_source": "apple_search_ads",
"campaign_id": attributionData.campaignId,
"ad_group_id": attributionData.adGroupId,
"install_date": Date(),
"attributed": attributionData.attribution
]
// POST to your CRM API
sendToAPI(endpoint: "https://your-crm.com/api/contacts", payload: crmPayload)
}
API Integration Patterns
Search Ads Campaign Management API
Authentication:
# Generate OAuth token
curl -X POST https://appleid.apple.com/auth/oauth2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Authorization: Basic [base64_client_credentials]" \
-d "grant_type=client_credentials&scope=searchadsorg"
Common API Operations:
Fetch Campaign Performance:
import requests
def get_campaign_metrics(access_token, org_id, campaign_id):
url = f"https://api.searchads.apple.com/api/v4/campaigns/{campaign_id}"
headers = {
"Authorization": f"Bearer {access_token}",
"X-AP-Context": f"orgId={org_id}"
}
response = requests.get(url, headers=headers)
return response.json()
Automated Bid Management:
def update_keyword_bid(access_token, org_id, campaign_id, ad_group_id, keyword_id, new_bid):
url = f"https://api.searchads.apple.com/api/v4/campaigns/{campaign_id}/adgroups/{ad_group_id}/targetingkeywords/{keyword_id}"
headers = {
"Authorization": f"Bearer {access_token}",
"X-AP-Context": f"orgId={org_id}",
"Content-Type": "application/json"
}
payload = {
"bidAmount": {
"amount": str(new_bid),
"currency": "USD"
}
}
response = requests.put(url, json=payload, headers=headers)
return response.json()
Bulk Reporting:
def get_campaign_report(access_token, org_id, start_date, end_date):
url = f"https://api.searchads.apple.com/api/v4/reports/campaigns"
headers = {
"Authorization": f"Bearer {access_token}",
"X-AP-Context": f"orgId={org_id}",
"Content-Type": "application/json"
}
payload = {
"startTime": start_date,
"endTime": end_date,
"selector": {
"orderBy": [{"field": "localSpend", "sortOrder": "DESCENDING"}],
"pagination": {"offset": 0, "limit": 1000}
},
"groupBy": ["countryOrRegion"],
"timeZone": "UTC",
"returnRowTotals": True,
"returnRecordsWithNoMetrics": False
}
response = requests.post(url, json=payload, headers=headers)
return response.json()
Data Export and Warehouse Integration
Export Options
Search Ads Reporting API
- Format: JSON via REST API
- Frequency: Real-time to daily aggregation
- Granularity: Campaign, ad group, keyword, search term
- Metrics: Impressions, taps, installs, spend, average CPA, TTR, conversion rate
- Retention: Up to 12 months via API
MMP Data Exports
- Format: CSV, Parquet, JSON
- Delivery: S3, Google Cloud Storage, SFTP, HTTP endpoint
- Frequency: Hourly, daily, or real-time streaming
- Scope: Raw install data, aggregated reports, cohort analysis
- Use Cases: Data warehouse loading, BI tool integration
Data Warehouse Integration
BigQuery Integration Example:
from google.cloud import bigquery
import requests
def load_search_ads_to_bigquery(access_token, org_id, project_id, dataset_id):
# Fetch data from Search Ads API
campaigns = get_all_campaigns(access_token, org_id)
# Transform to BigQuery schema
rows_to_insert = []
for campaign in campaigns:
rows_to_insert.append({
"campaign_id": campaign["id"],
"campaign_name": campaign["name"],
"impressions": campaign["impressions"],
"taps": campaign["taps"],
"installs": campaign["installs"],
"spend": campaign["spend"],
"date": campaign["date"]
})
# Load to BigQuery
client = bigquery.Client(project=project_id)
table_id = f"{project_id}.{dataset_id}.search_ads_campaigns"
errors = client.insert_rows_json(table_id, rows_to_insert)
if errors:
print(f"Errors: {errors}")
else:
print("Data loaded successfully")
Snowflake Integration:
- Use Search Ads API to export to S3
- Configure Snowpipe for automatic ingestion
- Transform data with dbt or Snowflake SQL
- Join with other marketing data sources
Redshift Integration:
- Export Search Ads data to S3 via scheduled scripts
- Use COPY command to load into Redshift
- Create materialized views for common queries
- Join with app event data from MMPs
Common Integration Issues
Issue 1: Missing Attribution Data
Symptoms:
- Installs showing as organic when they should be attributed to Search Ads
- Keyword data not appearing in MMP dashboard
Causes:
- Search Ads Attribution API not implemented
- SKAdNetwork not properly configured
- User denied ATT permission
- Attribution window mismatch
Solutions:
- Implement both SKAdNetwork and Attribution API
- Verify Info.plist includes Apple's SKAdNetwork ID
- Check MMP integration is properly configured
- Review attribution window settings (default is 30 days)
Issue 2: Conversion Value Not Updating
Symptoms:
- All SKAdNetwork postbacks showing conversion value of 0
- Events firing but not reflected in postback
Causes:
- Conversion value not being updated in code
- Events firing after 24-hour lockout window
- Incorrect conversion value schema
Solutions:
// Ensure conversion value updates occur early
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize early
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
// Update conversion value after app is stable
SKAdNetwork.updatePostbackConversionValue(10) // Base value for install
}
return true
}
// Update for key events
func onPurchaseComplete(amount: Double) {
let value = calculateConversionValue(for: amount)
SKAdNetwork.updatePostbackConversionValue(value)
}
Issue 3: API Authentication Failures
Symptoms:
- 401 Unauthorized errors from Search Ads API
- Token expires unexpectedly
Causes:
- Invalid client credentials
- Expired OAuth token
- Incorrect org ID in headers
- Insufficient permissions
Solutions:
- Verify client ID and secret in Apple Search Ads UI
- Implement token refresh logic (tokens expire after 1 hour)
- Confirm user has API Account Manager role
- Check X-AP-Context header includes correct orgId
Issue 4: Data Discrepancies
Symptoms:
- Install counts differ between Search Ads and MMP
- Revenue numbers don't match between platforms
Causes:
- Attribution window differences
- Time zone mismatches
- Currency conversion
- Different event definitions
Solutions:
- Align attribution windows across platforms
- Use UTC for all date comparisons
- Store revenue in single currency before aggregation
- Document event definitions and ensure consistency
- Accept 5-10% variance as normal due to attribution methodology
Support and Resources
When to Contact Support
Apple Search Ads Support:
- Campaign approval issues
- Billing discrepancies
- API access problems
- Account access issues
- Contact: Search Ads support in dashboard or Apple Business Chat
MMP Support:
- Attribution discrepancies > 10%
- SKAdNetwork postback issues
- SDK integration problems
- Data export failures
- Contact: Via partner support portals
App Store Connect Support:
- App Analytics integration issues
- Custom product page problems
- In-app event configuration
- Contact: App Store Connect support
Additional Resources
- Apple Search Ads API Documentation
- SKAdNetwork Documentation
- Search Ads Attribution API Guide
- MMP Integration Guides
Backlog & Opportunities
- Explore advanced SKAdNetwork conversion value mapping strategies for multi-event optimization
- Evaluate custom product pages for Search Ads traffic to improve conversion rates
- Implement server-to-server attribution validation for fraud prevention
- Test fine conversion value updates to maximize data granularity within 6-bit limit
- Build automated bid management using machine learning on Search Ads API data
- Create unified attribution dashboard combining SKAdNetwork and deterministic data
- Implement cross-promotion workflows using shared attribution insights across app portfolio