Zalando Ads Library Scraper - Sponsored Products avatar

Zalando Ads Library Scraper - Sponsored Products

Pricing

from $0.60 / 1,000 ads

Go to Apify Store
Zalando Ads Library Scraper - Sponsored Products

Zalando Ads Library Scraper - Sponsored Products

Scrape the Zalando Ads Library, the public EU ad repository of every sponsored product on Zalando, by search term, sponsor or ad id. One row per distinct ad, charged once: sponsor, product title in up to 44 languages, image, period, 26 markets, reach, targeting. JSON, CSV, API.

Pricing

from $0.60 / 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

5 days ago

Last modified

Share

Zalando Ads Library Scraper - Sponsored Products

Scrape the Zalando Ads Library, the public EU ad repository (Digital Services Act) of every sponsored product shown on Zalando's shops: about 19 million ads, 26 markets, product titles in up to 44 languages. Search by term, by sponsor (the legal entity that paid) or by ad id, filter by market and period, and get one row per distinct ad with the sponsor, the product, the image, the days it ran, the markets, the reach and the targeting. Each ad is charged once; every miss is a free row.

The archive's own search box times out on words with no ad and on rare words (its 30 second limit). This Actor answers both in seconds through a second query shape, lists a rare brand completely, and tells you in a free row when even that fails.

Quick start

  1. Open the Actor, keep the prefilled input (searchTerms: ["nike"], 20 ads) and press Start, or give your own search terms, sponsor names or ad ids.
  2. Narrow the search with markets (DE, FR, NL, PL, ...), a period (startDate, endDate, or activeOnly for ads running now) and the languages you want the product title in.
  3. Set maxAds (100 when left out), and memoryName for a scheduled run that should deliver only new ads.
  4. Read the dataset: ad rows, one coverage row per search, free status rows for misses, one summary row with every counter.

What you get

