# Pinterest Scraper: Pins, Boards and Search (`cleanscrape/pinterest-scraper`) Actor

Pinterest pins from searches, boards, public profile feeds and links. Export images, videos, source websites and available saves, with text filters and a research view. $1.25 per 1,000 pins, usage included. Maintained by CleanScrape.

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

## Pricing

from $1.00 / 1,000 exported 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 Scraper

Collect public Pinterest pins from search terms, boards, profile feeds or individual pin links. Keep the image and video references, descriptions, destination links and available engagement fields in one consistent export.

Use it to assemble design references, research content ideas or find the websites behind relevant pins. Alongside the dataset, you get a **visual research view with destination-domain counts** and a **coverage report** that explains what was scanned, filtered or unavailable.

**Base price: $1.25 per 1,000 exported pins.** No startup or separate enrichment fee. Normal platform and built-in proxy usage are included in the event price. Maintained by CleanScrape.

### Watch a real run

Let's use home-office research as an example. This short demo follows a real 50-pin run from the search settings to the Research view and Excel/CSV export.

https://www.youtube.com/watch?v=bl7tb0c8AG8

The demo uses **All query words** and enables **Include additional public pin details**. To open the visual report, choose **Research view** in Output, then open the **RESEARCH\_VIEW** record. Source websites appear only when Pinterest supplies a destination link.

For a focused spreadsheet, export **Research essentials**; choose **All fields** when you want the complete dataset.

### Start with an example

Let's research home-office ideas and find the original websites behind them.

1. Add `home office` under **Search terms**.
2. Set **Maximum pins** to `50`.
3. For a tightly matched list, choose **All query words** under **Search matching**. Leave Pinterest relevance selected for broader recommendations.
4. Click **Start**. Open **Output** for the pins, **Research view** for a visual preview and destination-domain counts, and **Run report** for coverage.
5. Export the dataset as CSV, Excel or JSON. Open `outboundUrl` to inspect an original source rather than treating the Pinterest link as the source website.

The same workflow works with your own topic. No Pinterest login, cookies, developer token or numeric board ID is required.

```json
{
  "searchTerms": ["home office"],
  "maxPins": 50,
  "searchMatching": "allWords"
}
```

### What can I collect?

| Input | What it returns |
| --- | --- |
| Search terms or Pinterest pin-search URLs | Public pins returned by Pinterest's search feed |
| Public board URLs | Available public pins from that board |
| Profile homepage URLs | Available public profile-feed pins, which may include saved pins |
| Individual pin URLs | The requested pin, with its available public details |
| `pin.it` links | The corresponding supported Pinterest page when the public redirect resolves |

You can combine up to 25 inputs. Pins are deduplicated by their ID within a run. A pin's source fields identify its **first accepted input**, not every query it might match. The maximum result count applies to the whole run; inputs are processed in the order provided.

Private boards, logged-in account data, comment text, board sections and exhaustive profile archives are not supported. Media URLs are provided as references; this Actor does not download or grant rights to the media files.

### Choose the results you need

| Setting | How to use it |
| --- | --- |
| Maximum pins | Your total output cap, from 1 to 5,000. Fewer results can be available. |
| Search matching | Pinterest relevance, all query words, or the exact phrase in the pin's title, description or alt text. Matching is case-insensitive and ignores punctuation. |
| Include any / Exclude any | Optional words or phrases in those same text fields. Exclusion takes priority. These are literal text filters, not AI classifications. |
| Media type | Keep all pins, image pins or video pins. |
| Pin creation date | Any date, last 7 days, last 30 days or last 90 days. No date-format entry needed. |
| Include details | Request the additional public pin-detail response. This can improve dates and engagement coverage, but unavailable fields remain null. No additional event charge. |
| Scan limit | Advanced safeguard limiting the number of feed pins examined, including duplicates and filtered pins. Default: at least 500, increasing with the requested output cap. |
| Connection | Automatic is recommended. It starts directly and uses bounded residential-proxy retries when needed. Direct and Residential are available for troubleshooting. |

Pinterest can return broad recommendations even for an obscure search. Use **All query words** or **Exact phrase** if relevance must be backed by the visible text. Strict matching can exclude useful synonyms and pins whose relevant text is only inside the image.

The date filter uses the pin's source-reported creation date, **not** the date it was saved to a board, the publication date of the linked article, or the time it became popular. Pins without a usable date are excluded when a date filter is selected. Missing dates trigger a best-effort detail lookup.

### Output you can work with

Each dataset row is a real exported pin, never a diagnostic or error record.

| Field | Meaning |
| --- | --- |
| `pinId`, `pinUrl` | Stable string ID and link to the Pinterest pin |
| `title`, `description`, `altText` | Public source text. The original title may be absent. |
| `displayTitle` | A readable label drawn from the title, description or alt text; not an invented title |
| `outboundUrl`, `outboundDomain` | The external destination supplied by Pinterest, if any |
| `imageUrl`, `thumbnailUrl` | Original/largest available image reference and preview reference |
| `videoUrl`, `videoDurationSeconds` | Available video stream/file reference and duration; a stream URL may be HLS rather than MP4 |
| `createdAt`, `createdAtRaw` | Normalized UTC pin creation date and original source value |
| `repinCount` | Pinterest's pin-level repin count, where supplied |
| `aggregateSaveCount` | Pinterest's separate aggregate save metric, where supplied |
| `commentCount`, `shareCount` | Public counts when available; not comment text or view counts |
| `pinnerUsername`, `pinnerUrl`, `boardName`, `boardUrl` | Public attribution supplied with that pin |
| `sourceType`, `sourceInput`, `sourceUrl`, `sourceRank` | First accepted input and position examined within its feed; not a global popularity rank |
| `detailsStatus`, `scrapedAt` | Whether optional details were obtained and when the row was collected |

