How to Export Apple Ads Data to CSV, Power BI, and a Warehouse
Export Apple Ads data by CSV or API, then load spend, taps, impressions, campaigns, and keywords into Power BI, PostgreSQL, Redshift, or another BI tool.

You can export Apple Ads data manually as CSV or automate the export through Apple's Campaign Management API.
CSV is the fastest route for a one-off analysis. The API is the better foundation for Power BI, PostgreSQL, Redshift, Tableau, Qlik, or a recurring internal dashboard.
Apple renamed Apple Search Ads to Apple Ads in 2025. Many product screens, integrations, and search queries still use the old name, but the reporting architecture is the same.
The short answer
Choose the simplest extraction method that matches how often the data must refresh.
| Need | Recommended method | What you maintain |
|---|---|---|
| One-off campaign review | Download a CSV from Apple Ads | A local file and spreadsheet |
| Weekly analyst report | Scheduled API extract to CSV or a database | Authentication, pagination, and refresh jobs |
| Power BI dashboard | API extract to a stable table or JSON endpoint | A small server-side data pipeline |
| PostgreSQL reporting | API extract plus an idempotent upsert | Schema, keys, and late-data refreshes |
| Amazon Redshift reporting | API extract to object storage, then COPY and MERGE | Staging files and warehouse jobs |
| Keyword-level subscription ROAS | Reporting data plus install attribution and revenue events | The join across spend, installs, and subscriptions |
The last row is the important boundary. An Apple Ads export tells you what Apple delivered and spent. It does not, by itself, connect a keyword to a subscriber who paid or renewed later.
What Apple Ads data can you export?
Apple's Campaign Management API exposes reporting at several levels, including campaigns, ad groups, keywords, ads, and search terms. Depending on the endpoint and requested dimensions, the response can include:
- Impressions and taps.
- Spend and currency.
- Installs and redownloads reported by Apple.
- Campaign, ad group, keyword, and ad identifiers.
- Names and status fields for reporting entities.
- Date, country or region, and other available dimensions.
Keep both IDs and names. IDs are the durable join keys. Names are useful labels, but a campaign or ad group can be renamed after historical rows have already been loaded.
Apple's API metrics are aggregate reporting data. For a device-level install attribution flow, use AdServices separately. The Apple Ads API vs AdServices guide explains why most revenue pipelines need both.
Option 1: Download an Apple Ads CSV
For a manual export, create or open the relevant report in the Apple Ads dashboard, choose the date range and reporting level, then download the results as CSV.
Before using the file, record:
- The account and organization.
- The report time zone.
- The selected date range.
- The row level, such as campaign or keyword.
- Any filters applied in the dashboard.
- The currency represented by spend.
This context prevents a common spreadsheet problem: two exports look compatible but were produced with different filters, grains, currencies, or time zones.
CSV works well for an audit, a budget meeting, or an initial Power BI prototype. It becomes fragile when someone must repeat the download every morning or merge files from several accounts.
Option 2: Export with the Apple Ads API
Use the Campaign Management API when the export must run without a person opening the Apple dashboard.
A production extractor has four responsibilities:
- Authenticate with Apple's OAuth 2 flow.
- Request reports at a declared grain and date range.
- Follow pagination until every row is collected.
- Store raw and normalized results so retries are safe.
Apple access tokens expire after one hour, so the job should obtain or refresh a token at runtime. Keep the private key and client credentials in a server-side secret manager, not in a mobile app, spreadsheet, or shared Power BI file.
A campaign-level report request uses the reports endpoint and an organization context header:
curl --request POST \
--url "https://api.searchads.apple.com/api/v5/reports/campaigns" \
--header "Authorization: Bearer ACCESS_TOKEN" \
--header "X-AP-Context: orgId=ORG_ID" \
--header "Content-Type: application/json" \
--data '{
"startTime": "2026-08-01",
"endTime": "2026-08-07",
"granularity": "DAILY",
"selector": {
"pagination": { "offset": 0, "limit": 1000 }
},
"returnRowTotals": false,
"returnGrandTotals": false
}'
Treat this as a shape, not a credential setup guide. The exact selector, filters, grouping, and endpoint should match the report you need. Keyword-level reports use a campaign-specific keyword report endpoint.
Apple currently limits the span of individual reporting requests. Daily requests can cover at most 90 days, while hourly requests have a much shorter window. Split long imports into smaller intervals and preserve a checkpoint for each completed interval.
Apple also recommends retrying rate-limited or temporarily unavailable requests with increasing delays. Make a retry idempotent so it replaces the same logical rows rather than duplicating them.
Design the reporting table before loading data
Choose one grain per table. A useful keyword-day fact table might contain:
| Column | Purpose |
|---|---|
report_date | The date in the selected Apple report time zone |
org_id | Apple Ads organization |
campaign_id | Stable campaign join key |
ad_group_id | Stable ad group join key |
keyword_id | Keyword identifier when available |
keyword_bucket | Named keyword, Search Match, or another explicit fallback |
country_or_region | Geographic reporting dimension |
impressions | Aggregate delivery metric |
taps | Aggregate tap metric |
installs | Apple-reported install metric |
spend_amount | Numeric spend value |
spend_currency | Currency supplied with spend |
source_updated_at | When the source interval was last pulled |
Do not silently convert a missing keyword ID to zero. Search Match and unavailable keyword cases should remain visible buckets, because they have different meanings from a named keyword.
Keep a raw-response table or object-storage copy as well. When Apple changes a field or your transformation has a bug, the raw payload lets you rebuild the normalized table without re-requesting every interval.
Connect Apple Ads to Power BI
Power BI can read CSV files, JSON, web APIs, and databases through Power Query. A direct call from a report file is possible in some configurations, but it is rarely the best production design for Apple Ads.
The safer pattern is:
Apple Ads API -> scheduled server-side extractor -> PostgreSQL, warehouse, or protected JSON/CSV endpoint -> Power BI
This keeps Apple's private key out of the .pbix file and gives one place to handle OAuth, retries, pagination, and schema changes.
For a quick prototype:
- Download the Apple Ads CSV.
- Import it with Power Query.
- Set explicit types for IDs, dates, spend, and currency.
- Create a folder-based query if several exports share the same schema.
- Replace the manual file source with a database or managed endpoint before relying on scheduled refreshes.
Avoid combining IDs as floating-point numbers. Large identifiers can lose precision in BI tools. Load them as text unless arithmetic is genuinely required.
Load Apple Ads data into PostgreSQL
For PostgreSQL, pull the API outside the database, validate the payload, then insert rows under a deterministic key. A simplified daily upsert looks like this:
INSERT INTO apple_ads_keyword_daily (
report_date,
org_id,
campaign_id,
ad_group_id,
keyword_bucket,
country_or_region,
impressions,
taps,
installs,
spend_amount,
spend_currency,
source_updated_at
)
VALUES (...)
ON CONFLICT (
report_date,
org_id,
campaign_id,
ad_group_id,
keyword_bucket,
country_or_region
)
DO UPDATE SET
impressions = EXCLUDED.impressions,
taps = EXCLUDED.taps,
installs = EXCLUDED.installs,
spend_amount = EXCLUDED.spend_amount,
spend_currency = EXCLUDED.spend_currency,
source_updated_at = EXCLUDED.source_updated_at;
The conflict key must match the actual report grain. If you add device class, placement, or another grouping, add it to the key or use a separate table.
Re-pull a rolling window instead of treating yesterday as permanently final. Attribution and reporting totals can settle after the first extract. A seven-day rolling refresh is a practical starting point, but the right interval depends on your reconciliation results.
Load Apple Ads data into Amazon Redshift
For Redshift, a common path is:
- Extract Apple Ads reports into compressed CSV or Parquet files.
- Write them to a date-partitioned object-storage location.
- Use Redshift
COPYto load a staging table. - Validate row counts, null keys, and spend currency.
- Use
MERGEto update the reporting table.
Do not run a row-by-row insert for a large backfill. Bulk loading through COPY is designed for the warehouse use case and is easier to restart by partition.
Keep the source interval in the file path, for example report_date=2026-08-07/. That makes it easier to find, replace, and audit one day without rebuilding the full dataset.
What about Tableau, Qlik, Looker, or a JSON export?
The same architecture applies to other BI tools.
- Tableau, Qlik, and Looker can query the normalized warehouse table.
- A small internal service can expose protected JSON for lightweight tools.
- A scheduled job can write CSV files to managed storage for teams that prefer file imports.
- A transformation layer can create campaign, ad group, and keyword views from the same fact tables.
Choose the serving format after the extraction is reliable. Changing a Power BI model is much easier than recovering missing report intervals or compromised Apple credentials.
Add attribution before calling the result ROAS
Apple Ads reporting supplies the cost side of ROAS. It does not identify every subscriber in your product database.
To calculate keyword-level subscription ROAS, the complete chain is:
| Stage | Source |
|---|---|
| Spend, taps, and impressions | Apple Ads reporting API |
| Attributed install | Apple AdServices or an attribution provider |
| Trial, purchase, renewal, and refund | RevenueCat, Superwall, StoreKit, or your backend |
| Cohort revenue and ROAS | A joined warehouse model or attribution product |
Join with stable IDs and keep acquisition date separate from event date. A renewal recorded today may belong to a keyword that acquired the customer months ago.
The RevenueCat keyword ROAS guide and Superwall subscription attribution guide cover the two common subscription stacks.
A production checklist
Before trusting an automated Apple Ads export, verify:
- OAuth credentials are stored only on the server.
- Access tokens refresh without manual intervention.
- Pagination stops only after all rows are received.
- Report grain is part of the table key.
- IDs are stored without numeric precision loss.
- Currency and report time zone are explicit.
- Search Match is not mislabeled as a broken keyword.
- Recent dates are re-pulled to capture settled totals.
- Raw responses are retained for replay and audit.
- Dashboard totals reconcile to a known Apple Ads report for the same scope.
- Subscription ROAS uses attributed revenue from the same acquisition cohort as spend.
If your real goal is the joined report rather than owning the export pipeline, connect Apple Ads to Postback to combine reporting data with attributed installs and downstream subscription events.
Sources
- Apple Campaign Management API - Current Apple Ads API documentation
- Apple Ads API use cases - Apple's guidance for custom reporting and business intelligence workflows
- Implementing OAuth for the Apple Ads API - Current server authentication flow
- Campaign-level reports - Report endpoint and request behavior
- Keyword-level reports - Keyword report endpoint and metrics
- Microsoft Power Query Web connector - Web, JSON, and API connection behavior in Power Query
- PostgreSQL INSERT - Current
ON CONFLICTupsert syntax - Amazon Redshift COPY and MERGE - Bulk loading and idempotent warehouse updates
FAQ
Yes. You can download reporting data from the Apple Ads dashboard for one-off analysis. Record the report level, filters, date range, time zone, organization, and currency beside the file.
Power BI can call web sources, but a server-side extractor is usually safer for Apple Ads because it keeps the private key out of the report file and centralizes OAuth, pagination, retries, and schema handling.
Yes. Apple provides keyword-level reporting endpoints. Search Match and other cases without a selected keyword must remain separate from named-keyword rows.
Yes. Extract the API on a schedule, store a raw copy, and load a normalized table with deterministic keys. Use an upsert in PostgreSQL or a staging, COPY, and MERGE flow in Redshift.
Not by itself. The export supplies aggregate delivery and spend data. Subscription ROAS also needs AdServices install attribution and trial, purchase, renewal, or refund events joined to the same acquisition cohort.
You might also like
See all posts →
Apple Ads API vs AdServices Attribution
Understand the difference between Apple's Campaign Management API and AdServices, what each returns, and how to combine them for campaign and keyword ROAS.

How to Connect Apple Ads to RevenueCat for Keyword-Level ROAS
Connect Apple Ads attribution and spend to RevenueCat trials, purchases, renewals, and refunds so you can measure subscription revenue and ROAS by keyword.

How to Connect Apple Ads to Superwall for Trial and Purchase Attribution
Connect Apple Ads attribution and spend to Superwall trial, purchase, renewal, and refund webhooks using a stable install identity and signed webhook flow.