One ad row per distinct ad (fill rates measured on 2026-10-08 on the archive's first 2,000 ads in id order, a random sample since the ids are random hex, 1,000 of them with every field):

FieldWhat it holdsFill
adId, adUrlthe archive's 32 character id and the archive page opened on it100 percent
sponsorthe legal entity that paid, as the archive names it (NIKE Retail B.V., Falke KGaA, Next Germany GmbH)100 percent (475 distinct in 2,000 ads)
title, titleLanguagethe product title in the first of your languages the ad has (English when none is given)100 percent; English on 98.8, German on 98.3
text, textLanguage, textEqualsTitlethe ad text in the same language (equal to the title on 93.5 percent of ads)99.7 percent
titles, textswith languages: ["all"]: every translation as an object, up to 44 languages per ad (most ads carry 23 to 25, about 2 percent only one)on request
languagesAvailablehow many languages the archive carries the title in100 percent
imagethe product image the ad shows (img01.ztat.net, jpg or png)100 percent
periodStart, periodEnd, periodEndRawthe first and the last day shown (the archive stores the day after the last day as an exclusive bound: that raw value is periodEndRaw)100 percent
daysShown, daysSinceEnd, isActivedays from the first to the last day; days since the last day; true when the last day lies within two days of the run day (the archive publishes with a lag of a day or two)100 percent; about 7 percent of ads run now
markets, marketNames, marketCountthe markets the ad was shown in, codes and names (one or several of 26; 43 percent of ads run in more than one)100 percent
reachrecipients (total) as the archive counts them (median 246, 90th percentile 5,124, up to 1.3 million)100 percent
targetingParameters, targetingLabelsthe archive's targeting parameters (contextual, personal, browsing_purchase, category_interest, demographic, device, geography, account, search) and the archive page's own words for them100 percent (contextual on every ad, personal on nearly every ad)
visibilityIdthe archive's visibility information id; the ads of one booking share it (12.5 percent of ads share theirs)100 percent
matchedInwhere every word of your search text appears literally on the ad: sponsor, title, text (empty when only the archive's stemmed search matched it)on search rows
source, search, scrapedAthow the row was found (search, sponsor, ad_id, sample), the search that found it, the read time100 percent

A coverage row per search: the archive's total when counted, the query shape used (mode), pages and rows read, candidates, ads delivered and charged, ads a memory or an earlier search already held, rows dropped by the sponsor check or the exact words option, archive timeouts, the stop reason, complete, seconds. Free status rows: no_result, archive_timeout, sponsor_not_found, ad_not_found, invalid, lookup_failed, skipped, memory_free. A summary row last, always, with the counters, the requests by kind, the exit country and what was charged.

How much does it cost to scrape the Zalando Ads Library?

EventFREEBRONZESILVERGOLD
Ad (one distinct ad delivered)$0.80 per 1,000$0.80 per 1,000$0.70 per 1,000$0.60 per 1,000
Actor start (once per run, per GB of memory; a 256 MB run pays one)$0.01$0.01$0.01$0.01

Platinum and Diamond plans pay the Gold price. The Store pricing card shows these same prices per 1,000 events: "$0.80 / 1,000" on the Ad row means one ad costs 0.08 cents. Example: 1,000 ads of one brand cost $0.81 at Bronze (1,000 ads plus the start); a scheduled run that finds 3 new ads costs $0.0124.

Free: a search with no result, a search the archive could not answer inside its 30 second limit, an ad id the archive does not have, a sponsor name no ad carries, a count, every page read, a repeated ad, an ad an earlier search of the run delivered, an ad a named memory already knows, a row the sponsor check or exactWords dropped, coverage rows, status rows, the summary. A run whose named memory cannot be opened, or that the platform restarted, delivers the rest free and says so; a memory that stops saving in the middle of a run frees the ads from that batch on, and the summary names the reason. The start fee of a run stands in every case.

Unpaid work is bounded: a run spends at most 120 seconds plus 1.5 seconds per ad charged on calls that end without a charge (absent words, unknown ids, sponsors no ad carries, counts, failed calls); past that the remaining inputs are listed in one free skipped row. A word with no ad costs about 4 seconds, so a list of twenty unknown brands is answered in full.

Input

FieldMeaning
searchTermsOne search text per line. The archive's search covers the product title, the ad text and the sponsor name in every language: whole words, every word must match, English stemming, and a word starting with your text matches too (the archive's own box wraps the text in stars; so does the Actor, unless your text carries an operator: "nike air" for a phrase, nike | adidas for either, - or ! for not). Up to 200 per run.
sponsorsOne sponsor per line: a brand word (nike) or the legal entity (NIKE Retail B.V.). The name is searched and only ads whose sponsor holds every word of it (whole words, capitals aside) are delivered; the rest of the pages read is dropped free. Up to 200.
adIdsAd ids (32 characters) or archive URLs, one per line, looked up 100 at a time; an id the archive does not have is a free row. Up to 5,000.
marketsKeep ads shown in at least one of these markets: AT, BE, HR, CZ, DK, EE, FI, FR, DE, HU, IE, IT, LV, LT, LU, NL, NO, PL, PT, RO, SK, SI, ES, SE, CH, GB (country names work too). Every market when left out.
startDate, endDateThe window the ad ran in (at least one day of it): YYYY-MM-DD, a month as YYYY-MM, today, yesterday, or 30 days back from the end. Open ended when left out.
activeOnlyOnly ads running now: ads whose period reaches the archive's latest day (it publishes with a lag of a day or two).
languagesThe codes you want the title and text in, in order of preference (en-GB, de-DE, fr-FR, nl-NL, pl-PL, it-IT, es-ES, sv-SE, da-DK, ...), or all for every translation as an object. English when left out.
sortByarchive (the archive's own order, the fastest, the one that walks a large result to its end) or newest (latest start date first; the archive sorts the whole result, several seconds per page on a large one). newest is the default when a memory name is given. A rare word (a few thousand ads or fewer) is the exception: since October 2026 the archive answers it only in its own relevance order, so its ads come in that order whichever sort you pick.
exactWordsDeliver only rows where your words appear literally (the archive's stemming also matches Jack for Jacke and Levi for levis); the other rows are dropped free. Off when left out.
countResultsAsk the archive how many ads match each search (2 to 30 seconds, free; above about 150,000 matches it may time out). Off when left out.
maxAds, maxAdsPerSearch, maxPagesPerSearchThe caps: 100 ads per run when left out (up to 200,000); no cap per search; 200 archive pages of up to 2,000 rows per search.
memoryName, resetMemoryA plain name for a scheduled run that should deliver only ads it has not delivered before (see the FAQ); resetMemory forgets everything under the name first.
proxyCountryThe exit country of the one residential session every run uses (the archive answers EU, EEA and UK addresses only): DE when left out, the next country of the list when the proxy has no exit there.

Without any target ({}) the run returns the first ads of the archive inside your markets and dates, capped by maxAds.

How the archive's limit is handled

The archive answers every query inside 30 seconds or not at all, and its own query plan walks the whole archive for a word with no ad or with fewer than a few thousand ads among 19 million. This Actor first reads a small slice of the archive (about a second) to see how common the word is: a common word is walked with the archive's plain query (100 rows a page, the most the archive answers per call); a rare word is read through a second query shape that makes the archive use its text index, so a brand with 80 ads comes back complete in a few seconds and a word with no ad is settled in three small calls. Narrow filters do not make a search faster (the archive scans more rows per matching ad), so a rare word with a narrow window can still run into the limit: the coverage row then says archive_timeout, nothing is charged for that search, and the other searches of the run go on.

What this Actor does not do

  • It does not read the shop: no product prices, sizes, stock, reviews, or the position of a sponsored slot on a live search page. The archive records the ad (who paid, what product, where, how long, how many recipients), not the page it appeared on.
  • It does not return the ad creative beyond the product image: the archive carries one product image and, for most ads, the product title as the text; brand campaign ads (about 6 percent) carry a short headline and a call to action instead. No body copy, no video.
  • It does not return spend: the archive publishes reach (recipients), not money.
  • It does not return an advertiser page or profile, and no impressions per market: the archive names the sponsor's legal entity and gives one reach count per ad with the list of markets.
  • It does not search by sponsor on the archive's side: the archive has no sponsor filter, so a sponsor search is a text search of the name plus a whole word check of every row's sponsor, and a sponsor whose name shares no word with its ads' titles can only be found by its name.

API

curl -X POST "https://api.apify.com/v2/acts/automation_craft~zalando-ads-library-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"searchTerms": ["nike"], "markets": ["DE", "AT"], "startDate": "30 days", "maxAds": 200}'
const { ApifyClient } = require('apify-client');
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('automation_craft/zalando-ads-library-scraper').call({ sponsors: ['NIKE Retail B.V.'], languages: ['de-DE', 'en-GB'], maxAds: 500 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const ads = items.filter((x) => x.type === 'ad');
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("automation_craft/zalando-ads-library-scraper").call(run_input={"searchTerms": ["adidas running"], "activeOnly": True, "maxAds": 100})
ads = [x for x in client.dataset(run["defaultDatasetId"]).iterate_items() if x["type"] == "ad"]

FAQ

Does Zalando have an ad library?

Yes. Under the EU Digital Services Act Zalando publishes a sponsored content archive, the ad repository behind en.zalando.de/ads-repository, with every sponsored product ad shown on its shops: about 19 million ads with the sponsor, the product, the period, the markets, the reach and the targeting. This Actor reads that archive.

How can I see competitor ads on Zalando?

Put the brand word into searchTerms (nike finds the product titles and the sponsor NIKE Retail B.V.), or the sponsor's name into sponsors for only that legal entity's ads. Every row carries the product, the image, the days it ran, the markets and the reach, so you see what a competitor sponsors, where and for how long.

What are Zalando Sponsored Products and who is the sponsor?

Sponsored Products are the paid product placements on Zalando's catalogue pages. The archive names the sponsor as the legal entity that paid, for example NIKE Retail B.V. or Falke KGaA; a brand can appear under several entities and a distributor can sponsor another brand's products. The sponsor field holds the name as the archive writes it.

Which markets and languages does the archive cover?

26 markets (Germany, Austria, Switzerland, the Netherlands, Belgium, France, Italy, Spain, Portugal, Poland, the Nordics, the Baltics, Ireland, the UK and more), one or several per ad, and the product title in up to 44 languages per ad (most ads carry 23 to 25, a few only one). Filter by market, ask for the title in the languages you read, or all of them at once.

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

Yes: schedule the same input with a memoryName. Ads delivered under that name are remembered in a key value store this Actor creates in your account and skipped, free, on later runs. A memory run reads the newest ads first and stops at the first page it already delivered once an earlier run under that name that was charging normally (not delivering free) walked the search to its end; until then each run carries on past the known ads to the next older ones, up to its cap, and charges them. So give a monitor a search it can finish and that stays the same from run to run: a date window with fixed dates, or a maxAds above the brand's ad count on the first run. (activeOnly also keeps the search small, the ads running now, but its window moves every day, so each run re-reads those few pages and skips the known ads free.) A run that finds nothing new then costs the start fee and a few seconds. A second run on one name while another is still running, or a memory that cannot be opened, makes that run deliver its ads free and remember nothing (the first run goes on as normal), and a status row says so; a memory that stops saving in the middle of a run makes the ads from that batch on free (the ads already delivered stay charged and remembered) and the summary row names the reason. The start fee stands in every case. A monitor of a rare word re-reads all of that word's ads on every run (the archive cannot sort a rare word by date), skipping the known ones free; when one run reaches roughly 5,000 to 8,000 known ads of rare words it stops early with a free status row and leaves its later searches for the next run, so split a very large rare word monitor over several memory names.

Why does this Actor run with limited permissions?

Least privilege: it reads only its own input, dataset and key value stores, plus the named memory store it creates itself. It needs nothing else from your account.

More data tools by Automation Craft

Changelog

  • 0.1 (2026-10-08): first release.