Pinterest Ads Library Scraper - EU Ads Repository
Pricing
from $0.60 / 1,000 ads
Pinterest Ads Library Scraper - EU Ads Repository
Scrape Pinterest's public EU Ads Repository: promoted Pins by country, advertiser, dates, category, gender and age, with the advertiser name and landing link on each ad, reach bands, targeting and moderation status. 30 countries, 12 months, many advertisers per run, new ads only memory. Pay per ad.
Pricing
from $0.60 / 1,000 ads
Rating
0.0
(0)
Developer
Automation Craft
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Pinterest Ads Library Scraper - EU Ads Repository
Get Pinterest ads from Pinterest's public EU Ads Repository as clean rows: every promoted Pin by country, advertiser, date window, category, gender and age, with the advertiser name and the landing link on each ad, the days it ran, the countries, the reach bands, the targeting and the moderation status. 30 countries (the 27 EU states plus Norway, Turkey and Brazil), the last 12 months, many advertisers and countries in one run, a memory that makes a daily watch pay only for new ads, no login, no API key, no proxy, no browser. You pay per ad, plus a small fee per search the repository answers; duplicates, unknown names, misses, coverage rows and the summary are free.
Quick start
- Pick the countries (one, several or ALL) and the date window (startDate and endDate; default the last 7 days; longer ranges are cut into 31 day slices for you).
- Optional: advertiserNames (the repository's own names such as
TEMU DEorIKEA Deutschland; case and accents do not matter). Set advertiserNameMatch tocontainsto search every advertiser whose name contains your text. Or paste adIds (pin ids or repository URLs) to fetch specific ads. - Optional filters: categories, genders, ageBuckets, maxDaysSinceLastShown (3 keeps the ads still running).
- Set maxAds (default 100) and run. Export the dataset as JSON, CSV or Excel, or call the Actor from the API, n8n, Make or a schedule.
- For a daily watch give a memoryName: the next run skips every ad already delivered under that name, free.
The default (prefilled) run reads Germany for the last 3 days and stops at 20 ads: about 5 seconds and 1.8 cents.
What you get
One ad row per distinct ad. Fill rates were measured on 2,636 promoted Pin rows delivered by this Actor's builds 0.1.2 and 0.1.11 (the same code for names and links) on the Apify platform on 2026-10-06 (Germany, Austria and Norway, several advertisers and windows) and on 397 detail records of the feasibility probe of 2026-10-05.
| Field | What it is | Fill |
|---|---|---|
pinId, adUrl | the ad's pin id (a string) and its page in the repository | 100% |
advertiserName, advertiserNames, advertiserNameStatus | the advertiser as the repository names it, from the ad detail (the list pages carry no name) | 2,036 of 2,052 asked (99.2%); the 16 others are ads the repository holds no name for (disapproved ads), delivered free |
title, description | the promoted Pin's text | 99.7% |
imageUrl, videoUrl | the creative | 99.9%, video on about 2% |
landingUrl, landingDomain, landingLinkStatus | where the ad sends the viewer, from the pin itself | 1,812 of 2,052 asked (88%); 237 pins (11.5%) had been deleted from Pinterest since the archive kept the ad (pin_deleted); the probe of 2026-10-05 saw 20% deleted on an older sample |
startDate, endDate, daysShown, daysSinceLastShown | first and last day shown and the days between; the repository's dates run about two days behind the live state | 100% |
countries, countryCodes | every country the ad ran in, as names and ISO codes | 99.3% |
reachEu, reachByCountry | the EU reach band and the band per country (bands of 10,000 users; 93% of ads sit in 0 - 10000) | 100% |
ageBuckets, genders | the targeting (18+, FEMALE, MALE, UNSPECIFIED and finer buckets where set) | 99.3% |
audienceListTypes | audience lists used: VISITOR, USER_LIST, ACTALIKE, ENGAGEMENT | 47% |
interests, regions, metros, postalCodes, devices, internetServiceProviders | finer targeting, as the repository gives it | under 1% each (the archive is thin here) |
keywordsUsed, negativeKeywordsUsed, isCommercial, isLocalInventory, hasExcludedLocations | targeting and content flags | 99.3% |
reviewStatus, statementOfReasons, violationSource, violationDecisionMeans | moderation: DISAPPROVED ads carry Pinterest's reasons | about 1 in 150 ads |
isVerifiedMerchant, usesPinterestAi, destinationUrls, dynamicImages | detail fields the repository sets on some ads | sparse |
pinCreatedAt, siteName | the pin's creation date and the landing site's name, from the pin | on every pin that still exists (88%) |
pinnerName, pinnerUsername, pinnerUrl, pinnerFollowers, pinnerDomain, pinBoard | the advertiser's Pinterest account, only with includeAdvertiserAccount (some advertisers are individual creators) | on every pin that still exists when asked |
adSource | pinterest for a promoted Pin, third_party for an ad Pinterest serves for another network (title, image, advertiser, a numeric country code, no pin) | 900 third party rows of 3,536 in the platform runs, nearly all from Norway |
query | the country, advertiser, filters and date slice that returned the ad | 100% |
Every run also writes free rows:
- one
coveragerow per query (country x advertiser x filters x 31 day slice):pagesWalked,rowsSeen,distinctAds,repeatedRows,adsDelivered,adsBilled,knownSkipped,queryCharged,stopReason(end_of_results,page_budget,max_ads,charge_limit,server_error,rate_limit_budget,bad_request,blocked,unexpected_answer,aborted,timeout),complete; statusrows:advertiser_not_found(with the names Pinterest suggests),advertiser_no_ads_in_window,ad_not_found,ad_not_recent(an id outsidemaxDaysSinceLastShown),invalid,query_failed,skipped,memory_free;- one
summaryrow with every counter, the requests made and the billing facts.
How much does it cost to scrape Pinterest ads?
| Event | FREE | BRONZE | SILVER | GOLD |
|---|---|---|---|---|
| Ad (one ad row delivered with the data above) | $0.80 per 1,000 | $0.80 per 1,000 | $0.70 per 1,000 | $0.60 per 1,000 |
| Query (one search the repository answered: a country, advertiser, filter and date slice, with or without ads; or one ad id found) | $0.30 per 1,000 | $0.30 per 1,000 | $0.30 per 1,000 | $0.30 per 1,000 |
| Actor start (once per run) | $0.002 | $0.002 | $0.002 | $0.002 |
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, "$0.30 / 1,000" on the Query row means one search costs 0.03 cents. Worked examples at Bronze: the prefilled run (one search, 20 ads) costs $0.0183; 1,000 ads from one search cost $0.8023; a daily watch of one advertiser in one country that finds nothing new costs $0.0023 (the start and one search); the same watch over all 30 countries costs about $0.011 (Norway counts one search per day). Nothing else is charged: duplicates across pages, queries and runs, ads already in your memory, ads whose advertiser name the repository does not hold, advertiser names the repository does not have (checked before any search runs), ad ids it does not know, searches it did not answer, coverage rows and the summary are free. The repository answers the Apify platform directly, so no proxy traffic is added to your bill.
Input
| Field | Meaning | Default |
|---|---|---|
countries | repository countries to search: ISO codes, names, or ALL for all 30; Norway is read one day at a time (a Norwegian week is seven searches) | ["DE"] |
startDate, endDate | the window, YYYY-MM-DD, today, yesterday or N days (counted back from the end date); an ad is returned when its run overlaps the window; ranges over 31 days are sliced | last 7 days |
advertiserNames | advertisers to search, one per line, as the repository names them | none (every advertiser) |
advertiserNameMatch | exact (the repository's own filter) or contains (every advertiser whose name contains the text, through Pinterest's own lookup) | exact |
adIds | pin ids or repository URLs to fetch; given alone, only these ads are fetched | none |
categories, genders, ageBuckets | the repository's filters (25 categories, 3 genders, 7 age buckets); several values become several searches, each ad delivered once | none |
maxDaysSinceLastShown | keep only ads last shown within N days of today (3 keeps the running ads); third party ads carry no date and are left out when it is set | none |
maxAds | most ads delivered and charged in one run | 100 |
maxPagesPerQuery | pages of 100 per query before the walk stops and the coverage row says page_budget | 50 |
includeAdvertiserName | fetch the detail of every ad (the only place with the advertiser name); off is faster and nameless | true |
includeLandingLink | fetch the pin of every ad (landing link, pinner account, creation date); about 1 in 11 pins of a recent window has been deleted since | true |
includeThirdPartyAds | deliver the third party ads the repository archives | true |
includeAdvertiserAccount | add the advertiser's Pinterest account (name, username, profile URL, followers, verified domain, board) to each ad; off because some advertisers are individual creators | false |
memoryName | a plain name; ads delivered under it before are skipped free | none |
resetMemory | forget the memory before this run | false |
proxyConfiguration | optional; the repository needs none, and the RESIDENTIAL group is replaced by the datacenter pool | off |
These alias keys are accepted too (country, advertiserName, advertiser_name, markets, start_date, campaignStartDate, maxResults, maxItems, limit, category, age, gender, pinIds, startUrls), so an existing JSON input can be pasted. A value that cannot be used as given (an unknown country, a date like 2026-09-31, a cap of 0) ends as one free invalid row and no paid work.
How the walk works, and what "complete" means
The repository lists a window one day at a time, 100 ads per page, repeats ads across pages and never says how many ads a query has. Pinterest also allows 20 list calls and 200 detail calls per minute per address; the Actor stays under both on one address and waits when asked. So a large advertiser (TEMU DE has about 5,000 ads active on a single day) or an unfiltered country can run to thousands of pages. Each query stops at maxPagesPerQuery and its coverage row says so (complete: false, stopReason: page_budget); the Actor never claims to have every ad of such a query. An advertiser plus a short window is the reliable unit, and that is what a daily watch with a memoryName does: new ads only, charged once, forever.
If the Apify platform restarts a run (a migration to another server), the ads delivered before the restart stay delivered and every row after it is free: a restarted run never charges.
Memory across runs
Give every scheduled run the same memoryName (for example temu-de-daily). The Actor keeps the ids of the ads it delivered under that name in a key value store of its own and skips them free on the next run (knownSkipped on the coverage row). An ad delivered with its advertiser name is remembered; an ad delivered free because the repository held no name for it is not, so it comes back when it can be billed. One run at a time per name: the memory is locked by the running run (an exclusive platform lock), a second run on a busy name delivers free and remembers nothing, and if the memory cannot be opened, locked, read or saved, the run delivers everything free and says so in a memory_free row. resetMemory forgets the memory before the run.
What this Actor does NOT do
- It does not promise every ad of a large advertiser or an unfiltered country: the repository lists a window day by day without a total; the coverage row tells you how far each query got.
- It does not return spend, impression counts, a payer, or demographics beyond age and gender: the repository publishes none of them.
- It does not flag an ad as active: the repository's end dates run about two days behind; use
daysSinceLastShownandmaxDaysSinceLastShown. - It does not return the landing link of a pin deleted from Pinterest since the archive kept the ad (about 1 in 11 ads of a recent window, 1 in 5 on older ads); the row says
pin_deleted. - It does not cover the US or the UK: the repository is the EU Digital Services Act archive (27 EU states plus Norway, Turkey and Brazil); US and GB are refused by Pinterest.
- It does not read Norway in one piece: the repository answers a server error for any Norwegian window longer than one day, so Norway is read one day at a time (seven searches for a week).
- It does not add the advertiser's Pinterest account to the rows unless
includeAdvertiserAccountis on: some advertisers are individual creators. - It does not look up more than 20 unknown ad ids in a row: after 20 misses the remaining ids are skipped with a free row (misses are free; this bounds the work a wrong list can cause).
- It does not look up unknown advertiser names without limit either: each name is checked right before its first search, and a run may hit 10 names the repository does not know or cannot confirm (a probing search counts once more), plus 3 more for every search it has billed; when that allowance is spent the remaining names are skipped in one free row that lists them, and no search runs for them. A name the lookup cannot confirm (its answer was capped at 100 names without the exact one, or failed) gets one probing search, at most 5 such probes per run: records confirm it, no record ends its searches with a free row.
- It does not need, and does not use, a Pinterest login, a developer key, a residential proxy or a browser.
- It does not pass platform usage to you: the price is the events above.
- It does not monitor changes to an ad (an ad's end date moves every day it runs); the memory delivers new ads only.
FAQ
Does Pinterest have an ad library like Facebook's Ad Library?
Yes, for the EU. Pinterest's Ads Repository is its Digital Services Act archive: every ad shown in the 27 EU states plus Norway, Turkey and Brazil during the last 12 months, with its creative, dates, countries, a reach band and basic targeting. This Actor turns a search of it into rows. There is no US or UK version; US and GB are refused by the repository.
Which countries does the Pinterest Ads Repository cover?
30: Austria, Belgium, Bulgaria, Croatia, Cyprus, Czech Republic, Denmark, Estonia, Finland, France, Germany, Greece, Hungary, Ireland, Italy, Latvia, Lithuania, Luxembourg, Malta, Netherlands, Norway, Poland, Portugal, Romania, Slovakia, Slovenia, Spain, Sweden, Turkey and Brazil. Give any number of them, or ALL; an ad shown in several of your countries is delivered and charged once.
How do I see a competitor's ads on Pinterest?
Put the advertiser's repository name in advertiserNames (case and accents do not matter) and pick the countries and dates. If you only know part of the name, set advertiserNameMatch to contains and the Actor searches every advertiser whose name contains your text, as Pinterest's own lookup lists them (up to 10 texts per run in this mode). An unknown name costs nothing and comes back as a free row with the names Pinterest suggests.
Can I see how much a competitor spends on Pinterest ads?
No. The repository publishes no spend, no impression counts and no payer. It gives a reach band per country and for the EU (most ads sit in the lowest band, 0 to 10,000 users), the days the ad ran, the countries and the age and gender targeting. The Actor returns exactly those.
Does it return every ad of an advertiser?
It returns every ad the repository lists for your query, one row each, and a free coverage row per query that says how many pages were walked, how many distinct ads came back and why the walk stopped. The repository lists a window one day at a time, repeats ads across pages and never says how many ads a query has, so large advertisers and unfiltered countries can run to thousands of pages; each query stops at maxPagesPerQuery (default 50) and says so. An advertiser plus a short window is the reliable unit.
Why does this Actor run with limited permissions?
Least privilege: it reads its input and writes its own run's dataset and key value store; with a memoryName it also creates and uses one named key value store of its own for that memory. It touches nothing else in your account.
Use it from the API
curl -X POST "https://api.apify.com/v2/acts/automation_craft~pinterest-ads-library-scraper/runs?token=YOUR_TOKEN&waitForFinish=120" \-H "Content-Type: application/json" \-d '{"countries": ["DE", "AT"], "advertiserNames": ["TEMU DE"], "startDate": "7 days", "maxAds": 200}'
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_TOKEN' });const run = await client.actor('automation_craft/pinterest-ads-library-scraper').call({countries: ['FR'], advertiserNames: ['ikea'], advertiserNameMatch: 'contains', startDate: '30 days', maxAds: 500, memoryName: 'ikea-fr-weekly',});const { items } = await client.dataset(run.defaultDatasetId).listItems();const ads = items.filter((x) => x.type === 'ad');
from apify_client import ApifyClientclient = ApifyClient("YOUR_TOKEN")run = client.actor("automation_craft/pinterest-ads-library-scraper").call(run_input={"adIds": ["https://ads.pinterest.com/ads-repository/4594867985295070848/"],})for item in client.dataset(run["defaultDatasetId"]).iterate_items():if item["type"] == "ad":print(item["advertiserName"], item["landingUrl"])
Changelog
- 0.1 (2026-10-06): first release. Repository API with the rate rule respected on one address, advertiser name and landing link per ad, many countries and advertisers per run, name lookup with candidates, ad id lookup, 31 day slicing, memory across runs, coverage and status rows.
More data tools by Automation Craft
Ad libraries: Meta Ad Library Scraper - All Placements, Filters, Facebook Ads Library Scraper - Page Ads, No Login, Instagram Ads Library Scraper - Creatives, Video, Google Ads Transparency Scraper - Decoded Creatives, Google Ads Library Scraper - Competitor Ads, No Login, TikTok Ads Library Scraper: EU Ads, No Login, TikTok Creative Center Scraper: Top Ads, No Login, LinkedIn Ad Library Scraper: Ads by Company, YouTube Ads Scraper - Video Ads by Advertiser.
Other data: LinkedIn Company Scraper - Details, No Login, Yahoo Finance Scraper: Quotes, History, Financials.