Apple Search Ads (ASA) is one of the highest-intent paid acquisition channels available to iOS developers — users searching the App Store are actively looking for a solution. But most guides stop at "create a campaign, set a bid, and review results." This guide goes further.
We'll cover competitor bidding, Custom Product Pages (CPP), campaign architecture, match type strategy, and cohort-based LTV analysis — the advanced techniques that separate apps spending efficiently from those burning budget.
Understanding the ASA Advanced Campaign Architecture
ASA Advanced uses a three-tier structure: Campaign → Ad Group → Keywords/Ads. The most important design principle is intent separation — grouping keywords by search intent and pairing each group with a CPP that matches what the user is looking for.
A well-structured campaign hierarchy for a photo editing app might look like this:
Campaign: Brand Keywords
├── Ad Group: Own Brand
│ Keywords: [AppName], [AppName free], [AppName review]
└── Ad Group: Competitor Brand
Keywords: [CompetitorA app], [CompetitorB photo editor]
Campaign: Generic Keywords
├── Ad Group: Core Function
│ Keywords: photo editor, image editing app, photo filter
├── Ad Group: Use Case — Social Media
│ Keywords: instagram photo edit, tiktok thumbnail, reels editor
└── Ad Group: Competitor Conquesting
Keywords: [CompetitorA alternative], [CompetitorA vs]
Campaign: Search Match Discovery
└── Ad Group: Auto Discovery
(Search Match ON — no manual keywords)
Competitor Keyword Bidding Strategy
Bidding on competitor brand terms is one of the highest-ROI moves in ASA. Users searching for a competitor by name are already problem-aware and comparison-shopping — exactly the right moment to present your alternative.
Finding the Right Competitors to Target
Start with the "You Might Also Like" and "More by This Developer" sections on your App Store page to identify direct competitors. Then mine your Search Match reports — any competitor brand names appearing in impression data are prime candidates.
Third-party tools like AppFollow, Sensor Tower, or data.ai can show which keywords competitors rank for and where they're likely buying ads.
Setting Maximum Bid Amounts
Competitor keywords are typically more expensive and convert at lower rates than branded terms. Calculate your tolerable CPA before setting bids:
Target CPA = ARPU × Payback Period (months) × Gross Margin
Example:
ARPU (monthly premium revenue per active user) = $2.00
Payback period = 6 months
Gross margin = 70%
→ Target CPA = $2.00 × 6 × 0.70 = $8.40
Competitor keyword average CVR = 3%
→ Max CPT (cost per tap) = $8.40 × 0.03 = $0.25
Apply this calculation per campaign and ad group, updating monthly as you gather more data.
Negative Keywords: Precision Over Volume
When targeting competitor keywords, you want comparison shoppers — not die-hard loyal users or support seekers. Use negative keywords to filter out low-intent traffic:
[Competitor] login— existing users, not prospects[Competitor] cancel— churning users unlikely to switch[Competitor] customer service— support-seeking, low conversion intent[Competitor] update— feature-checking existing users
Custom Product Pages (CPP) + Campaign Pairing
CPPs let you show a different App Store page — different screenshots and promotional text — to users landing from specific ad groups. Combined with ASA, they unlock significant conversion rate improvements.
The Core Principle
The message in the ad group's keywords must match the promise shown on the CPP.
| Ad Group Intent | CPP Focus | | Core photo editing queries | Showcase editing tools, filters, precision controls | | Social media / Instagram queries | Show finished social-ready images, share flows | | Competitor brand queries | Lead with your key differentiators: speed, price, features |
Creating CPPs in App Store Connect
Navigate to App Store Connect → Your App → Custom Product Pages → tap "+" to create a new page. Customize the screenshots and promotional text for the specific audience, submit for App Review, and once approved, it becomes available for selection in ASA Advanced.
Linking CPPs to Ad Groups in ASA
In ASA Advanced, navigate to an Ad Group → Ads → select "Custom Product Page" instead of the default store page, then choose your specific CPP.
This single change — matching CPP to keyword intent — consistently yields 20–50% CVR improvements compared to sending all traffic to the default product page.
A/B Testing CPPs
Within one ad group, you can run multiple ads simultaneously to compare CPP performance:
Ad Group: Competitor Conquesting
├── Ad A: CPP_Feature_Focused (highlight your unique features)
├── Ad B: CPP_Price_Focused (emphasize free trial / lower price)
└── Ad C: Default Product Page (baseline)
Run for 2–3 weeks, compare CVR and downstream CPA, and shift budget to the winner once statistical significance is reached.
Match Type Strategy
The Three Match Types
Exact Match: Ads appear only for searches closely matching your specified keyword. Highest precision, easiest CPA management — but limited reach. Use for proven high-performers.
Broad Match: Ads appear for close variants and related searches. Broader reach, good for discovering new high-intent terms, but requires active negative keyword management to avoid waste.
Search Match: No manual keywords needed — ASA automatically matches your app to relevant queries based on metadata and category. Ideal for the discovery phase of a new campaign.
The Three-Phase Campaign Build
Phase 1 — Discovery (Weeks 1–4) Run a Search Match campaign with no manual keywords. Let ASA find you. Review the "Search Terms" impression report weekly, noting which queries drive installs.
Phase 2 — Exact Harvest (Weeks 3–8) Promote top-performing Search Match queries to a dedicated Exact Match ad group. Add those same keywords as negatives in the Search Match campaign to prevent overlap.
Phase 3 — Broad Expansion (Week 6+) For keywords that are stable and profitable in Exact, create Broad Match variants to capture related queries. Add negatives aggressively as you see irrelevant traffic appear.
Timeline:
Weeks 1-4: Search Match Discovery
Weeks 3-8: Exact Match (from Discovery winners)
Week 6+: Broad Match (expansion from Exact winners)
Cohort Analysis: Measuring Post-Install Quality
Install count and CPA are lagging indicators. What really matters is whether the users you're acquiring convert to subscribers and stay. Cohort analysis by ad group reveals which campaigns bring high-LTV users.
Apple Ads Attribution API Integration
import AdServices
// Request attribution token on first app open
func requestAttributionToken() async throws -> String {
if #available(iOS 14.3, *) {
return try await AAAttribution.attributionToken()
}
throw AttributionError.unsupported
}
// Send token to your backend for server-side resolution
func sendTokenToBackend(_ token: String) async {
var request = URLRequest(url: URL(string: "https://yourapi.com/attribution")!)
request.httpMethod = "POST"
request.httpBody = try? JSONEncoder().encode(["token": token])
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
_ = try? await URLSession.shared.data(for: request)
}Resolving Attribution on the Backend
const resolveAppleAttribution = async (token: string) => {
const response = await fetch('https://api-adservices.apple.com/api/v1/', {
method: 'POST',
headers: { 'Content-Type': 'text/plain' },
body: token,
});
if (response.status === 200) {
const data = await response.json();
// data.attribution — true if from ASA
// data.campaignId, data.adGroupId, data.keywordId
return data;
}
return null;
};
const saveAttribution = async (userId: string, attr: AppleAttributionData) => {
await db.insert('user_attributions').values({
user_id: userId,
source: attr.attribution ? 'apple_search_ads' : 'organic',
campaign_id: attr.campaignId,
ad_group_id: attr.adGroupId,
keyword_id: attr.keywordId,
created_at: new Date(),
});
};LTV by Ad Group
SELECT
a.ad_group_id,
COUNT(DISTINCT u.user_id) AS installs,
AVG(r.revenue_30d) AS avg_ltv_30d,
COUNT(CASE WHEN u.is_premium THEN 1 END)::FLOAT /
NULLIF(COUNT(DISTINCT u.user_id), 0) AS conversion_rate
FROM user_attributions a
JOIN users u ON a.user_id = u.id
LEFT JOIN user_revenue_30d r ON u.id = r.user_id
WHERE a.source = 'apple_search_ads'
AND a.created_at >= NOW() - INTERVAL '90 days'
GROUP BY a.ad_group_id
ORDER BY avg_ltv_30d DESC;This query surfaces which ad groups drive high-LTV subscribers versus cheap but low-quality installs — enabling you to reallocate budget toward the campaigns that actually move the business.
Budget Allocation Framework
Daily budget = Target daily installs × Target CPI
Example: 10 installs/day at $5 target CPI = $50/day total
Initial allocation:
Brand Keywords: 20% — efficient, high CVR, protect brand
Generic Keywords: 50% — core volume
Competitor Conquesting: 20% — test and expand
Search Match Discovery: 10% — exploration
For automated bidding, ASA's target CPA (tCPA) mode works well once each ad group has accumulated 30–50+ installs. Before that threshold, manual bidding gives you more control and avoids the auto-optimizer overfitting to sparse data.
Closing Thoughts
Apple Search Ads rewards iteration. The teams getting the best ROI aren't those who set up a campaign and walk away — they're the ones running the Search Match → Exact Harvest → CPP A/B test cycle continuously.
Start simple: one Search Match campaign to collect data. Then gradually add Exact Match groups for proven queries, layer in CPPs aligned to each intent cluster, and use cohort LTV data to concentrate budget on what actually converts. Each cycle tightens your acquisition efficiency and builds a scalable, defensible growth engine for your Rork Max app.