# Pinterest Scraper & Monitor - Pins, Boards, Trends (`thirdwatch/pinterest-scraper`) Actor

Scrape and monitor public Pinterest pins from search, user feeds, boards, and pin URLs. Get images, products, videos, and engagement via fast HTTP.

- **URL**: https://apify.com/thirdwatch/pinterest-scraper.md
- **Developed by:** [Thirdwatch](https://apify.com/thirdwatch) (community)
- **Categories:** Social media
- **Stats:** 390 total users, 83 monthly users, 99.9% runs succeeded, 2 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.20 / 1,000 results

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 Scraper & Monitor

> **Thirdwatch portfolio:** 8,800+ users across 140+ public Actors, 2M+ records delivered, >95% run success. [Explore all Thirdwatch Actors](https://apify.com/thirdwatch).

### What you get

Scrape public Pinterest search results, pins from user feeds, boards, and individual pins. Collect full-resolution images, destination links, creator and board data, product and video metadata, and public engagement counts. Turn on monitoring to emit only new pins or engagement changes on scheduled runs.

The Actor reads Pinterest's public web resources directly. It does not require a Pinterest login or browser-based access.

### Why use this Pinterest scraper?

- **Four sources in one Actor:** keywords, usernames, board URLs, and pin URLs.
- **Incremental monitoring:** schedule a Task and receive only newly discovered pins or changed public engagement metrics.
- **Commercial fields:** distinguish the canonical `pin_url` from the pin's `outbound_url`, and identify product, price, currency, availability, video, and Story Pin metadata when Pinterest exposes it.
- **Research context:** every row includes its input source, result position, creator, board, image dimensions, and scrape timestamp.
- **Low operating cost:** efficient, login-free collection keeps per-result pricing low, with further discounts at higher usage tiers.

### Quick start

Search for visual trends:

```json
{
  "searchQueries": ["home office ideas", "summer fashion trends"],
  "maxResults": 100,
  "includeDetails": true
}
```

Monitor a board for new pins:

```json
{
  "boardUrls": ["https://www.pinterest.com/pinterest/official-news/"],
  "maxResults": 100,
  "monitorMode": "new-pins",
  "monitorStoreName": "official-news-watch"
}
```

Run the same input on a schedule. The first run establishes a baseline and emits the current pins; later runs emit only pins that were not in that monitor's history.

### Input

Provide at least one source. Sources may be combined, and `maxResults` is the total cap across the run.

| Field | Type | Description |
|---|---|---|
| `searchQueries` | string\[] | Pinterest keyword searches. |
| `usernames` | string\[] | Public Pinterest usernames, with or without `@`. |
| `boardUrls` | string\[] | Full public Pinterest board URLs. |
| `pinUrls` | string\[] | Full Pinterest pin URLs for direct lookup. |
| `maxResults` | integer | Total pins to collect, from 1 to 10,000. Default: 10. |
| `includeDetails` | boolean | Adds public engagement, product, video, Story Pin, hashtag, and SEO fields with one extra HTTP request per pin. Detailed runs support up to 500 results. |
| `monitorMode` | string | `off`, `new-pins`, or `engagement-changes`. |
| `monitorStoreName` | string | Optional stable identity for a scheduled watch. Reuse it on every run. |

`engagement-changes` automatically enables detailed lookups. Monitoring fails without updating its state if Pinterest returns an incomplete response, so a temporary upstream error does not create false alerts.

### Output

One dataset row represents one current pin or one monitoring event.

```json
{
  "pin_id": "123456789",
  "title": "Modern home office setup",
  "description": "A compact workspace with natural light",
  "pin_url": "https://www.pinterest.com/pin/123456789/",
  "outbound_url": "https://example.com/workspace-guide",
  "image_url": "https://i.pinimg.com/originals/...jpg",
  "image_width": 1200,
  "image_height": 1800,
  "pinner_username": "designstudio",
  "pinner_followers": 18400,
  "board_name": "Small Office Ideas",
  "board_pin_count": 342,
  "saves_count": 91,
  "reaction_count": 14,
  "repin_count": 37,
  "comment_count": 3,
  "share_count": 5,
  "is_product": false,
  "is_video": false,
  "source_type": "search",
  "source_value": "home office ideas",
  "position": 1,
  "change_type": "engagement-change",
  "changed_fields": ["saves_count", "repin_count"],
  "scraped_at": "2026-07-20T08:00:00+00:00"
}
```

Important URL semantics:

- `pin_url` is always the canonical Pinterest pin page.
- `outbound_url`, `url`, and `link` are the external destination attached to the pin. `url` and `link` remain compatibility aliases for existing integrations.

Detailed fields can be absent when Pinterest does not publish them for a pin. `likes_count` remains a backward-compatible numeric alias and defaults to `0`; use nullable `saves_count` when distinguishing unavailable data from an observed zero. Pinterest's public payload describes this metric as saves, not likes.

### Monitoring behavior

| Mode | First run | Later scheduled runs |
|---|---|---|
| `off` | Current snapshot | Current snapshot |
| `new-pins` | Current pins marked `new` | Only pin IDs first seen by this monitor |
| `engagement-changes` | Current pins marked `new` | New pins plus changed saves, reactions, repins, comments, or shares |

Monitoring history is stored in a dedicated Apify key-value store and capped at 20,000 pin IDs per watch. An evicted pin can be classified as new if it later reappears. State is written only after dataset events are published, providing at-least-once delivery if a run is interrupted. Avoid overlapping runs with the same monitor name; schedule the next run after the previous one can finish.

### Use cases

- Track competitor boards and content cadence.
- Discover rising visual, fashion, home, food, wedding, and product trends.
- Monitor engagement movement for campaign and creator reporting.
- Build product-research, moodboard, or creative-brief datasets.
- Find destination domains and product pins in a niche.
- Feed Pinterest research into Sheets, webhooks, Make, Zapier, or your data warehouse.

### Limitations

- Only data visible through Pinterest's public, logged-out web surfaces is returned. Private boards and account-only data are unavailable.
- Pinterest may omit engagement, product, price, video, or Story Pin fields for individual pins.
- User feeds can include pins a user saved; they are not guaranteed to include only original creations.
- Deleted pins and removals are not emitted as events. Monitoring detects additions and available engagement changes.
- Pinterest CDN URLs can change. Download assets you need to retain long term in accordance with applicable rights and terms.

### FAQ

#### Do I need a Pinterest account or API key?

No. The Actor works with public Pinterest pages and resources.

#### Can I monitor several boards independently?

Yes. Create one saved Task per watch and give each a distinct `monitorStoreName`. Schedule the Tasks at the cadence you need.

#### Why is an engagement count null?

Pinterest does not expose every metric on every pin. The Actor returns a value only when the public payload supplies it and does not turn a temporary omission into a false zero.

#### Does detailed mode use a browser?

No. It performs one additional HTTP detail request per pin, so it is richer but slower than the default snapshot.

#### Is this an official Pinterest API?

No. This is an independent scraper for publicly accessible web data and is not affiliated with Pinterest.

### Related Actors

- [Instagram Scraper - Posts, Profiles & Engagement](https://apify.com/thirdwatch/instagram-scraper) — Thirdwatch
- [TikTok Scraper - Videos, Creators & Trends](https://apify.com/thirdwatch/tiktok-scraper) — Thirdwatch

Last verified: 2026-07-20

Explore more production scrapers at [thirdwatch.dev](https://thirdwatch.dev).

# Actor input Schema

## `searchQueries` (type: `array`):

List of search terms to find pins for. Examples: 'minimalist bedroom', 'web design inspiration', 'healthy recipes'.

## `usernames` (type: `array`):

List of Pinterest usernames to scrape pins from. Example: 'pinterest', 'interiordesign'.

## `boardUrls` (type: `array`):

List of Pinterest board URLs to scrape pins from. Example: 'https://www.pinterest.com/username/board-name/'.

## `pinUrls` (type: `array`):

List of specific Pinterest pin URLs to scrape. Example: 'https://www.pinterest.com/pin/123456789/'.

## `includeDetails` (type: `boolean`):

Fetch each pin's public detail payload for engagement counts, video, Story Pin, product, hashtag, and SEO fields. Adds a little time per pin and supports up to 500 results.

## `monitorMode` (type: `string`):

Off returns the current snapshot. New pins emits only pins first seen by this watch. Engagement changes emits new pins plus changes in public save, reaction, repin, comment, or share counts.

## `monitorStoreName` (type: `string`):

Stable name for this watch. Reuse the same name on scheduled runs. If omitted, the Actor derives one from the watched inputs.

## `maxResults` (type: `integer`):

Maximum total number of pins to scrape across all inputs.

## Actor input object example

```json
{
  "searchQueries": [
    "minimalist kitchen design"
  ],
  "usernames": [],
  "boardUrls": [],
  "pinUrls": [],
  "includeDetails": false,
  "monitorMode": "off",
  "maxResults": 10
}
```

# Actor output Schema

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

No description

# 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 = {
    "searchQueries": [
        "minimalist kitchen design"
    ],
    "maxResults": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("thirdwatch/pinterest-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 = {
    "searchQueries": ["minimalist kitchen design"],
    "maxResults": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("thirdwatch/pinterest-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 '{
  "searchQueries": [
    "minimalist kitchen design"
  ],
  "maxResults": 10
}' |
apify call thirdwatch/pinterest-scraper --silent --output-dataset

```

## MCP server setup

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