# Pinterest Search Scraper — Pins by Keyword + Creator Leads (`scrapersdelight/pinterest-search-scraper`) Actor

Search Pinterest by keyword and get pins as clean rows: title, description, image URL, outbound link and domain, reactions, created date, pinner username, followers and verified-merchant flag, board. Optional creator enrichment adds the pinner's website, billed only when found. No login.

- **URL**: https://apify.com/scrapersdelight/pinterest-search-scraper.md
- **Developed by:** [Scrapers Delight](https://apify.com/scrapersdelight) (community)
- **Categories:** Social media, Marketing, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 per pin returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Pinterest Search Scraper — Pins by Keyword + Creator Leads

Search [Pinterest](https://www.pinterest.com) by keyword and get every pin as one clean row:
**pinId, pinUrl, title, description, altText, hashtags, imageUrl (full size), dominantColor,
link, linkDomain, isVideo / videoUrl, reactionCount, createdAt, isPromoted, visualTags,
pinnerUsername, pinnerName, pinnerFollowers, pinnerIsVerifiedMerchant, boardName,
boardUrl, boardPinCount** — and, with creator enrichment on, the pinner's public profile:
**creatorWebsite, creatorDomain, creatorDomainVerified, creatorContactEmail,
creatorContactPhone, creatorInstagram, creatorIsBusiness, creatorMonthlyViews,
creatorAbout**. No login. No cookies. No browser. No CAPTCHA solving.

**Measured scope: the shipped default returns 50 unique pins from 3 search pages with 0
duplicates, 43 of 43 creator profiles fetched and 0 failed, and 0 of the run's 48 requests needed
the residential fallback — all through the Apify datacenter proxy (platform run, 2026-08-27).**
Pinterest keeps paginating a popular keyword past 1,000 pins, so the ceiling is your limit, not
the site.

```json
{
  "queries": ["home office ideas"],
  "maxItems": 50,
  "maxPinsPerQuery": 50,
  "enrichCreators": true
}
```

Click **Try for free** and hit **Start** — that block is literally the input the Actor ships
with. A run on those shipped defaults returned **50 pins in 41 seconds** from 3 search pages,
opened 43 unique creator profiles, and found a contact (website, email, phone or Instagram) on
**25 of 43 creators (58%)**. It costs **$0.15 for the pins plus $0.004 per creator contact
actually found** — $0.25 for that run.

***

### The wedge: a creator contact, not just a pin

Ninety Apify Actors carry "Pinterest" in their name, and the handful that return search pins all
return the same JSON: title, image, description, pinner username, board. That row is commodity
data. What it is *not* is a lead.

This Actor does two things the top sellers in the lane do not advertise:

1. **It opens each unique pinner's public profile and reads the contact fields Pinterest
   publishes for business accounts.** Measured on the shipped-default run (2026-08-27, 50 pins
   from 43 unique creators): **website on 48% of rows, contact email 30%, contact phone 8%,
   Instagram handle 14% — at least one contact on 58%** of creators, and **95% are business
   accounts** that also publish `creatorMonthlyViews` (the "monthly views" number on a Pinterest
   profile; it ranged from 27 thousand to 6.7 million in the sample). That is the difference
   between "a pin about home offices" and "a home-decor publisher with 4.6 million monthly
   Pinterest views, a verified domain, and an Instagram handle".
2. **It bills that enrichment only when it finds something.** `creator-contact-found` is a
   separate success-billed event charged once per unique creator whose profile carried a
   website, email, phone or Instagram handle — never for a profile that came back empty, and
   never twice for a creator who pinned five of your results.

Everything else is priced to sit inside the lane: **$0.003 per pin, no start fee**, on the same
pure-HTTP technique the 256 MB incumbents use, with a capped residential fallback they do not.

***

### Read this before you buy rows

Five things that would otherwise turn into a refund request.

1. **Search rows carry reactions, not saves.** Pinterest's search resource publishes
   `reaction_counts` (60% of the 50-pin sample run had at least one) but **no save / repin
   count**. If you need `saveCount`, switch on *Include save counts* — one extra request per pin,
   same price per pin, measured 0.5–1 s each at concurrency 4. Off by default to keep the sample
   run fast.
2. **`link` fill depends on the keyword.** Only **28% of pins carried an outbound link on the
   shipped "home office ideas" sample**, which is idea-pin heavy (92% `isIdeaPin`). Idea pins are
   uploaded natively and usually have no link, so a keyword that skews to idea pins fills `link`
   less often. *Only pins with an outbound link* drops the rest **before** anything is fetched or
   billed.
3. **The contact is on the creator, not the pin.** `creatorContactEmail` etc. come from the
   pinner's profile, and one creator often owns several pins in your results. The creator
   enrichment event is charged once per unique creator, but the same contact will appear on every
   row that creator pinned — deduplicate on `pinnerUsername` downstream if you want a creator
   list rather than a pin list.
4. **`creatorMonthlyViews` is `null` for personal accounts.** Pinterest only publishes the
   monthly-views figure for business accounts (`creatorIsBusiness: true`, 95% of creators on the
   sample run). A `null` there means "personal account", not "zero views".
5. **`title` was 92% filled on the sample run, `description` 90%.** Pinterest pins do not have to
   carry a title. `altText` (Pinterest's own image description) is 100% and is the reliable text
   field.

***

### What you get

One row per unique pin. Every field is present on every row (63 keys, zero missing cells
measured); `null` means Pinterest published nothing. Dates are ISO-8601 UTC.

| Group | Fields | Example |
|---|---|---|
| **Pin** | `pinId`, `pinUrl`, `title`, `description`, `altText`, `hashtags[]`, `createdAt`, `isPromoted`, `isIdeaPin`, `isUploaded`, `sourceLabel` | `232920611975324494` · `35+ Stunning Home Office Decor Ideas…` · `2026-08-15T01:35:56.000Z` |
| **Media** | `imageUrl`, `imageWidth`, `imageHeight`, `thumbnailUrl`, `dominantColor`, `isVideo`, `videoUrl`, `videoDurationSec`, `videoThumbnailUrl` | `https://i.pinimg.com/originals/eb/2d/16/….jpg` · `1000×1500` · `#5c4d48` |
| **Destination** | `link`, `linkDomain`, `richSiteName`, `products[]` (`name`, `price`, `currency`, `inStock`, `url`) | `https://jane-athome.com/home-office-ideas/` · `jane-athome.com` |
| **Engagement** | `reactionCount`, `reactionCounts{}`, `saveCount`, `repinCount`, `commentCount`, `shareCount` | `483` · `{"1": 483}` · save counts only with *Include save counts* |
| **Pinner (free, from the search row)** | `pinnerId`, `pinnerUsername`, `pinnerName`, `pinnerUrl`, `pinnerFollowers`, `pinnerIsVerifiedMerchant`, `pinnerAvatarUrl` | `jcman1` · `116,104` followers |
| **Board** | `boardId`, `boardName`, `boardUrl`, `boardPinCount`, `boardOwnerUsername` | `Room Decor` · `5,551` pins |
| **Creator (enrichment)** | `creatorEnriched`, `creatorContactFound`, `creatorIsBusiness`, `creatorWebsite`, `creatorDomain`, `creatorDomainVerified`, `creatorContactEmail`, `creatorContactPhone`, `creatorInstagram`, `creatorAbout`, `creatorLocation`, `creatorPinCount`, `creatorBoardCount`, `creatorFollowing`, `creatorMonthlyViews`, `creatorJoinedAt` | `http://jane-athome.com` · verified · `jane_athome` · `4,603,516` monthly views |
| **Visual** | `visualTags[]` | `["Aesthetic Home Studio", "Office Design Simple", …]` |
| **Provenance** | `searchQuery`, `searchScope`, `resultRank`, `scrapedAt` | `home office ideas` · `pins` · `7` |

The dataset ships with a saved **table view** (image, title, pinner, followers, verified
merchant, link domain, outbound link, reactions, created, board, creator website, query, pin).

***

### Field fill — measured on real rows

**Shipped-default run, 50 pins for "home office ideas" with creator enrichment, 2026-08-27.**
Sorted by fill, so the sparse fields are impossible to miss.

| Field | Fill | Notes |
|---|---|---|
| `pinId` / `pinUrl` / `imageUrl` / `imageWidth` / `imageHeight` / `thumbnailUrl` / `dominantColor` | 100% | |
| `altText` | 100% | Pinterest's own image description — the reliable text field |
| `createdAt` / `reactionCount` / `sourceLabel` | 100% | `reactionCount` is a real 0 when nobody reacted |
| `pinnerId` / `pinnerUsername` / `pinnerName` / `pinnerUrl` / `pinnerFollowers` / `pinnerAvatarUrl` | 100% | |
| `boardId` / `boardName` / `boardUrl` / `boardPinCount` / `boardOwnerUsername` | 100% | |
| `creatorEnriched` / `creatorPinCount` / `creatorBoardCount` / `creatorFollowing` / `creatorJoinedAt` | 100% | 43/43 profiles fetched, 0 failed (a 50-pin run spans 43–49 unique creators run to run) |
| **`creatorIsBusiness` (true) / `creatorMonthlyViews`** | **96.0%** | monthly views are published by business accounts only; `null` = personal account |
| `title` | 92.0% | |
| `isIdeaPin` | 92.0% | this keyword is idea-pin heavy |
| `creatorAbout` | 90.0% | |
| `description` | 90.0% | |
| **`creatorContactFound` (true)** | **60.0%** of rows | 25 of 43 unique creators |
| `reactionCounts` | 60.0% | |
| **`creatorWebsite` / `creatorDomain`** | **48.0%** | |
| `visualTags` | 42.0% | Pinterest's visual annotations, ~8 tags per pin when present; the rate swung 40–94% across the seven runs of this keyword |
| `hashtags` | 36.0% | parsed from the description |
| **`creatorContactEmail`** | **30.0%** | published by business accounts |
| **`link` / `linkDomain`** | **28.0%** | keyword-dependent, see gotcha 2 |
| **`creatorInstagram`** | **14.0%** | |
| `richSiteName` | 10.0% | the destination site's display name |
| `creatorDomainVerified` / `creatorContactPhone` | 8.0% | |
| **`isVideo` / `videoUrl`** | **0%** | 0 of 320 rows across all seven runs to date; use `scope: "videos"` for video pins |
| **`saveCount` / `repinCount` / `commentCount` / `shareCount`** | **null by default** | switch on *Include save counts* |
| `isPromoted` / `pinnerIsVerifiedMerchant` / `products` / `creatorLocation` | 0% | rare fields — 0 of 320 rows across all seven runs to date. `products` fills only where Pinterest attaches a shoppable rich summary; treat all four as bonus, not as data you are buying. |

**Every run prints its own measured counts in the log** — pages per query, creators fetched,
contacts found, uniqueness verification, and duplicates dropped whenever there were any.

***

### How to run it

#### 1. Keywords (the usual choice)

```json
{
  "queries": ["boho bedroom", "vegan meal prep"],
  "maxPinsPerQuery": 100,
  "maxItems": 200
}
```

Each keyword is walked page by page (18–25 pins per page) using Pinterest's own `bookmark`
cursor, until `maxPinsPerQuery` or the end of results. Pins that rank for more than one keyword
are returned once and billed once.

#### 2. Video pins only

```json
{ "queries": ["desk setup"], "scope": "videos", "maxItems": 50 }
```

Same row shape; rows carry `videoUrl`, `videoDurationSec` and `videoThumbnailUrl` wherever
Pinterest publishes the rendition.

#### 3. Paste a Pinterest search URL

```json
{ "startUrls": ["https://www.pinterest.com/search/pins/?q=modern%20kitchen"] }
```

The keyword and scope are read from the URL. Works alongside `queries`.

#### 4. A pure creator-lead list

```json
{
  "queries": ["wedding photographer", "interior designer portfolio"],
  "onlyWithCreatorContact": true,
  "maxItems": 300
}
```

Keeps only pins whose creator profile carried a website, email, phone or Instagram handle. Rows
removed by the filter are never billed — but the Actor still has to open the search pages and
profiles to find out, so expect fewer rows per page than the limits suggest.

#### 5. With save counts

```json
{ "queries": ["logo design inspiration"], "includeSaveCounts": true, "maxItems": 100 }
```

Fills `saveCount`, `repinCount`, `commentCount` and `shareCount` from each pin's detail resource.
Same price per pin — it costs time, not money.

#### Scheduling and integrations

Save the input as a **Task** (Console → the Actor → *Save as Task*), then attach an Apify
**Schedule** — `0 6 * * 1` for a Monday-morning refresh of your keywords. The dataset is
available over the REST API and through the standard Apify integrations (Zapier, Make, n8n,
webhooks, MCP). Starting a run from the API:

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapersdelight~pinterest-search-scraper/runs?token=YOUR_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"queries":["boho bedroom"],"maxItems":100}'
```

***

### Sample row

A real row from the shipped-default run, captured 2026-08-22 17:32 UTC.

```jsonc
{
  "pinId": "232920611975324494",
  "pinUrl": "https://www.pinterest.com/pin/232920611975324494/",
  "title": "35+ Stunning Home Office Decor Ideas and Design Inspiration for 2026",
  "description": "Stunning home office decor ideas for 2026, with designer inspiration photos and tips on how to design, set up, organize, and decorate a beautiful and functional home office…",
  "altText": "an office with blue walls and wooden floors, the title says stunning home office ideas for 2016",
  "hashtags": [],
  "imageUrl": "https://i.pinimg.com/originals/eb/2d/16/eb2d16d320445c82c06f431b3a357997.jpg",
  "imageWidth": 1000,
  "imageHeight": 1500,
  "thumbnailUrl": "https://i.pinimg.com/236x/eb/2d/16/eb2d16d320445c82c06f431b3a357997.jpg",
  "dominantColor": "#5c4d48",
  "isVideo": false, "videoUrl": null, "videoDurationSec": null, "videoThumbnailUrl": null,
  "link": "https://jane-athome.com/home-office-ideas/",
  "linkDomain": "jane-athome.com",
  "sourceLabel": "jane-athome.com",
  "isUploaded": false,
  "reactionCount": 0,
  "reactionCounts": {},
  "saveCount": null, "repinCount": null, "commentCount": null, "shareCount": null,
  "createdAt": "2026-08-15T01:35:56.000Z",
  "isPromoted": false,
  "isIdeaPin": true,
  "visualTags": [],
  "products": [],
  "richSiteName": "jane at home",

  "pinnerId": "232920749386498365",
  "pinnerUsername": "jcman1",
  "pinnerName": "jane at home | decor and design",
  "pinnerUrl": "https://www.pinterest.com/jcman1/",
  "pinnerFollowers": 116104,
  "pinnerIsVerifiedMerchant": false,
  "pinnerAvatarUrl": "https://i.pinimg.com/75x75_RS/84/c0/a1/84c0a11b445a21e42bfddb0fe1b74014.jpg",

  "boardId": "232920680667023811",
  "boardName": "Room Decor",
  "boardUrl": "https://www.pinterest.com/jcman1/room-decor/",
  "boardPinCount": 5551,
  "boardOwnerUsername": "jcman1",

  "creatorEnriched": true,
  "creatorContactFound": true,
  "creatorIsBusiness": true,
  "creatorWebsite": "http://jane-athome.com",
  "creatorDomain": "jane-athome.com",
  "creatorDomainVerified": true,
  "creatorContactEmail": null,
  "creatorContactPhone": null,
  "creatorInstagram": "jane_athome",
  "creatorAbout": "Ideas and inspiration for effortless home decorating and entertaining, kitchen design, bedroom inspiration…",
  "creatorLocation": null,
  "creatorPinCount": 72650,
  "creatorBoardCount": 84,
  "creatorFollowing": 1253,
  "creatorMonthlyViews": 4603516,
  "creatorJoinedAt": "2011-09-03T19:00:21.000Z",

  "searchQuery": "home office ideas",
  "searchScope": "pins",
  "resultRank": 7,
  "scrapedAt": "2026-08-22T17:32:29.014Z"
}
```

Fields people misread:

- `reactionCount` is the sum of Pinterest reactions (`reactionCounts` is keyed by reaction type;
  `"1"` is the heart). It is **not** saves — see gotcha 1.
- `sourceLabel` is Pinterest's display label for where the pin came from: a domain, or the
  literal `Uploaded by user`. `linkDomain` is derived from the actual `link` and is `null` when
  there is no link.
- `creatorDomainVerified` means the creator proved ownership of `creatorDomain` to Pinterest —
  a strong "this is the real business" signal.
- `resultRank` is the pin's position in Pinterest's results for that keyword, 1-based, counting
  unique pins only.

***

### Input

Fields in the order the Console shows them.

| Field | Type | Default | What it does |
|---|---|---|---|
| **🔍 What to search** | | | |
| `queries` | string list | `["home office ideas"]` | Pinterest search terms, one per line. |
| `startUrls` | string list | `[]` | Paste Pinterest search URLs; keyword + scope read from the URL. |
| `scope` | select | `pins` | `pins` = all results · `videos` = video pins only. Same row shape. |
| **👤 Creator enrichment** | | | |
| `enrichCreators` | boolean | `true` | One request per unique pinner → website, email, phone, Instagram, monthly views, bio, counts. Billed only when a contact is found. |
| `onlyWithCreatorContact` | boolean | `false` | Keep only pins whose creator has a contact. Never bills a removed row. |
| **📦 Output shape** | | | |
| `includeSaveCounts` | boolean | `false` | One request per pin → `saveCount`, `repinCount`, `commentCount`, `shareCount`. Same price. |
| `onlyWithLink` | boolean | `false` | Drop pins with no outbound link, before any fetch or charge. |
| **💵 Limits & cost** | | | |
| `maxItems` | integer | `50` | **Your hard cost cap** for the pin event. 50 = $0.15, 1,000 = $3.00. |
| `maxPinsPerQuery` | integer | `50` | Depth per keyword, ~25 pins per page. |
| **⚙️ Advanced** | | | |
| `maxConcurrency` | integer | `4` | Parallel profile / pin-detail fetches (max 8). Search pages are sequential by design. |
| `proxyConfiguration` | proxy | Apify proxy (datacenter) | Not walled on the cheap rung; automatic capped RESIDENTIAL retry on 403/429. |

***

### Pricing

**$0.003 per pin returned — $3 per 1,000 — plus $0.004 per creator contact found.** No start
fee, no monthly platform fee from this Actor.

| Run | Pins | Contacts (≈0.5 per pin on the recent runs) | Cost |
|---|---|---|---|
| The shipped default | 50 | 25 | **$0.25** |
| One keyword, 500 deep | 500 | ~250 | **$2.50** |
| Five keywords × 200 | 1,000 | ~500 | **$5.00** |
| Same 1,000 pins, enrichment off | 1,000 | 0 | **$3.00** |

- **`pin-scraped`** is charged as rows are pushed (`Actor.pushData(items, 'pin-scraped')`), and
  the SDK trims each batch to what your run's *max total charge* can still pay for **before**
  pushing — so you get whole rows and stop, never a half-billed dataset.
- **`creator-contact-found`** is charged once per unique creator, only after that creator's pins
  were actually shipped, and only if the profile carried a website, contact email, contact phone
  or Instagram handle. A profile with none of those is fetched and never charged.
- Duplicates are dropped before billing. Rows removed by `onlyWithLink` or
  `onlyWithCreatorContact` are never billed.
- Turning on `includeSaveCounts` changes the price of nothing.

Where this sits in the lane (store prices read 2026-08-27): memo23 $0.00145/pin + start fee ·
easyapi $0.00299 + per-GB start fee · automation-lab $0.00345 + $0.01 start · fatihtahta $0.00399
(no start fee). Note that both fatihtahta and automation-lab price in plan tiers — those are their
FREE-tier rates, and on a paid Apify plan they step down (fatihtahta to $0.00199 from GOLD;
automation-lab to $0.0018 at GOLD and $0.00084 at DIAMOND). Our $0.003 is flat for everyone: on the
free tier we sit upper-middle of that ladder, above it we are the expensive end. The contact
enrichment is what the price buys.

***

### Honest limits

- **No save counts on search rows.** Pinterest's search resource does not publish them; the
  opt-in per-pin fetch does (measured 200 OK on direct, datacenter and residential).
- **Contacts exist on a third to three-fifths of creators, not all of them.** Across the seven
  platform runs of the sample keyword: 25 of 43 (58%) and 25 of 48 (52%) on 2026-08-27, 24 of 47
  (51%) on both 2026-08-22 runs, 15 of 48 (31%) on the earliest. B2B-flavoured keywords ("wedding
  photographer", "interior designer") skew higher; hobby keywords skew lower. The event is only
  billed when found, so a low-contact keyword costs you pins, not enrichment.
- **`link` is keyword-dependent** — 28% on an idea-pin-heavy keyword. Idea pins are native
  uploads and usually carry no destination URL.
- **Promoted pins were 0 of 320** across all seven runs to date: Pinterest does not serve ads to
  this logged-out resource, so `isPromoted` is carried but was never `true` in testing.
- **Board and user search are not here.** `scope` supports `pins` and `videos` — the two scopes
  whose results are pin rows. Boards and profiles are different record types and belong in
  their own Actors.
- **No login, no cookies, no CAPTCHA solving.** Only what a logged-out visitor's browser
  requests, with that browser's own header shape.
- **Personal data.** Pinner names, and the contact email / phone a business account chose to
  publish on its public profile, are personal data in some jurisdictions. See *Legal & fair use*.

***

### How it works, and what it cost to make reliable

The search page itself is a 1.2 MB client-rendered shell with zero pins in it. The pins come from
Pinterest's own JSON resource that the page calls — `/resource/BaseSearchResource/get/` — which
returns HTTP 403 to a bare request and **HTTP 200 to the same request carrying the browser's own
header shape** (`x-app-version`, a hex build id that rotates — the Actor ships the last known
value and re-reads it from the page the moment Pinterest answers 403; `x-pinterest-pws-handler`;
`x-pinterest-source-url`; `x-requested-with`; the cors `sec-fetch-*` set). No cookie, no CSRF token, no login — that was tested explicitly. Creator enrichment reads
`/resource/UserResource/get/` the same way; save counts read `/resource/PinResource/get/`.

**Transport ladder, measured 2026-08-22 through Apify:**

| Rung | Search resource | Page 2 (bookmark) | Videos scope | Creator profile | Pin detail |
|---|---|---|---|---|---|
| Bare GET, any rung (no browser headers) | **403**, 24-byte body, no vendor wall (0/9) | — | — | — | — |
| Direct, browser header shape | 200, 18 pins | 200, 25 pins, 0 overlap | 200, 25 pins | 200 | 200 |
| **Apify datacenter (default)** | 200, 18 pins | 200, 25 pins, 0 overlap | 200, 25 pins | 200 | 200 |
| Apify RESIDENTIAL + US | 200, 18 pins | 200, 25 pins, 0 overlap | 200, 25 pins | 200 | 200 |

**Sustained load — the platform runs whose datasets we can show you:**

| Test | Result |
|---|---|
| Shipped default, datacenter, 2026-08-27 22:29 | 50 pins from 3 pages + **43 / 43** profiles, 0 failed, 0 of 48 requests fell back to residential, 39 s |
| Shipped default, datacenter, 2026-08-27 01:46 | 50 pins from 3 pages + **48 / 48** profiles, 0 failed, 0 of 52 requests fell back, 29 s |
| Shipped default, datacenter, 2026-08-22 17:43 | 50 pins from 3 pages + **47 / 47** profiles, 0 failed, 0 of 50 requests fell back, 19 s |
| All seven platform runs to date | 320 rows, 0 profiles failed, 0 requests ever needed the residential fallback |

So the default is the cheap datacenter rung. Search and creator-profile requests retry up to three
times on a fresh session (pin-detail fetches twice); a 403/429 that survives them gets **one
capped retry pass through RESIDENTIAL with a pinned session** (cap = 20% of the run's requests,
minimum 10), and the log prints "residential fallback used for N of M requests" on every run. A request that fails every rung
is never pushed and never billed.

**`robots.txt`.** Pinterest's robots file declares, for every agent not on its allow-list:

```
User-agent: *
Disallow: /
```

Named search-engine and preview bots are allow-listed for `/resource/*/get/` specifically. This
Actor does not impersonate any of them — it sends an ordinary Chrome user-agent — and it reads
only what a logged-out visitor's browser requests. You are responsible for deciding whether that
fits your use.

***

### Duplicates — measured

| Walk | Pins returned | Unique | Duplicates |
|---|---|---|---|
| Page 1 → page 2 of one keyword | 18 + 25 | 43 | **0** |
| One keyword, 3 pages — the shipped default, on each of the six 50-pin platform runs | 50 | 50 | **0** |

Pinterest's bookmark cursor does not repeat pins within a keyword. Across keywords it can — a
popular pin ranks for "boho bedroom" and "bedroom decor" alike — and the Actor keeps a run-wide
set keyed on `pinId`, drops the repeat **before** any enrichment fetch or charge, and **asserts
uniqueness across everything it pushed** before the run is allowed to succeed. If that assertion
ever fails, the run errors instead of handing you a dirty dataset.

***

### When a run fails

This Actor fails loudly rather than handing back a quiet empty dataset:

- **0 rows** → the run ends with a status message naming the cause: every search page failed
  (with the HTTP 403/429 count, so you can tell rate-limiting from a typo), the response shape
  was not recognised (a Pinterest change — please report it), every pin was removed by your
  filters, or the keyword genuinely returned nothing.
- **Stale app version** → a 403 after start triggers one fresh read of Pinterest's app version
  from the page, then the retry.
- **Duplicate leak** → the uniqueness assertion fails the run.
- **Run time budget** → collection stops before the platform timeout, everything collected is
  pushed and billed, and the status message says so.
- **Charge cap** → the Actor reads the run's *max total charge* at startup and stops at the number
  of pins it can cover instead of fetching rows it could never deliver.

A run that returns fewer rows than you asked for because Pinterest ran out of results is a log
line, not an error.

***

### Who buys this

- **Influencer and creator-partnership teams** — `creatorMonthlyViews`, `pinnerFollowers`,
  `creatorInstagram` and a contact email on the creators already ranking for your category.
- **Affiliate and e-commerce marketers** — `linkDomain` shows who is sending Pinterest traffic
  where (`amzn.to`, Etsy shops, Shopify stores); `products` carries price and stock on the rare
  pin where Pinterest attaches a shoppable summary — 0 of 320 rows so far, so treat it as a bonus,
  not as the product.
- **Agencies selling Pinterest management and SEO** — business accounts with a website but no
  verified domain, or high monthly views on a tiny follower count, are a ready-made prospect
  list.
- **Content and trend teams** — `visualTags`, `hashtags`, `createdAt` and reactions for what is
  ranking this week, on a schedule.
- **Brand monitoring** — `linkDomain` filtered to your domain, or your competitors'.
- **AI agents** — keyword in, structured pins + creator contacts out, pay-per-event, limited
  permissions.

***

### FAQ

**Does this need an account, a login or cookies?**
No. The Actor sends the same request a logged-out browser sends, with that browser's headers.
No cookie, no CSRF token, no browser automation, no CAPTCHA solving.

**Why are there no save counts?**
Pinterest's search resource does not publish them. Switch on *Include save counts* and the Actor
fetches each pin's detail resource — same price, about 0.5–1 s per pin.

**How many pins can one keyword return?**
Pinterest keeps paginating popular keywords well past 1,000. `maxPinsPerQuery` is the bound.

**Two keywords — will I get duplicates?**
Within a run, never: dedupe is on `pinId` and is asserted before the run can succeed.

**Do I get charged for a creator with no contact?**
No. `creator-contact-found` is charged only when the profile carried a website, email, phone or
Instagram handle — and once per creator, however many of their pins you received.

**Do I need a residential proxy?**
No. On the latest platform run the datacenter rung fetched 3 search pages and 43 of 43 creator
profiles with 0 failures, and none of the run's 48 requests fell back. The Actor falls back to
RESIDENTIAL automatically (capped) if the datacenter pool is ever rate-limited.

**Will a run ever succeed with zero rows?**
It ends SUCCEEDED with a status message naming the cause and bills nothing — a FAILED run would
only hide the reason behind a red badge.

***

### Legal & fair use

This Actor reads Pinterest's public search, profile and pin resources exactly as a logged-out
visitor's browser does. It does not log in, does not use cookies, and does not solve or bypass
any challenge. Pinterest's `robots.txt` carries a blanket `User-agent: * / Disallow: /` (quoted
above); the Actor does not impersonate any allow-listed crawler.

Rows can contain personal data — pinner names, and the contact email or phone a business
account chose to publish on its public profile. **You are responsible for complying with
Pinterest's terms of service and with how you use the data**, including GDPR, CCPA and the rules
on unsolicited marketing in your jurisdiction.

Pinterest® is a trademark of Pinterest, Inc. This Actor is not affiliated with, endorsed by, or
connected to Pinterest.

***

### Feedback

Found a missing field or want a new filter? Open an issue on the **Issues** tab, and if the
Actor earns it, a review on the **Reviews** tab helps other buyers find it.

# Actor input Schema

## `queries` (type: `array`):

Pinterest search terms, one per line — exactly what you would type into the Pinterest search box ("boho bedroom", "vegan meal prep", "logo design inspiration"). Each keyword is walked page by page (about 25 pins per page) until "Max pins per search" is reached or Pinterest runs out of results. Pins that rank for more than one keyword are returned once and billed once.

## `startUrls` (type: `array`):

Paste Pinterest search pages directly instead of, or alongside, keywords — e.g. https://www.pinterest.com/search/pins/?q=modern%20kitchen or https://www.pinterest.com/search/videos/?q=desk%20setup. The keyword and scope (pins / videos) are read from the URL.

## `scope` (type: `string`):

PINS = Pinterest's normal pin results for the keyword (images, idea pins and the occasional video — 1% of rows were videos on a 390-pin sample). VIDEOS = only video pins; every row then carries videoUrl, videoDurationSec and videoThumbnailUrl. Both produce the identical row shape.

## `enrichCreators` (type: `boolean`):

ON (default): one extra request per unique pinner adds creatorWebsite, creatorDomain + creatorDomainVerified, creatorContactEmail and creatorContactPhone (published by business accounts), creatorInstagram, creatorAbout, creatorLocation, creatorIsBusiness, creatorMonthlyViews and pin / board / following counts. Billed as a separate 'creator-contact-found' event ONLY when a website, email, phone or Instagram handle is actually found (measured 2026-08-22: 27.5% of 40 creators had a website, 52.5% were business accounts). A profile with no contact is fetched but never charged. OFF: the creator\* columns stay present and null.

## `onlyWithCreatorContact` (type: `boolean`):

Keep only pins whose creator profile carried a website, contact email, contact phone or Instagram handle — a pure lead list. Turns creator enrichment on. Pins removed by this filter are never billed, but note the Actor still has to fetch the search pages and profiles to find out, so a run returns fewer rows per page than the limits suggest.

## `includeSaveCounts` (type: `boolean`):

Pinterest's search results do NOT carry save counts — only reactions. Switching this on opens each pin's detail resource once and fills saveCount, repinCount, commentCount and shareCount. Same price per pin; it costs time (about 0.5-1 s per pin at the default concurrency), not money.

## `onlyWithLink` (type: `boolean`):

Drop pins that were uploaded directly with no destination URL. 59.5% of pins carried a link on a 390-pin sample, so this removes roughly 4 in 10. Applied from the search row BEFORE any enrichment fetch — filtered-out pins cost nothing and are never billed.

## `maxItems` (type: `integer`):

Stop after this many unique pins across all searches. Your hard cost ceiling for the pin event: 50 = $0.15, 500 = $1.50, 1,000 = $3.00. Duplicates are dropped before billing and never count against it.

## `maxPinsPerQuery` (type: `integer`):

How deep to walk each keyword. Pinterest serves about 25 pins per page and keeps paginating for popular terms well past 1,000, so this is what bounds a broad keyword. Measured 2026-08-22: 18 of 18 pages returned 18-25 pins with 0 overlap between consecutive pages.

## `maxConcurrency` (type: `integer`):

Parallel creator-profile / pin-detail fetches. Search pages are always walked one at a time (each page needs the previous page's bookmark). Measured 40/40 profiles at concurrency 4 through the Apify datacenter proxy. Values above 8 are rejected by the schema.

## `proxyConfiguration` (type: `object`):

Measured 2026-08-22 against Pinterest's search resource: direct 3/3, Apify datacenter 18/18 search pages + 40/40 creator profiles, Apify RESIDENTIAL 3/3 — so the default is the CHEAP datacenter rung rather than billing you for residential IPs you do not need. If the datacenter pool is ever rate-limited (HTTP 403/429), the Actor automatically retries those requests through RESIDENTIAL with a pinned session, capped at 20% of the run. Pick RESIDENTIAL here only if you see repeated failures in the log.

## Actor input object example

```json
{
  "queries": [
    "home office ideas"
  ],
  "startUrls": [],
  "scope": "pins",
  "enrichCreators": true,
  "onlyWithCreatorContact": false,
  "includeSaveCounts": false,
  "onlyWithLink": false,
  "maxItems": 50,
  "maxPinsPerQuery": 50,
  "maxConcurrency": 4,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `items` (type: `string`):

One row per unique pin found for your keyword(s): pin id and URL, title, description, alt text, hashtags, full-size image URL and dimensions, dominant colour, outbound link and its domain, video URL where the pin is a video, reaction count, created date, promoted flag, pinner username / name / follower count / verified-merchant flag, board name and URL, shoppable products where Pinterest attaches them, and — when creator enrichment is on — the pinner's website, location, bio and profile counts. Deduplicated run-wide on pin id, so a pin that ranks for two of your queries is billed once.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "queries": [
        "home office ideas"
    ],
    "maxItems": 50,
    "maxPinsPerQuery": 50,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapersdelight/pinterest-search-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "queries": ["home office ideas"],
    "maxItems": 50,
    "maxPinsPerQuery": 50,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapersdelight/pinterest-search-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": [
    "home office ideas"
  ],
  "maxItems": 50,
  "maxPinsPerQuery": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call scrapersdelight/pinterest-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapersdelight/pinterest-search-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/FtfFhizUxyhnVSf2V/builds/gM6j9vCM59l0K0oTH/openapi.json
