# Pinterest Search & Pin Engagement Scraper (`simpleapi/pinterest-search-scraper`) Actor

Pinterest Search Scraper extracts Pins from Pinterest search results, capturing titles, descriptions, image URLs, outbound links, creators, and engagement metrics. Ideal for trend research, inspiration mining, SEO analysis, and automating structured Pinterest search data collection at scale.

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

## Pricing

$19.99/month + usage

To use this Actor, you pay a monthly rental fee to the developer. The rent is subtracted from your prepaid usage every month after the free trial period. You also pay for the Apify platform usage, which gets cheaper the higher Apify subscription plan you have.

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

## 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 Scraper — Search Results Ranked by Engagement

Pinterest Search & Pin Engagement Scraper searches Pinterest by keyword and returns an engagement-ranked result set — every pin scored and ranked by save count, plus domain/creator roll-ups, hashtags, color palette, and honest cross-run trend deltas. No Pinterest login is required. It's built for content researchers, SEO/Pinterest marketers, and trend analysts who need to know which pins in a niche are actually performing, not just a raw search grid.

### What is Pinterest Search & Pin Engagement Scraper?

Pinterest Search & Pin Engagement Scraper is an Apify Actor that searches Pinterest for a keyword and computes engagement rank, percentile, and aggregate analytics across the returned result set. Key capabilities:

- Search by keyword, filtering to all pins or videos only
- Compute per-pin `engagementRank` and `engagementPercentile` by save count, plus aggregate roll-ups (top domains, top creators, hashtags, color palette)
- Optionally fetch save/comment counts via an extra per-pin closeup request — coverage is honestly partial and reported, never faked
- Filter by minimum save/comment count, best-effort (pins with unknown counts are kept, not silently dropped)
- Track real cross-run trend deltas (`isNew`, `rankDelta`, `firstSeenAt`) via a named key-value store snapshot — the first run is always a baseline, never a fabricated history
- Deduplicate pins by canonical pin ID

### What data can I extract with Pinterest Search & Pin Engagement Scraper?

| Field | Example Value | Use Case |
| --- | --- | --- |
| `title` / `domain` / `link` | `"Minimalist Home Office Ideas"` / `"pinterest.com"` / destination URL | Identify the pin and its destination |
| `pinUrl` / `image_url` | Pinterest pin link / CDN image URL | Direct link and visual reference |
| `saveCount` / `saveCountSource` | `1240` / `"closeup"` | The core engagement metric, with its data source disclosed |
| `commentCount` | `18` | Secondary engagement signal (best-effort) |
| `engagementRank` / `engagementPercentile` | `3` / `98.5` | See exactly how this pin ranks within this run's result set |
| `isNew` / `rankDelta` / `isFirstSnapshot` / `firstSeenAt` | `false` / `+5` / `false` / `"2026-06-01T10:00:00Z"` | Real cross-run trend signals |
| `hashtags` / `dominant_color` | `["#homeoffice", "#minimalist"]` / `"#E8DCC8"` | Content and visual-style signals |
| `isVideo` / `type` | `false` / `"pin"` | Filter by content format |
| `createdAtISO` / `scrapedAt` | pin creation date / collection timestamp | Confirm timing |

#### Real save-count coverage, honestly disclosed

`saveCount` is not always available from Pinterest's search grid alone. `fetchSaveCounts` (off by default) triggers an extra per-pin closeup fetch to recover save and comment counts that the grid doesn't include — but this coverage is explicitly partial and reported via `saveCountSource`, never silently faked as a zero. `engagementRank`/`engagementPercentile` are computed only from pins with a known save count; pins without one are honestly excluded from ranking rather than assigned a fabricated rank.

#### Real cross-run trend tracking — never a fabricated time series

`isNew`, `rankDelta`, and `firstSeenAt` come from a genuine per-pin snapshot comparison: this run's result set is written, keyed by pin ID, to a named key-value store, and compared against the previous snapshot for that same search term. Runs are stateless — the first run against a given `trendSnapshotKey` is always a baseline (`isFirstSnapshot: true`, null deltas), never a fabricated trend. Leave `trendSnapshotKey` blank to auto-derive one from the search term and content type, so re-running the same query automatically builds a trend over time.

