Apple Search Ads
Create, optimize, and scale Apple Search Ads campaigns with API automation, attribution integration, and bid strategy recommendations.
安装 / 下载方式
TotalClaw CLI推荐
totalclaw skills install shop:github:LeoYeAI~openclaw-master-skills~apple-search-adscURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/github%3ALeoYeAI~openclaw-master-skills~apple-search-ads/file -o apple-search-ads.md# Apple Search Ads 🍎
Complete toolkit for Apple Search Ads: Campaign Management API v5, attribution integration (AdServices + SKAdNetwork), bid optimization, and strategic recommendations.
## What's New in v1.0.0
- Full Campaign Management API v5 coverage
- iOS app integration (AdServices framework)
- SKAdNetwork 4.0 support
- Automated reporting scripts
- Bid optimization strategies
- Multi-country campaign patterns
## Contents
1. [Setup](#setup)
2. [When to Use](#when-to-use)
3. [Architecture](#architecture)
4. [API Essentials](#api-essentials)
5. [Campaign Structure](#campaign-structure)
6. [Keywords & Bidding](#keywords--bidding)
7. [Attribution Integration](#attribution-integration)
8. [Reports & Analytics](#reports--analytics)
9. [Strategy Playbook](#strategy-playbook)
10. [Scripts & Automation](#scripts--automation)
11. [Common Traps](#common-traps)
## Setup
On first use, read `setup.md` for integration guidelines.
## When to Use
User needs to run Apple Search Ads for iOS apps. Agent handles campaign creation, bid optimization, attribution tracking, performance analysis, and strategic recommendations.
## Architecture
Memory lives in `~/apple-search-ads/`. See `memory-template.md` for structure.
```
~/apple-search-ads/
├── memory.md # Active campaigns, preferences, learnings
├── credentials.md # OAuth config (NEVER commit real secrets)
├── campaigns/ # Campaign-specific notes and performance
│ └── {app-id}/
├── reports/ # Generated reports
└── scripts/ # Custom automation
```
## Quick Reference
| Topic | File |
|-------|------|
| Setup process | `setup.md` |
| Memory template | `memory-template.md` |
| API endpoints | `api-reference.md` |
| iOS integration | `ios-integration.md` |
| Strategy guide | `strategy.md` |
| Script library | `scripts.md` |
## API Essentials
### Authentication (OAuth 2.0)
Apple Ads API uses OAuth with client credentials. Generate credentials at:
https://app.searchads.apple.com/cm/app/settings/apicertificates
```bash
# 1. Generate client secret (JWT signed with private key)
# Header
{
"alg": "ES256",
"kid": "{KEY_ID}"
}
# Payload
{
"sub": "{CLIENT_ID}",
"aud": "https://appleid.apple.com",
"iat": {CURRENT_TIMESTAMP},
"exp": {TIMESTAMP_+180_DAYS},
"iss": "{TEAM_ID}"
}
# 2. Exchange for access token
curl -X POST "https://appleid.apple.com/auth/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id={CLIENT_ID}" \
-d "client_secret={CLIENT_SECRET}" \
-d "scope=searchadsorg"
# Response contains access_token (valid 1 hour)
```
### Base URL & Headers
```
Base URL: https://api.searchads.apple.com/api/v5
Headers:
Authorization: Bearer {ACCESS_TOKEN}
X-AP-Context: orgId={ORG_ID}
Content-Type: application/json
```
### Core Endpoints
| Resource | Method | Endpoint |
|----------|--------|----------|
| **Apps** | | |
| Search apps | POST | `/search/apps` |
| App eligibility | GET | `/apps/{adamId}/eligibilities` |
| **Campaigns** | | |
| List campaigns | GET | `/campaigns` |
| Create campaign | POST | `/campaigns` |
| Update campaign | PUT | `/campaigns/{id}` |
| Delete campaign | DELETE | `/campaigns/{id}` |
| **Ad Groups** | | |
| List ad groups | GET | `/campaigns/{id}/adgroups` |
| Create ad group | POST | `/campaigns/{id}/adgroups` |
| **Keywords** | | |
| List keywords | GET | `/campaigns/{cId}/adgroups/{agId}/targetingkeywords` |
| Add keywords | POST | `/campaigns/{cId}/adgroups/{agId}/targetingkeywords/bulk` |
| **Reports** | | |
| Campaign report | POST | `/reports/campaigns` |
| Ad group report | POST | `/reports/campaigns/{id}/adgroups` |
| Keyword report | POST | `/reports/campaigns/{cId}/adgroups/{agId}/keywords` |
| Search term report | POST | `/reports/campaigns/{cId}/searchterms` |
| Impression share | POST | `/reports/campaigns/{id}/impressionshare` |
## Campaign Structure
### Hierarchy
```
Organization (orgId)
└── Campaign (Search Results / Search Tab / Today Tab)
├── Budget & Schedule
├── Countries/Regions
└── Ad Groups
├── Keywords (targeting + negative)
├── Audience (age, gender, device, etc.)
├── Creatives (default or Custom Product Pages)
└── Bid settings
```
### Campaign Types
| Type | Placement | Best For |
|------|-----------|----------|
| **Search Results** | Top of search results | High-intent users, brand defense |
| **Search Tab** | Suggested apps before search | Discovery, broad reach |
| **Today Tab** | Today tab featured | Brand awareness, launches |
### Campaign Object
```json
{
"name": "MyApp - US - Brand",
"adamId": 123456789,
"countriesOrRegions": ["US"],
"budgetAmount": {"amount": "1000", "currency": "USD"},
"dailyBudgetAmount": {"amount": "50", "currency": "USD"},
"supplySources": ["APPSTORE_SEARCH_RESULTS"],
"billingEvent": "TAPS",
"status": "ENABLED",
"startTime": "2026-01-01T00:00:00.000",
"endTime": null
}
```
### Ad Group Object
```json
{
"name": "Brand Keywords",
"campaignId": 123456,
"defaultBidAmount": {"amount": "1.50", "currency": "USD"},
"cpaGoal": {"amount": "5.00", "currency": "USD"},
"startTime": "2026-01-01T00:00:00.000",
"targetingDimensions": {
"age": {"included": [{"minAge": 18}]},
"gender": {"included": ["M", "F"]},
"deviceClass": {"included": ["IPHONE", "IPAD"]},
"daypart": {"userTime": {"included": [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23]}},
"adminArea": null,
"locality": null,
"appDownloaders": {"included": [], "excluded": []}
},
"automatedKeywordsOptIn": false,
"status": "ENABLED"
}
```
## Keywords & Bidding
### Match Types
| Type | Behavior | Use Case |
|------|----------|----------|
| **Exact** | Query = keyword exactly | Brand terms, proven converters |
| **Broad** | Synonyms, related terms | Discovery, expansion |
| **Search Match** | Auto-matched by Apple | New apps, keyword research |
### Keyword Object
```json
{
"text": "meditation app",
"matchType": "EXACT",
"bidAmount": {"amount": "2.00", "currency": "USD"},
"status": "ACTIVE"
}
```
### Bid Strategy Rules
1. **Brand keywords** → Bid high (defend your brand)
2. **Competitor keywords** → Test carefully, monitor CPA
3. **Generic keywords** → Start low, increase for winners
4. **Discovery (Search Match)** → Low bids, mine for keywords
5. **Negative keywords** → Essential to reduce waste
### Bid Optimization Loop
```
Week 1: Set baseline bids (industry avg or $1-2)
↓
Week 2: Review search term report
- High converts, low bid → raise bid 20-30%
- Low converts, high spend → lower bid or pause
- Irrelevant terms → add as negative
↓
Week 3+: Repeat. Target CPA within 20% of goal.
```
## Attribution Integration
### AdServices Framework (iOS 14.3+)
Modern attribution without user tracking. Integrates directly in iOS app.
```swift
import AdServices
func trackAttribution() async {
do {
// 1. Get attribution token from device
let token = try AAAttribution.attributionToken()
// 2. Send to Apple's attribution API
var request = URLRequest(url: URL(string: "https://api-adservices.apple.com/api/v1/")!)
request.httpMethod = "POST"
request.setValue("text/plain", forHTTPHeaderField: "Content-Type")
request.httpBody = token.data(using: .utf8)
let (data, _) = try await URLSession.shared.data(for: request)
let attribution = try JSONDecoder().decode(Attribution.self, from: data)
// 3. attribution contains: campaignId, adGroupId, keywordId, etc.
// Send to your analytics backend
} catch {
// Not from Apple Search Ads or error
}
}
struct Attribution: Codable {
let attribution: Bool
let orgId: Int?
let campaignId: Int?
let adGroupId: Int?
let keywordId: Int?
let creativeSetId: Int?
let conversionType: String?