App Store Ads Scraper: Apple Search Ads Library avatar

App Store Ads Scraper: Apple Search Ads Library

Pricing

from $1.25 / 1,000 ads

Go to Apify Store
App Store Ads Scraper: Apple Search Ads Library

App Store Ads Scraper: Apple Search Ads Library

See which apps buy App Store ads against yours: every Apple Search Ads ad shown in the EU in the last year, by app, developer, link, file or country, with slot, days running, creative and targeting flags. Add-ons: advertiser lists with ad counts, Apple's restrictions feed, changed ad alerts.

Pricing

from $1.25 / 1,000 ads

Rating

0.0

(0)

Developer

Automation Craft

Automation Craft

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

App Store Ads Scraper: Apple Search Ads Library

Scrape App Store ads from Apple's public App Store Advertising Repository, the EU ad library of every ad bought through Apple Ads (called Apple Search Ads until April 2025) and shown on the App Store in 25 EU countries over the last year: search results, the Search tab, the Today tab and product pages. Give App Store links, app or developer ids, names, or whole countries, and get one row per ad with the advertised app, the developer and its legal name, the placement, the format, the first and last day shown, the targeting flags, the texts, the screenshots and the videos.

Optional add-ons, each off until you switch it on and each with its own price: Apple's restrictions feed (ads Apple removed and advertiser accounts it suspended, with reason and countries), an advertiser search (one row per app or developer with its ad count, the latest day shown and sample ads, to list who advertises), and changed ads for monitors (a known ad delivered again when Apple reports a later last day shown). You can also give your links as a file, a Google Sheet or a Drive file, and pick your own proxy.

Use it to see which apps advertise against yours, where on the App Store they buy ads, in which countries and for how long, and what creative they show. Every page Apple returns is read to the last one, and each app, developer or country gets a coverage row with Apple's own total next to the ads delivered. A name that matches no app, or several, comes back as a free row listing the candidates with their ids. Each ad is charged once per run.

