Pinterest Ad Library Scraper — Ad Search & Export
Pricing
from $3.00 / 1,000 ad scrapeds
Pinterest Ad Library Scraper — Ad Search & Export
Export ad records from Pinterest's public Ads Repository — pin id, title, image, date range, countries, genders, age buckets, and EU reach. Filter by country, date window, advertiser name, gender, and ad vertical. Covers EU27, Brazil, and Turkey. Deduplicated rows, no login required.
Pricing
from $3.00 / 1,000 ad scrapeds
Rating
0.0
(0)
Developer
DevilScrapes
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
13 days ago
Last modified
Categories
Share
Quick answer: The Pinterest Ad Library Scraper searches Pinterest's public Ads Repository by country and date range and returns every matching ad as structured, deduplicated data — pin id, title, creative image, delivery date window, targeted countries/genders/age buckets, and EU reach count. No Pinterest developer account or API key is required. Pricing is pay-per-result — $3.20 per 1 000 ads landed, no subscription, no card required to try it. Coverage is EU27, Brazil, and Turkey — this is not a global or US ad library.
🎯 What this scrapes
Pinterest's Ads Repository is its public transparency registry for ads running across the EU, Brazil, and Turkey. This Actor searches it by country and date window — optionally narrowed by advertiser name, gender, or ad vertical — and walks Pinterest's own pagination cursor to pull every matching ad.
Per ad you get:
| Field | Type | Notes |
|---|---|---|
pin_id | string | Pinterest's stable id for this pin — our dedup key |
title | string | Pin title |
image_link | string | Creative image URL |
start_date / end_date | string | Ad delivery window, YYYY-MM-DD |
countries | array | Countries this ad ran in, as Pinterest's own full names (e.g. "Germany", not "DE") |
genders | array | Gender targeting buckets reported |
age_buckets | array | Age targeting buckets reported |
user_count_eu | string | Reported EU reach as a bucketed range, e.g. "0 - 10000" |
query_country | string | The country your search used |
advertiser_name | string | ⚠️ Real merchant name only with fetch_advertiser_details (see below) — Pinterest's search endpoint never returns it. Otherwise an echo of your filter, when set |
scraped_at | string | ISO-8601 UTC timestamp |
🔥 What we handle for you
- 🛡️ We rotate browser fingerprints (curl-cffi impersonation — Chrome and Firefox) on every page, even though this endpoint's limiter is request-based, not fingerprint-based — a cheap hedge against Pinterest tightening that later.
- 🧱 We back off when Pinterest rate-limits. Its Ads Repository allows roughly 20 pages before a sliding-window
429— we pause 45 seconds and resume from the exact same pagination cursor, never losing your place or failing the run. - 🧊 We deduplicate every row. Pinterest repeats close to a third of records across pages; we track unique pin ids incrementally so your dataset count is always the true number of unique ads, never
pages × page size. - 🔁 We retry with exponential backoff on server errors and network hiccups, honoring
Retry-After— up to 5 attempts per page. - 💰 You pay only for results that land. No data → no charge (only the small
actor-startwarm-up fee).
💡 Use cases
- Competitor ad monitoring — track what a competitor brand is currently running on Pinterest in your target EU/BR/TR market.
- Ad creative research — pull dozens to hundreds of live pin titles and images for a market/date window to inform your own creative testing.
- Brand protection — search your own brand name via
advertiser_nameto spot unauthorized advertisers, and turn onfetch_advertiser_detailsto confirm who's actually behind each result. - Market research — gauge Pinterest ad activity for a vertical across the EU, Brazil, and Turkey.
- Agency reporting — export a client's (or a competitor's) live Pinterest ad set straight to a spreadsheet.
- AI / RAG ingestion — feed titles and creative image URLs into a vector store for creative-trend analysis.
⚙️ How to use it
- Click "Try for free" at the top of the page.
- Set a start date (
YYYY-MM-DD) — required. This is the beginning of the delivery window you want to search. - Set a country — required, ISO-3166 alpha-2 (e.g.
DE,FR,BR). The Ads Repository only covers EU27, Brazil, and Turkey. - (Optional) Narrow the search with an end date, advertiser name, gender, or ad vertical.
- (Optional) Turn on Fetch real advertiser names if you need to know who is running each ad — it costs an extra paced request per ad, so runs take longer.
- Run. Each unique ad is one row in the dataset; export to JSON, CSV, or Excel from the Storage tab.
The first run on a new account uses $5 of free Apify credit — that's roughly 1 500 ads at our pricing.
📥 Input
The schema lives in .actor/input_schema.json. The fields:
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
start_date | string | yes | — | YYYY-MM-DD, repository window start |
country | string | yes | — | ISO-3166 alpha-2 (e.g. DE); uppercased automatically |
end_date | string | no | null | YYYY-MM-DD, repository window end |
advertiser_name | string | no | null | Free-text advertiser filter, no autocomplete |
fetch_advertiser_details | boolean | no | false | Best-effort per-ad lookup of the real advertiser/merchant name (extra request + runtime per ad) |
gender | string | no | null | Optional passthrough filter |
ad_vertical | string | no | null | Optional passthrough filter |
maxResults | integer | no | 500 | Cap on unique deduplicated rows |
maxPages | integer | no | 20 | Soft ceiling on pagination round-trips (never a hard-fail) |
proxyConfiguration | proxy config | no | no proxy | This endpoint returns 200 with zero proxy by default |
start_date and country are both required — the Actor fails fast if either is missing, before any network call or charge.
Proxy defaults to none, on purpose. Pinterest's Ads Repository answers with a plain 200 with zero proxy involved, so we don't force a residential tier you'd pay for and not need. If you opt into Apify Proxy anyway, we pin the exit country to your country input — a floating exit could otherwise return a plausible-looking result set for the wrong market.
Example input
{"start_date": "2026-08-01","country": "DE","maxResults": 100,"maxPages": 5,"proxyConfiguration": { "useApifyProxy": false }}
📤 Output
Every row is one unique ad. Example (default settings — fetch_advertiser_details off):
{"pin_id": "1074427839201234567","title": "Summer sale — 30% off sneakers","image_link": "https://i.pinimg.com/originals/ab/cd/ef/example.jpg","start_date": "2026-08-01","end_date": "2026-08-31","countries": ["Germany", "France", "Brazil"],"genders": ["FEMALE", "MALE"],"age_buckets": ["25-34", "35-44"],"user_count_eu": "100000 - 500000","query_country": "DE","advertiser_name": null,"scraped_at": "2026-09-13T10:15:00+00:00"}
With fetch_advertiser_details: true, advertiser_name resolves to the real merchant behind the ad, e.g. an ad titled "Esprit Damen Top | Sale | Gr. M | Mehrfarbig | Second Hand" resolves to "advertiser_name": "momox fashion" — the resale platform actually running it, not the brand named in the creative.
Export options once the run finishes:
- JSON — full payload
- CSV / Excel — for analyst spreadsheets
- JSONL — line-delimited, easy to stream into a warehouse
- API — fetch programmatically via
GET /v2/datasets/{id}/items; webhook onACTOR.RUN.SUCCEEDEDfor live pipelines
💰 Pricing
Pay-per-event. You pay for what you get, nothing for what you ask for:
| Event | Price | When charged |
|---|---|---|
actor-start | $0.20 | Base fee, once per run (warm-up, input validation) |
ad-result | $0.003 | Per unique pin_id written to the dataset |
Examples:
| Pull | Cost |
|---|---|
| 100 ads | $0.50 |
| 1 000 ads | $3.20 |
| 10 000 ads | $30.20 |
🚧 Limitations
- Coverage is EU27, Brazil, and Turkey — not global or US. Pinterest's own Ads Repository doesn't publish for other markets, so we don't fabricate results for them. If you need US Pinterest ad data, this Actor isn't the right tool.
- ~33% of raw records repeat across pages. We absorb this with incremental dedup, so your dataset's row count is always the true unique count — but it means the source itself isn't clean, and a
maxPagessized too small can undercount if the overlap lands unevenly. - The rate-limit window means a large
maxPagesrun can take longer thanmaxPages × 5s. If Pinterest rate-limits mid-run, we pause 45 seconds and resume — the run still finishes, just not on the fastest possible clock. - No advertiser-name autocomplete.
advertiser_nameis a free-text filter with no validation against Pinterest's own advertiser list — the lookup endpoint that would provide that requires Pinterest authentication we don't have and don't attempt to bypass. - Pinterest's search endpoint never returns advertiser identity. We verified this live across 227+ records, 9 countries, and multiple date windows (including rejected/
DISAPPROVEDads) — the schema field that would carry it isnullon every sampled row.advertiser_nameisnullby default unless you set theadvertiser_namefilter (which just echoes back what you typed) or turn onfetch_advertiser_detailsfor a real, paced, per-ad lookup. fetch_advertiser_detailsis best-effort, not guaranteed. It adds one ~1 MB request per unique ad and meaningfully increases run time; Pinterest also throttles rapid repeat requests to that page, so an occasional row can still come backnulleven with the option on.- No public per-ad URL in the output row (yet). Every ad's
pin_idmaps tohttps://www.pinterest.com/pin/<pin_id>/— that page is exactly whatfetch_advertiser_detailsreads — but it isn't emitted as its own field today.
❓ FAQ
Is this legal?
Yes. Pinterest's Ads Repository is a public transparency registry Pinterest operates for EU DSA and related regulatory requirements. We search only what the public endpoint exposes, at a paced rate, with no login wall or paywall involved.
Do I need a Pinterest developer account or API key?
No. This Actor works entirely against the public Ads Repository endpoint — no app registration, no OAuth, no access token.
Why does my result count sometimes look lower than expected?
Two reasons: your maxPages/maxResults caps, and the ~33% cross-page duplicate rate the endpoint itself produces, which we dedupe out rather than count twice.
Can I search a specific advertiser?
Yes — set advertiser_name to a free-text value. There's no autocomplete against Pinterest's own advertiser list (that lookup requires Pinterest authentication), so match it as closely as you can to how the brand appears on Pinterest.
Does the output tell me who's actually running each ad?
Only if you turn on fetch_advertiser_details. Pinterest's search endpoint itself never returns advertiser identity — by default advertiser_name is just an echo of your own advertiser_name filter (or null if you didn't set one). With the option on, we do a second, paced lookup per ad against its public pin page to resolve the real merchant name — useful because the account actually running an ad is sometimes a reseller or agency, not the brand named in the creative (see the Output example above).
How do I schedule this to run automatically?
Apify Console → Schedules → attach this Actor → set your cron. Weekly is plenty; ad libraries don't turn over fast enough to need more.
What integrations does this Actor support?
- Schedule — Apify Console → Schedules for recurring monitoring.
- Webhooks — register
ACTOR.RUN.SUCCEEDEDto fire a downstream pipeline. - API —
POST /v2/acts/DevilScrapes~pinterest-ad-library-scraper/run-sync-get-dataset-itemsfor a single synchronous pull. - Make / Zapier — every Apify Actor surfaces as a node out of the box.
💬 Your feedback
Spotted a bug, missing field, or want a new feature? Open an issue on the Apify Store listing — we read every one.
Built by Devil Scrapes — Apify Actors with attitude. PPE, transparent pricing, no junk fields.