Snapchat Ads Library Scraper: EU Ads Gallery
Pricing
from $0.60 / 1,000 ads
Snapchat Ads Library Scraper: EU Ads Gallery
Scrape Snapchat's EU Ads Gallery by advertiser name, EU and Turkey, no login or API key: every page read, a free coverage row per name. Get headline, call to action, media and landing links, impressions per country, age, gender and device targeting. JSON, CSV or API; watch mode bills only new ads.
Pricing
from $0.60 / 1,000 ads
Rating
0.0
(0)
Developer
Automation Craft
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
4 days ago
Last modified
Categories
Share
Snapchat Ads Library Scraper: EU Ads Gallery
Get the Snapchat ads library of any advertiser as clean rows: every commercial ad Snap shows for that name in its EU Ads Gallery, with headline, call to action, media and landing links, start date, impressions in total and per country, and the age, gender, language and device targeting Snap publishes.
Snap keeps the Ads Gallery under the EU Digital Services Act: commercial ads that delivered in the 27 EU countries and Turkey in the last 12 months. This Actor searches it by advertiser name, follows every page of Snap's list until the list ends, and writes one row per ad plus one free coverage row per name. No login, no API key and no proxy settings are needed from you.
- Several advertisers per run: up to 200 names, each read on its own.
- Every page of Snap's list is read: the run follows each next page until Snap sends none, and the coverage row of the name says whether the end of the list was reached.
- Each ad is delivered and charged once per run, whatever Snap's list repeats.
- Exact name match next to Snap's own "contains" match, and the paying advertiser names Snap returned for each name, so you can pick the exact one.
- Watch mode delivers and charges only ads a watch name has not delivered before.
- Turkey (TR) next to the 27 EU countries, with impressions for all 28 countries on every row.
- A name without ads is a free row, and so is a call Snap refuses: the coverage row says
rationedorpartial, never "no ads".
This is an independent tool, not affiliated with, endorsed by or sponsored by Snap Inc. "Snapchat" and "Snap" name the data source only.
Quick start
- Enter one or more advertiser names, one per line (the prefill is
Nike). Snap's search takes the name of the paying advertiser. - Optional: countries as two letter codes in any case or English names (
DE,tr,Germany); the prefill isDE. - Optional filters: name match (
containsorexact), ad status, a delivery window, a start date window, media types and minimum impressions. - Set maximum ads (the prefill is 20; 100 when the field is left out) and, if you like, a cap per advertiser name. Run, then export the dataset as JSON, CSV or Excel, or read it through the API.
- To receive only new ads on a schedule, give a watch name such as
nike-de-weeklyand schedule the run.
What you get
Each run writes three kinds of rows to the dataset, told apart by the field type: ad (one per ad, charged), coverage (one per advertiser name, free) and status and summary rows (free).
Ad row
| Field | What it holds | Fill rate |
|---|---|---|
adId, adUrl | Snap's ad id and a link to the ad in the gallery | 100 % |
payingAdvertiserName | the paying advertiser, as Snap names it | 93.7 % |
profileName, profileLogoUrl | the public Snapchat profile that ran the ad | 85.3 %, 85.1 % |
adAccountName, adName | the ad account and the ad's own name | 100 % |
brandName | the brand name, where Snap gives one | 23.9 % |
headline, callToAction | the ad's headline and its button text | 99.1 %, 100 % |
status, reviewStatus, rejectionReasons | ACTIVE or PAUSED, Snap's review state and reasons | 100 %, 100 %, 4.6 % |
adType, creativeType, renderType | the kind of ad (web view, app install, story, collection, lens) | 100 % |
mediaType, mediaUrl, mediaUrls | the main creative's type and direct CDN links to the media files | 94.5 %; mediaUrl 73.6 % from the top Snap |
landingUrl, landingDomain | the landing page and its domain | 68.4 % |
startDate | the day the ad started (ISO 8601) | 100 % |
impressionsTotal, impressionsByCountry, countries, topCountry | impressions in total and for each of the 28 countries | 100 % |
languages | the ad's languages | 79.9 % |
targetMinAge, targetMaxAge | the targeted age range | 98.0 %, 28.2 % |
targetGenders | the targeted genders | 45.7 % |
targetOs | the targeted device systems | 48.0 % |
targetLanguages, targeting | targeted languages, and Snap's whole targeting block | |
productCount, products | catalogue products: the real count and up to 20 per row | 15.5 % |
storySnaps, collectionItems | the Snaps of a story ad and the tiles of a collection ad | 6.0 % (story) |
appName, iosAppId, androidAppId | app install ads | 8.0 %, 7.2 %, 5.7 % |
deepLinkUri | deep link ads | 1.7 % |
searchedAdvertiser, nameMatchedIn | the name you gave and the fields of the ad that hold it | 100 % |
raw | Snap's record exactly as its API returned it (only with Include Snap's raw record) |
Fill rates were measured on 2026-10-06 over 348 distinct ads (22 pages of a broad query in Germany, 9 pages of Nike without a country, filter probes). Snap does not publish an end date, spend, targeting below the country or interest targeting in the Ads Gallery, so no row carries them.
A real ad row (run of 2026-10-06; the impressionsByCountry object is cut to three of its 28 countries, every other country of this ad was 0):
{"type": "ad","adId": "015db1b8-0fd5-424c-81d6-b2206bd38d6d","adUrl": "https://adsgallery.snap.com/?adId=015db1b8-0fd5-424c-81d6-b2206bd38d6d","searchedAdvertiser": "Sephora","nameMatchedIn": ["payingAdvertiserName", "profileName", "adAccountName"],"payingAdvertiserName": "SephoraTR","brandName": null,"profileName": "Sephora Türkiye","adAccountName": "Sephora","adName": "ad 02","headline": "Yeni Yıl Hediye Fikirleri","callToAction": "SHOP NOW","status": "ACTIVE","reviewStatus": "APPROVED","adType": "REMOTE_WEBPAGE","creativeType": "WEB_VIEW","renderType": "STATIC","mediaType": "VIDEO","landingUrl": "https://www.sephora.com.tr/yilbasi/","landingDomain": "sephora.com.tr","startDate": "2025-12-24T21:00:00.000Z","impressionsTotal": 49760,"impressionsByCountry": { "DE": 0, "FR": 0, "TR": 49760 },"countries": ["TR"],"topCountry": "TR","languages": ["tr"],"targetMinAge": 18,"targetMaxAge": null,"targetGenders": ["FEMALE"],"targetLanguages": [],"targetOs": [],"productCount": 0,"products": [],"storySnaps": [],"scrapedAt": "2026-10-06T17:54:41.799Z"}
The row above also carries profileLogoUrl, mediaUrl, mediaUrls, rejectionReasons, regulatedContent, targeting, collectionItems, the app fields and lensIconUrl; they are left out here for length only.
Coverage row (free, one per advertiser name)
The coverage row tells you what was read for each name and what was not. A real one from the same run:
{"type": "coverage","advertiser": "Lego","advertiserKey": "lego","status": "complete","complete": true,"endOfListReached": true,"message": "Every page of Snap's list for this name was read: 23 ad(s), 23 matched, 23 delivered.","pagesRead": 3,"pagesRefused": 0,"adsRead": 23,"adsMatched": 23,"adsDelivered": 23,"adsDeliveredBefore": 0,"adsAlreadyInThisRun": 0,"adsNotMatchingName": 0,"adsFilteredOut": 0,"adsRepeatedBySource": 0,"adsNotDelivered": 0,"entriesNotRead": 0,"tooManyRequestsAnswers": 1,"secondsWaited": 6,"stoppedBy": null,"payingAdvertiserNames": [{ "payingAdvertiserName": "LEGO", "ads": 17 },{ "payingAdvertiserName": "M. Gallego", "ads": 6 }],"payingAdvertiserNamesTotal": 2,"searched": { "nameMatch": "contains", "countries": ["DE", "TR", "DK"], "status": "all", "startDate": null, "endDate": null },"scrapedAt": "2026-10-06T17:54:21.817Z"}
The main values of status in a coverage row:
complete: every page of Snap's list for the name was read.no_ads: Snap answered with an empty list for this name and these settings.partial: some pages were read and the run stopped before the end, for example at your cap or because Snap kept refusing calls;stoppedBynames the reason.rationed: Snap refused the calls and nothing was read. That is not an empty result, and nothing is charged for it.not_read: the run ended before this name was asked.refused_by_sourceandfailed: Snap refused the request itself or gave no usable answer; themessagefield carries the reason.
payingAdvertiserNames lists the paying advertiser names Snap returned for your text (up to 20) with the number of ads of each. In the row above, "Lego" also matched "M. Gallego": run again with name match set to exact and the name LEGO to keep only the brand's own ads. A brand that buys through an agency or a holding appears under the paying advertiser's name, so this list is where you find the exact one.
A summary row at the end counts pages, ads read, matched and delivered, calls Snap refused, waits and charges for the whole run.
Watch mode: only new ads
Give a watch name (monitorName) and schedule the run. Each ad is delivered and charged once per watch name: later runs skip the ads this watch already delivered and the coverage row counts them in adsDeliveredBefore. Snap's list is not ordered by date, so every run reads the whole list of each name and keeps only ads that are new to the watch. A run that finds nothing new pays the start fee only. Use a new watch name when you change the names or the filters.
Keep a watch's list short enough to be read in one run: a run that bills nothing reads for about two minutes, which is about 20 pages or 200 ads. Set ad status to active and give the countries you care about: measured on 2026-10-06, Nike in Germany had 59 active ads (6 pages). An advertiser with a list of several hundred ads in one country (Zalando in Germany had more than 400, active and paused together) is not read to its end by a run that finds nothing new; its coverage row then says partial, and the next run starts again from the first page.
Speed
Snap rations its Ads Gallery API for all callers together, in windows of about five seconds. This Actor asks one page of ten ads at a time, about every six seconds, and waits a refusal out with pauses of varied length. Measured on 2026-10-06: about 90 ads a minute when no call is refused (300 ads in 202 seconds), and 30 to 40 ads a minute in runs on the platform while other callers were active (300 ads in 494 seconds). The default run timeout of one hour is enough for about 2,000 ads at that slower rate; raise it for more.
A run works for up to two minutes plus six seconds for every ad it bills. A run that keeps delivering ads stays far inside that time. A run that reads without billing (a name without ads, an exact name or filters that few ads pass, a watch with nothing new, calls Snap keeps refusing) stops when the time is used up and says in its coverage and status rows what was not read. Nothing is charged for what was not read.
Media links are Snap's CDN links: 30 of 30 answered without a login in the test of 2026-10-06, and 1 of 15 links saved a day earlier had expired. Download the files you need soon after the run.
How much does it cost to scrape Snapchat ads?
You pay per Ad row delivered plus a small start fee per run. Coverage rows, status rows, the summary, names without ads, calls Snap refuses and ads that do not match your name or filters are free. Nothing else is charged.
| Event | FREE | BRONZE | SILVER | GOLD |
|---|---|---|---|---|
Ad (ad, one ad delivered as a row) | $1.00 / 1,000 | $0.80 / 1,000 | $0.72 / 1,000 | $0.60 / 1,000 |
Actor start (apify-actor-start, once per run) | $0.01 | $0.01 | $0.01 | $0.01 |
Platinum and Diamond plans pay the Gold price. The Actor start event is a flat fee with no tier discount, charged once per run (this Actor runs at 256 MB). It covers starting the run and up to two minutes of reading that ends without a new ad: a name without ads, a watch run that finds nothing new, waiting out calls Snap refuses.
Worked examples (start fee included):
| Run | FREE | BRONZE | SILVER | GOLD |
|---|---|---|---|---|
| A name without ads, or a watch run with nothing new | $0.01 | $0.01 | $0.01 | $0.01 |
| 20 ads (the prefill) | $0.03 | $0.026 | $0.0244 | $0.022 |
| 1,000 ads | $1.01 | $0.81 | $0.73 | $0.61 |
Each total is the start fee plus the number of ads times the tier's price per ad: 20 ads on Free cost $0.01 + 20 x $0.001 = $0.03, and 1,000 ads on Gold cost $0.01 + 1,000 x $0.0006 = $0.61.
Input
| Field | Type | What it does |
|---|---|---|
advertisers | array of strings | Advertiser names, one per line, up to 200 per run. Snap matches every paying advertiser whose name contains your text, in any case. |
nameMatch | contains or exact | contains (default) keeps every ad Snap returns for the name; exact keeps only ads whose paying advertiser name is exactly your text, case and extra spaces ignored. |
countries | array of strings | Only ads with impressions in at least one of these countries: AT, BE, BG, HR, CY, CZ, DK, EE, FI, FR, DE, GR, HU, IE, IT, LV, LT, LU, MT, NL, PL, PT, RO, SK, SI, ES, SE, TR. Codes in any case or English names. |
status | all, active or paused | Ad status as Snap reports it (default all). |
startDate, endDate | YYYY-MM-DD | Snap's own delivery window: ads that delivered impressions inside it, including ads that started earlier and were still running. A start without an end means until now. Empty means the whole 12 months. A day in the future is not accepted. |
startedFrom, startedTo | YYYY-MM-DD | Only ads whose start date falls in this window (UTC). |
mediaTypes | array: video, image, dynamic, lens | Only ads whose main creative is of these kinds (dynamic is a product catalogue ad). |
minImpressions | integer | Only ads with at least this many impressions in total. |
maxItems | integer | The most Ad rows this run may deliver and charge, over all names (100 when left out). |
maxItemsPerAdvertiser | integer | The most Ad rows per name. Empty means no cap per name. |
monitorName | string | The watch name: deliver and charge each ad once per watch name. |
includeRaw | boolean | Adds raw, Snap's record as returned, to every ad row. The price stays the same. |
For API callers the Actor also accepts these key names: advertiser, advertiserName, advertiserNames, payingAdvertiserName, search and searchTerms for advertisers; country for countries; dateFrom and dateTo for startDate and endDate; maxResults, maxAds, limit and resultsLimit for maxItems; maxAdsPerAdvertiser for maxItemsPerAdvertiser; watchName for monitorName. Input it cannot use is reported in a free status row.
API examples
curl
curl -X POST "https://api.apify.com/v2/acts/automation_craft~snapchat-ads-library-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"advertisers": ["Nike"], "countries": ["DE"], "maxItems": 20}'
Node.js (apify-client)
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('automation_craft/snapchat-ads-library-scraper').call({advertisers: ['Zalando SE', 'Sephora'],countries: ['DE', 'TR'],maxItems: 200,});const { items } = await client.dataset(run.defaultDatasetId).listItems();const ads = items.filter((row) => row.type === 'ad');const coverage = items.filter((row) => row.type === 'coverage');console.log(ads.length, coverage.map((c) => `${c.advertiser}: ${c.status}`));
Python (apify-client)
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("automation_craft/snapchat-ads-library-scraper").call(run_input={"advertisers": ["LEGO"],"nameMatch": "exact","monitorName": "lego-weekly","maxItems": 500,})for row in client.dataset(run["defaultDatasetId"]).iterate_items():if row["type"] == "ad":print(row["adId"], row["headline"], row["impressionsTotal"])
What this Actor does not do
- No ads outside the EU and Turkey (no US or UK ads), and no ads older than 12 months: the Ads Gallery covers the 27 EU countries and Turkey for the last 12 months only.
- No spend, no end date, no interest targeting and no targeting below the country: Snap does not publish them in the Ads Gallery.
- No search by a keyword in the ad text and no browsing without an advertiser name: Snap's search takes the paying advertiser's name.
- No lookup of single ads by id in this version: Snap rations that call like a search and it returns one ad per call.
- No sponsored creator content: Snap keeps it in a separate archive.
- No political ads: they are in Snap's Political Ads Library, read by Snapchat Political Ads Scraper: Spend & Targeting.
- It does not download media files: it delivers the links.
- In watch mode it does not deliver an ad again because its impressions changed: the watch is about new ads.
FAQ
How can I see competitor ads on Snapchat?
Enter the competitor's paying advertiser name in advertisers: the run returns every ad Snap's EU Ads Gallery shows for that name, with headline, media and landing links, impressions per country and targeting. The coverage row lists the paying advertiser names Snap found, so you can switch to an exact match.
Which countries does the Snapchat Ads Library cover?
The Ads Gallery holds commercial ads that delivered in the 27 EU countries and Turkey in the last 12 months, kept for the EU Digital Services Act. Every ad row carries impressions for all 28 countries.
Why does a search for a brand return no ads?
Snap's search takes the name of the paying advertiser, which for a brand that buys through an agency or a holding is not the brand's own name; try the names in payingAdvertiserNames of a broader search. A brand that did not advertise in the EU or Turkey in the last 12 months has no ads in the gallery. A name without ads is a free no_ads coverage row; a call Snap refused is marked rationed or partial, never "no ads".
Does Snapchat have an ads API?
Snap offers a public Ads Gallery API without a key, and this Actor reads it for you: no login, no API key and no proxy settings are needed. Snap rations that API for all callers together, so the Actor paces itself at about one page every six seconds.
Does this Actor return Snapchat political ads?
No. Political ads are in Snap's Political Ads Library, a separate archive read by Snapchat Political Ads Scraper: Spend & Targeting.
Why does this Actor run with limited permissions?
It runs with Apify's limited permissions, the least privilege level: it reads its input and writes only its own run's storages. The one exception is watch mode: when you give a watch name, it opens a named key-value store it creates itself (snap-gallery-watch-v1-...) to remember which ads it delivered. It touches nothing else in your account.
Changelog
See CHANGELOG.md. 0.1 (2026-10-06): first release.
More data tools by Automation Craft
Same family: Snapchat Political Ads Scraper: Spend & Targeting.
Ad libraries: Meta Ad Library Scraper - All Placements, Filters, Facebook Ads Library Scraper - Page Ads, No Login, Instagram Ads Library Scraper - Creatives, Video, TikTok Ads Library Scraper: EU Ads, No Login, TikTok Creative Center Scraper: Top Ads, No Login, Pinterest Ads Library Scraper - EU Ads Repository, Google Ads Transparency Scraper - Decoded Creatives, Google Ads Library Scraper - Competitor Ads, No Login, YouTube Ads Scraper - Video Ads by Advertiser, LinkedIn Ad Library Scraper: Ads by Company.
Other data: Google Trends Scraper - Compare and Trending Now, Trustpilot Reviews Scraper: Coverage Per Company, G2 Reviews Scraper: Ratings, Pros and Cons, Substack Scraper: Posts, Notes and Profiles, Airbnb Scraper: Prices, Calendar, Reviews.