Quick start

  1. Open the Actor, keep the prefilled input (the name Temu, Germany, 20 ads) and press Start.
  2. Put your competitors into the first fields: App Store links (https://apps.apple.com/de/app/.../id1641486558), app or developer ids, exact names, or a file of links. With none of them, no advertiser search and no restrictions feed, the run browses every App Store ad of the countries you pick.
  3. Pick countries (all 25 when empty), a period (90 days, 180 days or a year), and optional filters: placements, formats, startDate and endDate.
  4. Set maxAds (1,000 when left out), and a memoryName for a scheduled run that should return only new ads.
  5. Optional: an advertiser search (advertiserSearchTerms, for example fitness), the restrictions feed (includeRestrictions), or changed ads for a monitor (redeliverChanged with a memoryName).
  6. Read the dataset: ad rows, advertiser and restriction rows when asked for, one coverage row per app, developer, country or restrictions feed, free status rows, and one summary row with every counter. The "Ads", "Advertisers", "Restrictions" and "Coverage" views show the main columns of each.

What you get

One ad row per App Store ad. Apple's ad id is one ad in one country: an app that ran the same creative in three countries has three rows. Fill rates measured by this Actor on 2026-10-11 on 5,000 ads of France (2,697 apps of 2,185 developers; the first pages Apple returns, which hold the ads shown on its newest day):

FieldWhat it holdsFill
adIdApple's ad id (32 hex characters)100 percent
country, countryNamethe country the ad was shown in100 percent
appId, appName, appStoreUrlthe advertised app, its App Store id (as text) and its App Store page in that country100 percent
developerId, developerName, developerUrlthe developer the ad ran for and its App Store page100 percent
legalNamethe seller's legal name on the App Store100 percent; differs from the developer name on 26.6 percent
placement, placementNameAPPSTORE_SEARCH_RESULTS (96.1 percent), APPSTORE_PRODUCT_PAGE (1.8), APPSTORE_SEARCH_TAB (1.5) or APPSTORE_TODAY_TAB (0.6), and the plain name100 percent
formatIcon Ad or Icon + Asset Ad (72.1 percent carry assets)100 percent
firstShown, lastShown, daysShownfirst and last day Apple recorded an impression (YYYY-MM-DD), and the days between, both counted; the first day can lie before the period100 percent
targeting, targetingUsedwhether the campaign used Apple's age, gender, location and customer type refinements (Apple publishes yes or no, not the values)100 percent; any of them on 13.4 percent (customer type 12.0, age 2.4, gender 1.0, location 0.1)
language, languageName, previewDevicethe default language of the ad and the device Apple previews it on100 percent
iconUrl, category, descriptionthe app icon, its App Store category and the description Apple shows with the ad100 percent
subtitlethe app's subtitle96.8 percent
promotionalTextthe promotional text, when the ad has one31.0 percent
inAppPurchasestrue when the app offers in-app purchases100 percent (true on 78.7)
assets, screenshotCount, videoCount, firstScreenshotUrlthe screenshots and videos in their order, with width, height and orientationat least one image on 99.8 percent; a video on 17.7 percent
colors, editorialBadge, subFormatApple's colour code, the editorial badge flag, and Apple's sub format0.3, 1.0 (true) and 0 percent
variationswith Add variations on: every language version of the ad (app name, subtitle, category, promotional text and, where Apple has them, per device screenshots) and its icon variations, with a statuson request
foundBythe app, developer, name or country that found the ad, and the countries asked100 percent
period, periodStart, periodEndApple's reporting window the ad was read in100 percent

A coverage row per app, developer or browsed country holds appleTotal (Apple's own count of ads for your countries and period), pagesRead, pagesFailed, adsDelivered, adsCharged, the ads skipped as already known (knownSkipped), already delivered (duplicatesSkipped) or filtered out (filteredOut), stopReason, and complete: true only when every page was read to Apple's last and the distinct ads seen equal Apple's total.

Advertiser rows (optional)

With advertiserSearchTerms, every app and developer in Apple's repository whose name starts with your text gets one advertiser row: advertiserType (app or developer), advertiserId, name, appStoreUrl, adsCount (Apple's total of its ads in your countries and period), latestShown (the newest last day shown among its ads), sampleAds (up to three ads: id, country, placement, format, first and last day), countriesAsked, period. Rows with adsCount 0 are free and marked charged: false. On 2026-10-12 the search "fitness" found 35 apps and developers, and Temu's developer had 407 ads in Germany and France over 90 days.

Restriction rows (optional)

With includeRestrictions, every record of Apple's restrictions feed in your period gets one restriction row: action (ACTION_ADVERTISING_REMOVED or ACTION_ACCOUNT_SUSPENDED) and actionName, actionDate, reason, basis, details, firstShown, placements with the countries affected, countries, targeting flags, and a restrictionId (Apple gives none: a hash of the record). Apple's feed names no app, developer or ad. On 2026-10-12 it held 42 removed ads and 6 suspended accounts over 90 days, 196 and 19 over a year. A record is kept when one of its countries is among yours.

Changed ads (optional, for monitors)

With redeliverChanged and a memoryName, an ad the memory delivered before comes back when Apple now reports a later last day shown (the ad kept running): changeStatus: "updated" and previousLastShown, charged as an Ad update instead of an Ad. New ads carry changeStatus: "new".

Free status rows: name_not_found and name_ambiguous (with up to 20 candidate apps and developers, their ids and App Store links), no_ads (an app, developer or country without ads in your scope, or none passing your filters), lookup_failed (Apple did not answer after its retries), invalid (a value that could not be used), skipped (inputs not started because the run stopped), memory_free.

How much does it cost to scrape App Store ads?

You pay per ad delivered, at Apify's Store prices for your plan:

EventFree planBronzeSilverGold
Ad (per 1,000 ads)USD 1.75USD 1.60USD 1.45USD 1.25
Ad variation set (per 1,000, only with Add variations)USD 1.00USD 1.00USD 0.90USD 0.80
Ad update (per 1,000, only with Deliver changed ads again)USD 1.20USD 1.10USD 1.00USD 0.85
Restriction (per 1,000, only with the restrictions feed)USD 2.50USD 2.20USD 1.80USD 1.40
Advertiser (per 1,000, only with an advertiser search)USD 4.50USD 3.80USD 3.10USD 2.50
Actor start (once per run)USD 0.007USD 0.007USD 0.007USD 0.007

Platinum and Diamond plans pay the Gold price. The Actor start fee has no plan discount. The Store pricing card shows these same prices per 1,000 events: "$1.75 / 1,000" on the Ad row means one ad costs USD 0.00175.

Examples on the Free plan: every ad of one developer in one country (194 ads) costs USD 0.007 + 194 x 0.00175 = about USD 0.35; 5,000 ads of a whole country cost about USD 8.76. Ads an earlier input of the same run already delivered, ads your memory knows, rows your filters drop, names without a match, targets without ads and calls Apple did not answer are free. A variation set is charged only when Apple answered the variations call for that ad. A year of the restrictions feed (215 records) costs USD 0.007 + 215 x 0.0025 = about USD 0.55 on the Free plan; an advertiser search that delivers 35 apps and developers with ads costs USD 0.007 + 35 x 0.0045 = about USD 0.16. Advertisers without ads in your scope, restrictions outside your countries or known to your memory, and known ads that did not change are free.

Input

FieldWhat it does
searchTermsApp or developer names, matched through Apple's own name search, which reads names from their first letter. By default only an app or developer named exactly like your text (capitals and spaces aside) is used; otherwise a free row lists the candidates. An App Store link pasted here is read as that app or developer.
appsApp Store app links or app ids (1641486558, id1641486558). Every ad of the app in your countries and period.
developersApp Store developer links or developer ids. Every ad of every app of the developer.
countriesISO codes (DE, de) or country names (Germany, Deutschland) of Apple's 25 countries (no Lithuania, no Malta). All 25 when empty.
periodLAST_90_DAYS, LAST_180_DAYS or LAST_YEAR. When left out, the shortest one that holds your dates (90 days without dates).
startDate, endDateKeep ads that ran on at least one day between them: YYYY-MM-DD, today, yesterday, or 30 days back.
placementssearchResults, searchTab, todayTab, productPage. All when empty.
formatsiconAd, iconAssetAd. Both when empty.
nameMatchexact (when left out) or startsWith: every app and developer whose name begins with your words as whole words.
nameTypesall (when left out), apps or developers.
includeVariationsRead each delivered ad's variations with one extra call per ad (charged as an Ad variation set when Apple answers). Apple's variations call takes 4 to 33 seconds and fails now and then; after about 35 seconds of failed calls in a run (plus 15 for every set charged) no more variations are asked, and the ads are still delivered.
maxAdsTotal cap, 1,000 when left out, up to 1,000,000.
maxAdsPerTargetCap per app, developer or browsed country.
memoryName, resetMemoryCross run memory for scheduled runs: an ad delivered once under a name is never delivered or charged again under it (unless it changed and redeliverChanged is on).
redeliverChangedWith a memory name: deliver a known ad again when Apple reports a later last day shown, charged as an Ad update. Off when left out.
startUrlsFileApp Store links one per line, or ONE link to a public .txt or .csv file, Google Sheet or Google Drive file holding them (up to 2,000 links and 2 MB; pasted links count toward the limits of 1,000 apps and 1,000 developers; a file with more than 2,000 links uses the first 2,000 and says so on a free row; other cells are skipped and counted). Bare ids go into apps or developers.
advertiserSearchTerms, maxAdvertisersAdvertiser search: one row per app or developer whose name starts with your text, with its ad count; at most maxAdvertisers rows with ads (100 when left out). nameTypes limits it to apps or developers.
includeRestrictions, restrictionActionsAdd Apple's restrictions feed; removed, suspended or both when empty. With no app, developer, name, file or advertiser search, the run returns only the feed.
proxyConfigurationLeft out: the Apify datacenter proxy. Your own proxy URLs are used as given; no proxy uses the run's own address, one call at a time; a residential group is mapped to the datacenter group (the summary says so).

Example through the API:

{
"apps": ["https://apps.apple.com/de/app/temu-shop-like-a-billionaire/id1641486558"],
"developers": ["368677371"],
"countries": ["DE", "FR", "IT"],
"placements": ["todayTab", "searchTab"],
"startDate": "30 days",
"maxAds": 5000
}

How names are matched

Apple's name search returns apps and developers whose name starts with the letters you type. "Temu" returns the developer Temu, the app "Temu: Shop Like a Billionaire" and the developer "Temurbek Rakhimov". With the default exact, only the developer Temu is used. With startsWith, the developer Temu and the app are used (both begin with the word Temu), and Temurbek is not. A name that matches nothing, or several apps or developers with exactly that name, gives a free row with the candidates and their ids: put the id you mean into apps or developers.

Countries, pages and speed

An app or developer is read over every country in one query when no country is given, and in groups of five otherwise; a browsed country is read on its own. Apple returns 100 ads per page and the Actor reads three pages at a time through the Apify datacenter proxy. Measured on 2026-10-11: 5,000 ads of France in about 2 minutes; on 2026-10-09 one app's 3,206 ads in all countries took 40 seconds, and a read test of Apple's API from an Apify run with the same three datacenter exits walked all 175,584 ads of Germany's 90 days in 47 minutes with no page lost. The default run timeout is 2 hours: raise it for a run of more than about 200,000 ads.

Filters and the work allowance

Apple's API has no placement, format or date filter, so these filters are applied to every row Apple returns: every page is still read and the rows that do not pass are dropped free. Every request the run sends draws on a work allowance of 26 units (a page or a name search is 1, a variations call 3; names are searched up to three at a time) plus 0.03 for every ad charged and 10 for every variation set charged. A page that brings 34 or more new ads earns more than it costs; a name search and its first page earn their 2 units back from about 67 ads, and the base covers the rest of a list of 20 names that bring about 30 ads each (such a list is read to the end); a long list of names whose apps advertise little, or a run whose pages earn little or nothing (ads a memory already knows, a filter that keeps few rows of a whole country, names nobody has, a failing variations call) stops when it is spent, with a free row naming the inputs it did not start.

An advertiser search spends 1 unit per count call (one call per group of five countries, one for all 25 when none is given) and 1 per page of Apple's name search; each advertiser row charged earns 1.5 units, a restriction row 0.03. A search whose apps and developers mostly have no ads in your countries therefore stops at the allowance (on 2026-10-12 a search for "ma" in Luxembourg counted 31 of its first 100 names, 4 with ads), with a free row naming the apps and developers it did not count: narrow the text or widen the countries.

Monitoring with a memory

With a memoryName, a scheduled run delivers and charges only ads it has not delivered before under that name. Apple sorts its pages by the last day an ad was shown, newest first, so ads that are still running, known or new, share the first pages, and a memory run reads every page of its apps and developers again and skips the known ads free; with the work allowance a memory run reads about 26 pages of ads it already knows (about 2,600 ads) plus one more page for every 33 new ads, which suits apps and developers (a developer with 2,000 ads is 20 pages) far better than whole countries. Split a larger watch list over several memory names. With redeliverChanged, a known ad Apple now shows with a later last day is delivered again as an update (every ad is remembered with its last day shown); ads remembered before this option existed carry no day and are never read as changed. A named memory also remembers the restrictions it delivered, so a scheduled restrictions run returns new records only. Two runs on one memory name at the same time are not supported: the second one delivers its rows free and remembers nothing.

What this Actor does not do

  • It returns what Apple's repository publishes. Apple does not publish the keywords an ad was bought on, bids, spend, impressions, taps, installs or the values of the targeting (only whether age, gender, location and customer type targeting was used).
  • It covers App Store ads only. Apple Ads also sells ads on Apple Maps and in Apple News; Apple's repository holds App Store ads, and none of 2,000 rows checked on 2026-10-11 had another placement.
  • It covers the 25 EU countries of Apple's repository and the last year, with Apple's publishing delay of about 5 to 7 days. No other country and no older ad.
  • Restriction rows name no app, developer or ad: Apple's restrictions feed does not carry them, so a restriction cannot be joined to an ad.
  • Advertiser rows are a snapshot of each run: they are not remembered across runs, so a scheduled advertiser search returns the whole list each time.
  • A changed ad is one whose last day shown moved later; Apple publishes no other change of a running ad (its creative is part of the ad id).
  • A file of links is read from a public address only (no login, no private network), up to 2,000 links and 2 MB.
  • Residential proxies are not used: a residential group is mapped to the datacenter group, which reads Apple's API the same way.

API

Run it and read the ads with curl:

curl -X POST "https://api.apify.com/v2/acts/automation_craft~app-store-ads-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"developers": ["1641486560"], "countries": ["DE"], "maxAds": 100}'

Node.js:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation_craft/app-store-ads-scraper').call({ searchTerms: ['Temu'], countries: ['DE'], maxAds: 100 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter((x) => x.type === 'ad').length);

Python:

from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("automation_craft/app-store-ads-scraper").call(run_input={"apps": ["1641486558"], "maxAds": 100})
ads = [x for x in client.dataset(run["defaultDatasetId"]).iterate_items() if x["type"] == "ad"]

FAQ

Is there a library of App Store ads?

Yes. Under the EU Digital Services Act, Apple publishes its App Store Advertising Repository (adrepository.apple.com), often called the Apple Search Ads repository: every ad Apple delivered on the App Store in 25 EU countries over the last year, searchable by app or developer. This Actor reads it as rows, every page to the end.

How can I see which App Store ads my competitors run?

Put each competitor's App Store link, app id, developer id or exact name into the input and pick the countries. You get every ad Apple recorded for it in the EU repository: placement, format, the days it ran, the targeting flags and the creative, one row per ad and country.

Does it show the keywords competitors bid on in Apple Search Ads?

No. Apple's repository does not publish keywords, bids, spend, impressions or installs, so no row carries them. It shows which app advertised, where on the App Store (search results, Search tab, Today tab, product pages), in which country, on which days, with which creative, and whether age, gender, location or customer type targeting was used.

Which countries does the App Store ad repository cover?

Apple's 25 countries: Austria, Belgium, Bulgaria, Croatia, Cyprus, Czech Republic, Denmark, Estonia, Finland, France, Germany, Greece, Hungary, Ireland, Italy, Latvia, Luxembourg, Netherlands, Poland, Portugal, Romania, Slovakia, Slovenia, Spain and Sweden (no Lithuania, no Malta). Germany alone held 174,354 ads over 90 days on 2026-10-11, all 25 countries 1,866,580.

Can I monitor a competitor and pay only for new ads?

Yes. Give a memoryName and schedule the run: each ad is delivered and charged once under that name, later runs return only ads that are new. Known ads are skipped free; with redeliverChanged a known ad that kept running (a later last day shown) comes back as an update at the Ad update price.

Why does this Actor run with limited permissions?

It runs with the least privileges the platform offers: it can only use its own storages. The cross run memory is a named store the Actor creates itself under your memory name, which works with limited permissions.

More data tools by Automation Craft

Changelog

  • 0.1 (2026-10-13): optional add-ons: Apple's restrictions feed, advertiser rows with ad counts, changed ads for memory monitors, App Store links from a file, Google Sheet or Drive file, and a proxy setting; empty country, placement and format lists mean all.
  • 0.1 (2026-10-11): first version of the App Store Ads listing: apps, developers and names, whole country browse, every page to Apple's last with a coverage row, filters, variations, memory.