Missing fields are `null`, not invented zeros. A real source-reported zero stays zero. Pinner attribution does not establish original authorship. Saves, comments and shares are different measures; none should be presented as views, sales or demand.

#### Research view and coverage

The **Research view** presents the first 200 exported pins with source links, destination-domain counts for the full export, and a per-input coverage table. It is a lightweight preview, not an extra paid dataset.

The machine-readable **Run report** records scanned/exported counts, filters, duplicate skips, detail failures, connection attempts and stopping reasons. `responseBytes` measures decoded response bytes, not billable proxy traffic. Check this report before treating the output as complete.

`result_limit` and `charge_limit` are intentional stops. `scan_limit`, repeated pagination, unavailable details and source failures can leave partial output. A source returning no public pins is labelled `empty_unverified`, not proof that the board or profile is empty. If every input fails, the run fails instead of reporting an empty success.

### Pricing and spending controls

The single billable event is **one unique pin stored in the output dataset**.

| Exported pins | Base event charge |
| ---: | ---: |
| 50 | $0.0625 |
| 100 | $0.125 |
| 1,000 | $1.25 |

There is no startup fee, no charge event for duplicates, filtered pins or the reports, and no separate enrichment event. Built-in proxy and platform usage are included in this pay-per-event price. The same pin collected in a separate fresh run is a new result and is charged again.

Store-tier discounts are **Bronze 10%, Silver 15% and Gold 20%** off base event prices; higher eligible tiers receive the Gold rate. Apify displays your applicable price before you run. Set **Maximum pins** and Apify's **maximum charge** to control spending.

On a graceful interruption, the Actor finishes an in-flight result write and saves a final report. If the process is forcibly stopped, the report can lag behind the dataset; its `checkpointAt` timestamp identifies the last saved snapshot. Already exported rows remain in the dataset. Resurrecting a run that already has output deliberately does not scrape or charge again. Start a fresh run to collect more data; automatic continuation of an interrupted export is not supported in this version.

### API and recurring use

Use the **API** tab for JavaScript, Python and HTTP examples with your own Apify credential. Never share that credential in a public workflow or screenshot. Saved tasks and Apify schedules can repeat the same input; webhooks and integrations can move the resulting dataset into your workflow.

Each scheduled run is a fresh snapshot. This Actor does not claim to detect new pins or changes across runs. Compare stable `pinId` values in your own system if you need that workflow, and keep incomplete coverage separate from confirmed removals.

### Limits and support

Pinterest controls public availability, ranking, pagination and rate limits. Results may differ from a logged-in or differently located browser. A maximum of 5,000 pins is an output cap, not guaranteed coverage. Requests and response sizes are bounded; difficult inputs may stop earlier. Image/video links and public fields can change after collection.

CleanScrape maintains this Actor and investigates reproducible issues. Use the **Issues** tab or email **contact.cleanscrape@gmail.com** with a run ID, a public example input and what you expected. Do not send passwords or API tokens. If it helped your workflow, an honest review is welcome. Feedback is never conditional on a positive rating.

**Disclaimer:** This is an independent tool, not affiliated with, endorsed by or sponsored by Pinterest. Pinterest and other trademarks belong to their respective owners. Use collected data in accordance with applicable terms, laws and creator rights.

# Actor input Schema

## `searchTerms` (type: `array`):

Add topics, one per line. Use search terms, Pinterest URLs, or both. Pinterest relevance can include broader recommendations.

## `pinterestUrls` (type: `array`):

Full HTTPS links to public pins, boards or profile homepages. Public pin.it links are resolved where possible.

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

Total unique exported pins across all inputs. This is a maximum, not a guaranteed result count.

## `searchMatching` (type: `string`):

Literal matching uses title, description and alt text. All query words helps exclude broad recommendations; synonyms may be missed.

## `includeAny` (type: `array`):

Optional. At least one phrase must appear in title, description or alt text. Case-insensitive, punctuation ignored.

## `excludeAny` (type: `array`):

Optional. Exclude pins containing any of these phrases in title, description or alt text.

## `mediaType` (type: `string`):

Keep the public pin media type you need. Video URLs are only included when Pinterest supplies them.

## `dateRange` (type: `string`):

Uses the pin creation date, not the date saved to a board or the linked article date. Pins with no usable date are excluded when filtering.

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

Best-effort extra lookup for dates and engagement fields. Slower, with no separate event fee; missing fields remain null.

## `maxPinsToScan` (type: `integer`):

Maximum feed pins examined, including filtered pins and duplicates. When omitted: max(500, five times Maximum pins), capped at 20,000.

## `connection` (type: `string`):

Automatic starts directly and uses bounded residential retries when needed. Built-in connection usage is included in the event price.

## Actor input object example

```json
{
  "searchTerms": [
    "home office"
  ],
  "maxPins": 100,
  "searchMatching": "pinterest",
  "mediaType": "all",
  "dateRange": "any",
  "includeDetails": false,
  "connection": "automatic"
}
```

# Actor output Schema

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

Unique exported pins with source links and available public fields.

## `research` (type: `string`):

Visual preview and destination-domain counts. Full output remains in the dataset.

## `coverage` (type: `string`):

Scanned/exported counts, filtering and source limitations.

# 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 = {
    "searchTerms": [
        "home office"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("cleanscrape/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 = { "searchTerms": ["home office"] }

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

```

## MCP server setup

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