# Pinterest Search Scraper — Pins, Ranks & Linked Websites (`northbell/pinterest-search-scraper`) Actor

Pinterest search scraper: pins for a keyword with rank, the website each pin links to and rank changes since your last run, plus a free list of the websites behind the top pins. No login, no API key.

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

## Pricing

from $0.80 / 1,000 pins

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Pinterest Search Scraper — Pins, Ranks & Linked Websites

Give it keywords and get the pins Pinterest shows for them, in order: **rank and the website each pin links to**, plus title, description, image, date and a video flag. **$1 per 1,000 pins**, no login, no API key.

**Try it now — the input is already filled in.** Press **Start**: the example keyword (`kitchen ideas`) returns 100 pins in Pinterest's order in about 11 seconds, for about $0.11, plus a free summary row of the websites behind them.

| `rank` | `domain` | `previousRank` | `rankChange` | `title` |
| --- | --- | --- | --- | --- |
| 1 | tilebar.com | 1 | 0 | Explore Montauk Gin 2x8 White Ceramic Subway Wall… |
| 3 | thewoodmeter.com | 3 | 0 | Kitchen Trends to Avoid in 2026 |
| 5 | dreambundles.com | 11 | 6 | 6 Must-See Unique Kitchen Ideas for 2026 |

That run was on an account that had searched the same keyword before, so `previousRank` and `rankChange` are filled (dreambundles.com moved up 6). On your first run they are empty; from the second run of the same keyword they fill in. The summary row of that run: 62 of the 100 pins linked to a website, 46 different domains, paintloving.com the most often (6 pins).

Run it again — or put it on a daily schedule — and every pin also tells you **where it ranked last time**: `previousRank`, `rankChange` (positive = moved up) and `isNew`. Each keyword also gets a free **summary row with the websites behind the top pins**: which domains Pinterest's results send people to for that keyword, how many pins each has and its best rank.

**Save counts (since about 20 October 2026):** Pinterest now gives logged-out visitors a hidden pin id in search results, and the pin's own page answers "Pin not found" for it, so the number of saves can no longer be read without an account. `saves` is `null` for those pins and the summary `note` says how many. This Actor does not log in. Rank, website, title, image and the change since your last run are unaffected.

### What you get

| Field | What it is |
|---|---|
| `query`, `rank` | the keyword and the position among its pins, in Pinterest's order (ads are not counted, repeated pins are removed) |
| `previousRank`, `rankChange`, `isNew` | compared with your previous run of the same keyword (`null` on the first run; positive `rankChange` = moved up; `isNew` is `true` when the pin was not among the pins read last time) |
| `pinId`, `url` | the pin and its Pinterest address |
| `title`, `description` | as written on the pin, as plain text with **email addresses, phone numbers and @usernames removed**. `title` falls back to the grid title or to the page title Pinterest read from the website; either can be `null` |
| `link`, `domain` | the website the pin points to and its domain (`amazon.com`, `boredpanda.com`). **`null` for pins that were uploaded directly to Pinterest** |
| `imageUrl` | the original image |
| `pinnerName`, `pinnerUsername`, `boardName`, `boardUrl` | who saved the pin (public display name and username) and the board it is on (empty with *Leave out people's names*, except the board name) |
| `saves` | how many times the pin has been saved, when Pinterest still shows it to logged-out visitors; `null` otherwise (see above) |
| `reactions` | the reactions Pinterest shows on the pin (not saves) |
| `isVideo`, `createdAt` | `true` for video pins and idea pins with video; when the pin was created (ISO date) |
| `observedAt` | when this row was read |

One extra row per keyword (`type: "summary"`, free): **`relatedSearches`** (the related searches Pinterest offers above the results, best first — keyword ideas straight from Pinterest), `pinsRead`, `pinsWithWebsite`, `uniqueDomains`, **`topDomains`** (the 10 domains with the most pins: `domain`, `pins`, `share` of the pins that link out, `totalSaves`, `bestRank`), `medianSaves`, `newSinceLastRun`, `previousRunAt`, `complete` and a `note`.

### Use it for

- **Pinterest SEO and content planning** — see what ranks for a keyword, how much it gets saved and how old it is, before you create a pin
- **Finding who is behind the top pins** — the blogs, shops and marketplaces that win a keyword, with their pins and best rank, in one row per keyword
- **Keyword research** — every summary row lists Pinterest's own related searches; set **Also search the related searches** to get their pins and ranks in the same run (rows say `relatedTo`)
- **Rank tracking** — schedule it daily and watch your own site's pins (filter `domain`) or a competitor's move up and down

### Input

```json
{ "queries": ["kitchen ideas", "boho bedroom"], "maxPinsPerQuery": 100, "includeSaves": true }
```

A Pinterest search URL (`https://www.pinterest.com/search/pins/?q=kitchen%20ideas`) works in place of a keyword. Rankings are remembered per keyword (capital letters and extra spaces are ignored) in a named key-value store in your Apify account, so the second run of the same Actor already shows changes. Schedule it (Apify → Schedules) for a daily history.

### Pricing

**$1 per 1,000 pins**, plus $0.01 per run. Summary and error rows are free. The $0.01 run-start fee is the one charge every run pays, even one that returns nothing.

### Notes

- **Saves need one extra request per pin, and most pins no longer show them** (see the top of this page). Pinterest does not put saves in its search results, so with *Read the number of saves* on (the default) the Actor opens each pin's own page: about 100 pins take 20 seconds and 750 pins under 3 minutes in the 8 October 2026 checks. Turn it off for a faster run; `saves` is then `null` and everything else is the same. `saves` is also `null` for a pin that has been removed since the search, or when Pinterest limits the requests (the summary `note` says so).
- **Pins without a website.** Pins uploaded straight to Pinterest have no outbound link, so `link` and `domain` are `null` for them: 41 of the first 100 pins for "kitchen ideas", 14% of 752 pins for "modern farmhouse decor" and 84% of 120 pins for "tattoo ideas" in the 8 October 2026 checks, so it depends a lot on the keyword. `share` in `topDomains` is the share of the pins that do link out.
- **How deep it goes.** Pinterest's search ends after roughly 750 to 1,100 pins for broad keywords and earlier for narrow ones, so asking for 1,000 can return fewer. `pinsRead` and the `note` in the summary row say how many you got and why it stopped. Pinterest also returns pins for keywords it does not know, so an unusual keyword still gives results.
- **What "rank" is.** The order a signed-out visitor sees. Apify's servers are in the US, so results are what a US visitor gets; Pinterest personalises for signed-in users, so your own screen can differ.
- **Since the last run.** `isNew` is `null` when you read more pins than last time and the pin lies beyond the part you read before (it cannot be told whether it is new). A run that fails, or that stops before it has read as many pins as the remembered list holds, does not replace the remembered ranks.
- Public data only: what anyone sees without signing in. The pinner's public display name and username are returned; follower counts and profiles are not, and `@usernames` written into titles and descriptions are removed. Turn on **Leave out people's names** (`omitPersonalNames`) and the pinner fields stay empty: useful for GDPR-minded projects in the EU that should hold no personal data.

To find which keywords to track, see [Keyword Suggestions — Google, YouTube & Amazon Autocomplete](https://apify.com/northbell/keyword-suggestions-autocomplete). To check whether interest in a topic is rising or fading, see [Google Trends Scraper](https://apify.com/northbell/google-trends-tracker).

### For AI agents

`{"queries": ["boho bedroom"], "maxPinsPerQuery": 20}` returns 20 ranked pins with the linked website, plus one summary row with the top domains. Rows have `type`: `pin`, `summary` or `error`.

# Actor input Schema

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

One keyword or phrase per line, exactly as you would type it into Pinterest search. A Pinterest search URL (pinterest.com/search/pins/?q=…) also works.

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

How many pins to read for each keyword, in the order Pinterest shows them (rank 1 first). Pinterest's search ends at roughly 1,000 pins for broad keywords, so you may get slightly fewer than you ask for.

## `includeSaves` (type: `boolean`):

Pinterest does not show saves in search results, so this reads each pin's own page (one extra request per pin) to fill in saves. Since about 20 October 2026 most pins have a hidden id for logged-out visitors and their saves cannot be read; those stay empty. Turn it off for a faster run: the saves column is then empty and everything else is the same.

## `searchRelated` (type: `integer`):

Pinterest shows related searches above the results (for "garden ideas": fairy garden ideas, small garden ideas…). They are always listed in each keyword's summary row (relatedSearches, free). Set a number here to also search the first N of them, with the same pins per keyword; their rows carry relatedTo and their pins are charged like any pin. 0 = off. At most 50 extra searches per run.

## `omitPersonalNames` (type: `boolean`):

Off: names and handles are returned as shown publicly. On: they are left out (empty), for GDPR-minded projects that need no personal data.

## Actor input object example

```json
{
  "queries": [
    "kitchen ideas"
  ],
  "maxPinsPerQuery": 100,
  "includeSaves": true,
  "searchRelated": 0,
  "omitPersonalNames": false
}
```

# Actor output Schema

## `pins` (type: `string`):

Pins in Pinterest's order with saves, the website they link to and rank changes since the last run.

## `summary` (type: `string`):

One row per keyword: how many pins link out, which domains appear most, and how many pins are new since the last run.

# 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": [
        "kitchen ideas"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("northbell/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": ["kitchen ideas"] }

# Run the Actor and wait for it to finish
run = client.actor("northbell/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": [
    "kitchen ideas"
  ]
}' |
apify call northbell/pinterest-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,northbell/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/bm8gqyTdkknhcEwGD/builds/bRqPp9vuCT7mHF3Jh/openapi.json