### Why not build this yourself?

Pinterest's official API requires app review and business-account approval, and doesn't expose a general keyword-search-with-engagement-ranking capability to third-party developers in the way this Actor provides. Building an equivalent tool yourself means handling Pinterest's aggressive datacenter-IP blocking (residential proxy is required for reliable results), building the save-count-based ranking/percentile math with honest null-handling, and implementing the cross-run KV-store snapshot diffing for real trend deltas. All of that is already implemented in this Actor's source.

### How to use data extracted from Pinterest?

#### Content research and Pinterest SEO

Search your target niche keyword and use `engagementRank`/`hashtags`/`dominant_color` to see which pin styles, hashtags, and color palettes are performing best right now, informing your own pin design and hashtag strategy.

#### Trend and campaign monitoring

Run the same `searchTerm` on a schedule with `enableTrendTracking` on and track `isNew`/`rankDelta` over time to see which pins are climbing the rankings versus dropping — a genuine trend signal, not a guess.

#### Competitive and domain research

Use the aggregate domain/creator roll-ups (stored as `ENGAGEMENT_SUMMARY` in the run's key-value store) to see which websites and creators dominate a search term's top results, informing competitive content strategy.

#### AI agents and automated pipelines

An agent can call this Actor to pre-rank a content niche's top-performing pins before generating a content brief, filtering on `engagementPercentile` to focus only on genuinely high-performing examples.

### 🔼 Input sample

| Parameter | Required | Type | Description | Example Value |
| --- | --- | --- | --- | --- |
| `searchTerm` | **Yes** | string | Keyword to search on Pinterest | `"minimalist home office"` |
| `contentType` | No | string (enum) | `all` (default) or `videos` | `"all"` |
| `maxPins` | No | integer (1-10,000) | Pins pulled into the analyzed result set | `100` (default) |
| `computeEngagementAnalytics` | No | boolean | Derive rank/percentile and aggregate roll-ups | `true` (default) |
| `fetchSaveCounts` | No | boolean | Extra per-pin closeup fetch for save/comment counts | `false` (default) |
| `closeupSampleSize` | No | integer (min 0) | Max pins closeup-fetched when `fetchSaveCounts` is on | `25` (default) |
| `minSaveCount` / `minCommentCount` | No | integer (min 0) | Best-effort minimum thresholds; `0` = off | `0` (default) |
| `deduplicatePins` | No | boolean | Drop duplicate pins by canonical pin ID | `true` (default) |
| `enableTrendTracking` | No | boolean | Write/compare a named KV snapshot for real trend deltas | `true` (default) |
| `trendSnapshotKey` | No | string | Named snapshot store; blank auto-derives from search term | `"pin-trend-home-office"` |
| `proxyConfiguration` | No | object | Residential proxy strongly recommended | `{"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}` |

```json
{
  "searchTerm": "minimalist home office",
  "maxPins": 200,
  "fetchSaveCounts": true,
  "enableTrendTracking": true
}
```

**Common pitfall:** without a residential proxy, Pinterest blocks datacenter IPs and the run returns zero pins — the default `proxyConfiguration` already uses `RESIDENTIAL`, so don't override it with a datacenter-only setting.

### 🔽 Output sample

Output is typed, normalized JSON — one row per pin, ranked by engagement within this run's result set (exportable as JSON, CSV, or Excel).

```json
{
  "node_id": "123456789012345678",
  "type": "pin",
  "isVideo": false,
  "title": "Minimalist Home Office Ideas",
  "domain": "pinterest.com",
  "link": "https://example.com/blog/home-office",
  "pinUrl": "https://www.pinterest.com/pin/123456789012345678/",
  "saveCount": 1240,
  "saveCountSource": "closeup",
  "commentCount": 18,
  "engagementRank": 3,
  "engagementPercentile": 98.5,
  "isNew": false,
  "rankDelta": 5,
  "isFirstSnapshot": false,
  "firstSeenAt": "2026-06-01T10:00:00Z",
  "hashtags": ["#homeoffice", "#minimalist"],
  "dominant_color": "#E8DCC8",
  "createdAtISO": "2026-05-15T08:00:00Z",
  "image_url": "https://i.pinimg.com/...",
  "scrapedAt": "2026-07-26T14:02:11Z"
}
```

All 21 fields shown above are the Actor's real dataset columns — this is the full output shape, not a subset.

### How do you filter and target specific pins?

`searchTerm` is the core query, with `contentType` narrowing to all pins or videos only. `minSaveCount`/`minCommentCount` are the genuine quality thresholds — both are best-effort, applying only to pins with a known count so pins with unresolved counts aren't silently dropped as if they failed a threshold they were never actually tested against. Volume is controlled by `maxPins` (the analyzed result-set size) and, when save-count fetching is on, `closeupSampleSize` (bounding the extra per-pin request cost).

```json
{ "searchTerm": "vegan recipes", "minSaveCount": 500, "fetchSaveCounts": true, "closeupSampleSize": 50 }
```

```json
{ "searchTerm": "wallpaper", "contentType": "videos", "maxPins": 300 }
```

```json
{ "searchTerm": "minimalist home office", "enableTrendTracking": true, "trendSnapshotKey": "pin-trend-home-office" }
```

### ▶️ Want to try other visual-content scrapers?

| Scraper Name | What it extracts |
| --- | --- |
| Instagram Reels Scraper With Engagement Analytics | Comparable engagement-rate analytics for Instagram Reels |
| Instagram Hashtag Scraper: Content Planner | Hashtag posts plus best-time and topic planning |
| TikTok Trending Hashtags With Momentum Analytics Scraper | Comparable trend/momentum analytics for TikTok |
| Facebook Photos Scraper & High-Res Photo Export | Comparable full-resolution image extraction for Facebook |
| Google Trends Scraper: Rising & Breakout Keywords | Comparable keyword-trend spike detection |
| Instagram Related Hashtag Stats Scraper By Keyword Search | Comparable keyword-to-content-tag research for Instagram |

### How to extract Pinterest data programmatically

Every run is a standard Apify Actor call — one API request with your token, JSON input, JSON results back. No Pinterest login required.

#### Python example

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_API_TOKEN>")

run_input = {
    "searchTerm": "minimalist home office",
    "maxPins": 200,
    "fetchSaveCounts": True,
}

run = client.actor("<YOUR_USERNAME>/pinterest-search-pin-engagement-scraper").call(run_input=run_input)

for pin in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(pin["title"], pin["engagementRank"], pin["saveCount"])
```

#### Export to spreadsheets or CRM

Export the dataset directly as CSV or Excel, then map `title`/`pinUrl` to a content-research spreadsheet and `engagementRank`/`hashtags` to a prioritization column for content planning.

### Is it legal to scrape Pinterest search results?

Pin titles, save counts, and hashtags are public content metadata, not personal data tied to an individual in most cases — this is closer to public content/business data. Public Pinterest search results are visible to any logged-out visitor. Consult legal counsel for commercial applications involving bulk automated querying of Pinterest's services.

### ❓ FAQ

#### How accurate is the engagement ranking?

`engagementRank`/`engagementPercentile` are computed directly from real save counts within this run's result set — pins without a known save count are honestly excluded from ranking, never assigned a fabricated rank.

#### How does the trend tracking actually work?

It's a genuine snapshot comparison, not a fabricated time series — this run's pins are saved to a named key-value store keyed by pin ID, and compared against the previous snapshot for the same search term. The first run against any `trendSnapshotKey` is always a baseline with null deltas.

#### Why is saveCount sometimes null?

Pinterest's search grid doesn't always include save counts. Enable `fetchSaveCounts` to trigger an extra per-pin closeup fetch to recover them — but coverage remains honestly partial and is disclosed via `saveCountSource`, never silently faked.

#### How many pins can I get per run?

`maxPins` (1-10,000, default 100) caps the analyzed result-set size.

#### Do I need a Pinterest account to use this?

No — Pinterest search results are accessible without login. A residential proxy is required for reliable access, since Pinterest blocks datacenter IPs.

#### Does Pinterest Search & Pin Engagement Scraper work with Claude, ChatGPT, and AI agent frameworks?

It has no dedicated MCP server registration in this Actor's current setup, but it is callable as a standard Apify API endpoint by any agent framework that can make an authenticated HTTP request and parse JSON.

#### How does this compare to other Pinterest scrapers?

No independently verifiable competitor listing could be confirmed at the time of writing, so no specific comparison is made here. This Actor's distinguishing feature is the combination of engagement ranking and genuine cross-run trend tracking via real snapshot diffing.

#### What happens to duplicate pins?

`deduplicatePins` (on by default) drops duplicates by canonical pin ID, so the same pin surfacing multiple times in search results only appears once in your output.

### Conclusion

Pinterest Search & Pin Engagement Scraper turns a keyword search into a ranked, trend-aware content-research dataset — real save-based engagement ranking and genuine cross-run trend deltas via snapshot diffing, honestly disclosed wherever coverage is partial. It's built for content researchers, Pinterest marketers, and trend analysts who need to know what's actually performing. Start a run with your search term to get engagement-ranked pins back in one pass.

# Actor input Schema

## `searchTerm` (type: `string`):

Keyword to analyze on Pinterest. Example: 'minimalist home office'. (Base-compatible: a 'query' key is also accepted.)

## `contentType` (type: `string`):

Analyze all pins or only video pins. (Base-compatible: a 'filter' key is also accepted.)

## `maxPins` (type: `integer`):

How many pins to pull into the analyzed result set (1–10,000). Rank & percentile are computed within this set. Example: 100. (Base-compatible: a 'limit' key is also accepted.)

## `computeEngagementAnalytics` (type: `boolean`):

Derive per-pin engagementRank & engagementPercentile (by save count where available) plus aggregate roll-ups (top domains, top creators, color palette, hashtags — stored in the run key-value store as ENGAGEMENT\_SUMMARY). Default true.

## `fetchSaveCounts` (type: `boolean`):

Do an extra per-pin closeup fetch to recover save & comment counts that are NOT in the search grid. HONEST: coverage is PARTIAL and reported; costs extra requests. Default false.

## `closeupSampleSize` (type: `integer`):

Max number of pins to closeup-fetch when 'Fetch Save / Comment Counts' is on (0 = all pins lacking a grid save count). Keeps cost bounded. Example: 25. Default 25.

## `minSaveCount` (type: `integer`):

Keep only pins with at least this many saves. Best-effort: applied only to pins with a known save count (pins with unknown counts are kept, not silently dropped). 0 = off. Default 0.

## `minCommentCount` (type: `integer`):

Keep only pins with at least this many comments. Best-effort, same rule as minimum saves. 0 = off. Default 0.

## `deduplicatePins` (type: `boolean`):

Drop duplicate pins by canonical pin id. Default true.

## `enableTrendTracking` (type: `boolean`):

Write a snapshot of this run keyed by pin id to a named key-value store, and emit delta fields (isNew, rankDelta, firstSeenAt) vs the previous snapshot. Default true.

## `trendSnapshotKey` (type: `string`):

Named key-value store to hold the trend snapshot. Leave blank to auto-derive one from the search term + content type (so re-running the same query builds a trend automatically). Example: 'pin-trend-home-office'.

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

Apify Residential proxy is strongly recommended — Pinterest blocks datacenter IPs and the run returns zero pins without a residential session.

## Actor input object example

```json
{
  "searchTerm": "wallpaper",
  "contentType": "all",
  "maxPins": 100,
  "computeEngagementAnalytics": true,
  "fetchSaveCounts": false,
  "closeupSampleSize": 25,
  "minSaveCount": 0,
  "minCommentCount": 0,
  "deduplicatePins": true,
  "enableTrendTracking": true,
  "trendSnapshotKey": "",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped items in the Actor's default dataset.

## `engagementSummary` (type: `string`):

Aggregate roll-ups for the run: totals, save-count coverage, top domains/creators/hashtags, color palette, and cross-run trend stats.

# 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 = {
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("simpleapi/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 = { "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    } }

# Run the Actor and wait for it to finish
run = client.actor("simpleapi/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 '{
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call simpleapi/pinterest-search-scraper --silent --output-dataset

```

## MCP server setup

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