ASA API Client
A modern, fully-typed Python client for the Apple Ads APIs with async support and Pydantic models — covering both the new Apple Ads Platform API v1 and the legacy Campaign Management API v5 (sunset January 26, 2027).
Features
- Full Type Safety - Complete type hints with strict mypy compliance
- Async Support - Both sync and async methods in a unified client
- Pydantic Models - Validated request/response models
- Resource-based API - Intuitive
client.campaigns.list()pattern - Automatic Pagination -
iter_all()anditer_all_async()helpers - Reports with Pandas - Optional DataFrame export
Installation
Using uv (recommended):
uv add asa-api-client
Using pip:
pip install asa-api-client
With pandas support:
uv add "asa-api-client[pandas]"
# or
pip install "asa-api-client[pandas]"
Quick Start
from asa_api_client import AppleSearchAdsClient
# From environment variables
client = AppleSearchAdsClient.from_env()
# Or explicit configuration
client = AppleSearchAdsClient(
client_id="SEARCHADS.xxx",
team_id="SEARCHADS.xxx",
key_id="xxx",
org_id=123456,
private_key_path="private-key.pem",
)
# List campaigns
with client:
campaigns = client.campaigns.list()
for campaign in campaigns:
print(f"{campaign.name}: {campaign.status}")
Platform API v1
Apple's new Platform API v1 replaces v5 (which stops working on 2027-01-26). The v1 client ships alongside the v5 client with the same credentials — just add your ad account ID:
from asa_api_client import AppleAdsClient
from asa_api_client.v1 import Query
client = AppleAdsClient.from_env() # reads ASA_* plus ASA_AD_ACCOUNT_ID
with client:
# Flat query-based API with typed filters
enabled = client.campaigns.query(Query().where("status", "EQUALS", "ENABLED"))
# v1-only features
recs = client.recommendations
popularity = client.insights
history = client.change_history
bulk = client.bulk
Don't know your ad account ID? Run the read-only smoke check — it discovers accounts and validates the whole integration against the live API:
asa v1-smoke
See the Platform API v1 guide for the full migration crib and resource reference. Import v1 symbols from the package root (AppleAdsClient) — internal layout may change when v5 is removed.
Environment Variables
export ASA_CLIENT_ID="SEARCHADS.your-client-id"
export ASA_TEAM_ID="SEARCHADS.your-team-id"
export ASA_KEY_ID="your-key-id"
export ASA_ORG_ID="123456"
export ASA_PRIVATE_KEY_PATH="/path/to/private-key.pem"
export ASA_AD_ACCOUNT_ID="123456" # Platform API v1 only
Or use a .env file:
ASA_CLIENT_ID=SEARCHADS.your-client-id
ASA_TEAM_ID=SEARCHADS.your-team-id
ASA_KEY_ID=your-key-id
ASA_ORG_ID=123456
ASA_PRIVATE_KEY_PATH=private-key.pem
ASA_AD_ACCOUNT_ID=123456 # Platform API v1 only
Resources
Campaigns
# List all campaigns
campaigns = client.campaigns.list()
# Get a specific campaign
campaign = client.campaigns.get(campaign_id)
# Find with filters
from asa_api_client.models import Selector
enabled = client.campaigns.find(
Selector().where("status", "==", "ENABLED")
)
# Create a campaign
from asa_api_client.models import CampaignCreate, Money, CampaignSupplySource
campaign = client.campaigns.create(
CampaignCreate(
name="My Campaign",
adam_id=123456789,
countries_or_regions=["US"],
daily_budget_amount=Money(amount="100", currency="USD"),
supply_sources=[CampaignSupplySource.APPSTORE_SEARCH_RESULTS],
)
)
Ad Groups
# Access ad groups through campaign
ad_groups = client.campaigns(campaign_id).ad_groups.list()
# Create an ad group
from asa_api_client.models import AdGroupCreate
ad_group = client.campaigns(campaign_id).ad_groups.create(
AdGroupCreate(
name="My Ad Group",
default_bid_amount=Money(amount="1.00", currency="USD"),
)
)
Keywords
# List keywords in an ad group
keywords = client.campaigns(campaign_id).ad_groups(ad_group_id).keywords.list()
# Create keywords (bulk only)
from asa_api_client.models import KeywordCreate, KeywordMatchType
result = client.campaigns(campaign_id).ad_groups(ad_group_id).keywords.create_bulk([
KeywordCreate(
text="my keyword",
match_type=KeywordMatchType.EXACT,
bid_amount=Money(amount="1.50", currency="USD"),
)
])
Reports
from datetime import date
# Campaign report
report = client.reports.campaigns(
start_date=date(2024, 1, 1),
end_date=date(2024, 1, 31),
)
# Convert to DataFrame (requires pandas)
df = report.to_dataframe()
Async Usage
import asyncio
async def main():
client = AppleSearchAdsClient.from_env()
async with client:
campaigns = await client.campaigns.list_async()
# Async iteration
async for campaign in client.campaigns.iter_all_async():
print(campaign.name)
asyncio.run(main())
CLI
Generate a formatted Excel analysis workbook with the included asa analyze CLI:
pip install "asa-api-client[cli]"
asa analyze --period 90d --output report.xlsx
The workbook includes a summary sheet with KPIs and trends, formatted analysis sheets per reporting level, and raw daily data for pivoting. For details, see the CLI guide.
License
MIT License - Copyright (c) 2025 Peth Pty Ltd
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file asa_api_client-0.4.0.tar.gz.
File metadata
- Download URL: asa_api_client-0.4.0.tar.gz
- Upload date:
- Size: 333.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ffe790c831eec6ef094e479f504969644378eb818d884752db3e8f38f902b32d
|
|
| MD5 |
7e82e88478a45471348d55f8ed8f4d58
|
|
| BLAKE2b-256 |
48cfc2043a6a3a47e90484d5775469fd3e9522a107096928871d8b06fc893fb7
|
Provenance
The following attestation bundles were made for asa_api_client-0.4.0.tar.gz:
Publisher:
publish.yml on SamPetherbridge/asa-api-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
asa_api_client-0.4.0.tar.gz -
Subject digest:
ffe790c831eec6ef094e479f504969644378eb818d884752db3e8f38f902b32d - Sigstore transparency entry: 2495123390
- Sigstore integration time:
-
Permalink:
SamPetherbridge/asa-api-client@aa3ecf7809f5c4eeed5a163c05e3272af17252ad -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/SamPetherbridge
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@aa3ecf7809f5c4eeed5a163c05e3272af17252ad -
Trigger Event:
release
-
Statement type:
File details
Details for the file asa_api_client-0.4.0-py3-none-any.whl.
File metadata
- Download URL: asa_api_client-0.4.0-py3-none-any.whl
- Upload date:
- Size: 203.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
30802cce5207439a7015467deff2266cb28c2300c474ace453932b37fba514ab
|
|
| MD5 |
8719a2ae5db3695fe95938606ad1b72e
|
|
| BLAKE2b-256 |
be36d531fe001cc1cad4056eec521d38000fda054f52a26b54d879e98d09623f
|
Provenance
The following attestation bundles were made for asa_api_client-0.4.0-py3-none-any.whl:
Publisher:
publish.yml on SamPetherbridge/asa-api-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
asa_api_client-0.4.0-py3-none-any.whl -
Subject digest:
30802cce5207439a7015467deff2266cb28c2300c474ace453932b37fba514ab - Sigstore transparency entry: 2495123422
- Sigstore integration time:
-
Permalink:
SamPetherbridge/asa-api-client@aa3ecf7809f5c4eeed5a163c05e3272af17252ad -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/SamPetherbridge
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@aa3ecf7809f5c4eeed5a163c05e3272af17252ad -
Trigger Event:
release
-
Statement type: