# Pinterest Scraper — Pins, Boards, Profiles & Search (`steadyscrape/pinterest-scraper`) Actor

Pinterest pins, boards and profiles from any search, board or profile: full-size image and video links, pinner, board, product price, creation date; optionally saves, repins, shares, comments, topics, followers, monthly views and every board. Export data to JSON, CSV or Excel, or via API.

- **URL**: https://apify.com/steadyscrape/pinterest-scraper.md
- **Developed by:** [Steady Scrape](https://apify.com/steadyscrape) (community)
- **Categories:** Social media, Marketing, E-commerce
- **Stats:** 4 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 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.

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 — pins, boards, profiles and search

Give it **searches, boards, profiles or pin links** and get every pin with its data: title, description, the
**full-size original image**, the video (an **.mp4** and the stream), the link it leads to, the pinner, the board,
reactions, the **product price** of shopping pins and the creation date. Turn on details and each pin also gets its
**saves, repins, shares, comment count, topics and original creator**. Add a **profile row** (followers, monthly views,
website) and **board rows** when you want them.

It reads Pinterest's own web endpoints with plain HTTP. No login, no cookies to give, no browser, no proxy to pay
for: 1,958 pins from three searches took 47 seconds and 93 requests on Apify.

**US$1 per 1,000 pins** (US$2 per 1,000 with details). Rows that carry nothing — an unknown pin, board or profile, a
search with no results, a refusal — are free, and your maximum is checked before any request, so a run never
reads (or charges) more than you asked for.

### What makes it different

- **Whole boards, not the first 25 pins.** Logged out, about half of Pinterest's sessions are shown only 25 pins of a
  board and no way to the rest, which is how a board scraper comes back with "only 17 results".
  This Actor notices a board cut short (it knows how many pins the board has), starts a fresh session, and keeps the
  session that pages for the next board. Measured: an 86-pin board read whole after eight cut sessions in a row.
- **Full-size images and real video files.** `imageUrl` is the original upload (`/originals/`, e.g. 1440×1800), not
  the 236-pixel thumbnail. Video pins give `videoStreamUrl` (HLS), and with details the `.mp4` file and its length.
- **Numbers that only the pin page has.** With `includeDetails`, each pin is read from its own page: `saves` (the
  count Pinterest shows: 20,949 on one recipe video), `repins`, `shares`, `comments`, the `topics` Pinterest files it
  under and the account that first uploaded it. A pin whose page cannot be read is still delivered, with what the
  list gave, at the plain price.
- **Rank included.** Every pin carries its `position` in the search, board or profile, so a scheduled search is a
  rank tracker for your pins and your competitors'.
- **Limits you can trust.** `maxPins` is applied before a request is made; the run stops cleanly at your spending
  limit and says so. Nothing runs "until the platform default" on your money.
- **Every source says what happened.** A search, board, profile or pin that gives nothing ends as a free `status`
  row — `not_found`, `no_pins` or `blocked` — with the reason in plain words, never as an empty run marked succeeded.

### Use cases

- **Trend and keyword research**: what Pinterest shows for a keyword, ranked, with saves and topics — the visual
  side of SEO for home decor, fashion, food, weddings, beauty.
- **Competitor and brand monitoring**: a competitor's profile or boards on a schedule; which of their pins collect
  saves; which domains their pins link to.
- **Rank tracking**: where your own pins sit for your keywords, week after week.
- **Shopping and product research**: product pins with name, price, currency and stock, and the shop they link to.
- **Influencer and creator vetting**: followers, monthly views, verified domain and what their pins actually earn.
- **Image and video datasets**: original-resolution images and mp4 files with titles, descriptions, alt text and
  Pinterest's own image captions (`autoAltText`).

### Input

```json
{
    "searchQueries": ["scandinavian living room", "boho bedroom"],
    "urls": [
        "https://www.pinterest.com/marthastewart/canning-and-preserving/",
        "https://www.pinterest.com/marthastewart/",
        "https://www.pinterest.com/pin/317222367527146045/"
    ],
    "maxPins": 200,
    "includeDetails": true,
    "includeProfile": true,
    "includeBoards": false
}
```

| field | what it does |
|---|---|
| `searchQueries` | Words to search, one search per line. Pinterest serves about 1,000 pins per search. |
| `searchType` | `pins` (default) or `videos`, for the words above. |
| `urls` | Pins, boards, profiles (`/marthastewart/` or `@marthastewart`), a profile's own uploads (`/marthastewart/_created/`), search links, `pin.it` share links. Any country domain (`ar.pinterest.com`, `pinterest.co.uk`…). A repeat is scraped once. |
| `maxPins` | Per search, board or profile; default `100`, `0` for everything Pinterest lists. |
| `includeDetails` | Reads each pin's own page (saves, repins, shares, comments, topics, mp4). Charged as `pin-with-details`. |
| `includeProfile` | One profile row per profile link (default `true`). |
| `includeBoards` | One row per board of a profile, and the board's own row for a board link. |
| `profilePins` | For profile links: `all` the pins on its boards (default) or only the ones it `created`. |

Board sections and `/ideas/` pages are not read; the input says so by name instead of running for nothing.

### Output

One dataset; each row has a `type` — `pin`, `profile`, `board` or `status` — and a `source` (your words or link).
The **Pins**, **Profiles and boards** and **Sources without pins** views show each as a table.

A pin with details:

```json
{
    "type": "pin",
    "status": "ok",
    "sourceType": "search",
    "source": "easy dinner recipes",
    "position": 1,
    "detailed": true,
    "id": "707557791488257778",
    "url": "https://www.pinterest.com/pin/707557791488257778/",
    "title": "One Pan Chicken and Potatoes",
    "description": "This easy one pan chicken and potatoes is the perfect quick dinner of juicy chicken and crispy potatoes – a must-have for busy weekday nights.",
    "altText": "A video tutorial showing how to make chicken and potatoes meal in one pan.",
    "autoAltText": "one pan chicken and potatoes recipe",
    "link": "https://www.alphafoodie.com/one-pan-chicken-and-potatoes/",
    "domain": "alphafoodie.com",
    "imageUrl": "https://i.pinimg.com/originals/73/c6/17/73c617de8c3622bd23ef8456fb2bbeb3.jpg",
    "imageWidth": 1080,
    "imageHeight": 1920,
    "thumbnailUrl": "https://i.pinimg.com/236x/73/c6/17/73c617de8c3622bd23ef8456fb2bbeb3.jpg",
    "dominantColor": "#a05713",
    "mediaType": "video",
    "videoUrl": "https://v1.pinimg.com/videos/iht/720p/76/6a/ed/766aeda79426ea9b771bef95e12453e5.mp4",
    "videoStreamUrl": "https://v1.pinimg.com/videos/iht/hls/76/6a/ed/766aeda79426ea9b771bef95e12453e5.m3u8",
    "videoDurationSeconds": 56,
    "videoCoverUrl": "https://i.pinimg.com/videos/thumbnails/originals/76/6a/ed/766aeda79426ea9b771bef95e12453e5.0000000.jpg",
    "createdAt": "2024-08-25T19:55:29.000Z",
    "pinnerUsername": "alphafoodie",
    "pinnerName": "Alphafoodie",
    "pinnerFollowers": 175024,
    "pinnerUrl": "https://www.pinterest.com/alphafoodie/",
    "originalCreatorUsername": null,
    "boardName": "Food Videos",
    "boardUrl": "https://www.pinterest.com/alphafoodie/food-videos/",
    "boardPinCount": null,
    "reactions": 2126,
    "saves": 20949,
    "repins": 4619,
    "shares": 1606,
    "comments": 0,
    "hashtags": [],
    "topics": ["Night Dinner Ideas", "Chicken Pieces Dishes", "Simple Dinner Recipes For One", "Pan Oven Recipes", "One Pot Potato Meals", "Easy Chicken Recipes Videos", "Grilled Chicken And Potatoes Recipes", "Potato Recipes For Dinner", "Saturday Supper Ideas"],
    "isPromoted": false,
    "productName": null,
    "productPrice": null,
    "productCurrency": null,
    "productInStock": null,
    "scrapedAt": "2026-10-13T15:19:30.000Z"
}
```

| field | meaning |
|---|---|
| `position` | Rank of the pin in its search, board or profile, in Pinterest's order. |
| `detailed` | `true` when the pin was read from its own page; `saves`, `repins`, `shares`, `comments` and `topics` come from there. |
| `imageUrl` | The original upload; `thumbnailUrl` the 236-pixel version. |
| `videoUrl` / `videoStreamUrl` | The .mp4 (pin pages carry it; lists usually only the stream) and the HLS stream. |
| `saves` | Saves of the image across Pinterest — the count on the pin page. Board feeds also carry it; searches do not. |
| `repins` | Saves of this very pin. |
| `reactions` | Hearts and other reactions, summed. |
| `originalCreatorUsername` | Who uploaded the image first, when it is not the pinner. |
| `productName`, `productPrice`, `productCurrency`, `productInStock` | For shopping pins. |
| `createdAt` | When the pin was made (UTC). Board feeds do not carry it; details do. |

A profile row has `username`, `fullName`, `about`, `website`, `verifiedDomain`, `followers`, `following`, `pins`,
`boards`, `videoPins`, `monthlyViews`, `isVerified`, `isVerifiedMerchant`, `isPartner`, `imageUrl` and `createdAt`.
A board row has `name`, `url`, `description`, `pins`, `followers`, `sections`, `collaborators`, `ownerUsername`,
`category`, `coverImageUrl`, `createdAt` and `updatedAt`. A status row has `status` and `reason`.

The run's `SUMMARY` record counts sources by status, pins, profiles, boards and requests.

### Pricing

Pay per event, nothing per run:

| event | price | when |
|---|---|---|
| `pin` | US$0.001 | a pin from a search, board or profile |
| `pin-with-details` | US$0.002 | a pin read from its own page (details on, or a pin link) |
| `profile` | US$0.002 | a profile row |
| `board` | US$0.001 | a board row |

Status rows are free. 1,000 pins with saves and comments cost US$2.

### Limits

- Pinterest serves about **1,000 pins per search** (measured: 1,014 listed, 845 unique, for "sourdough starter";
  Pinterest repeats some pins on later pages, and every pin is delivered once per search). Narrower searches go further.
- Logged-out Pinterest shows no follower lists, no comment texts and no private boards; neither does this Actor.
- Profiles: `pins` counts what Pinterest says the account has; the list can be a few pins shorter (hidden pins are
  counted, not served).

### Is it legal?

It reads public pages that anyone can open without an account, at a human pace, and stores nothing about the people
it reads except what they published. Personal data is still personal data: if you collect it about people in the EU
or elsewhere with data-protection laws, you are responsible for having a legitimate reason. Pinterest's images
belong to their owners; use them within copyright law.

# Actor input Schema

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

Words to search, one search per line, exactly as you would type them on Pinterest. Pinterest serves about 1,000 pins per search; for more, use narrower searches.

## `searchType` (type: `string`):

<b>Pins</b> is every kind of pin; <b>Video pins</b> only pins with a video. Applies to the words above; a search link keeps its own type.

## `urls` (type: `array`):

Any of: a pin (<code>pinterest.com/pin/317222367527146045/</code>), a board (<code>pinterest.com/marthastewart/canning-and-preserving/</code>), a profile (<code>pinterest.com/marthastewart/</code> or <code>@marthastewart</code>), a profile's own uploads (<code>pinterest.com/marthastewart/\_created/</code>), a search (<code>pinterest.com/search/pins/?q=cake</code>) or a <code>pin.it</code> share link. Any country domain works.

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

Checked before any request, so you never pay for more. <code>0</code> takes everything Pinterest lists: a whole board, a whole profile, or the ~1,000 pins of a search.

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

One extra request per pin for what only its page has: saves, repins, shares and comment count, the topics Pinterest links it to, the original creator and the video as an .mp4 file. Charged as <code>pin-with-details</code> instead of <code>pin</code>. A pin link always reads its page.

## `includeProfile` (type: `boolean`):

For profile links: followers, following, pins, boards, monthly views, website and its verified domain, badges. Charged as one <code>profile</code> event.

## `includeBoards` (type: `boolean`):

For a profile, one row per board it has (name, pins, followers, sections, cover, dates); for a board link, the board's own row. Charged as one <code>board</code> event each.

## `profilePins` (type: `string`):

<b>All its pins</b> is everything the account saved to its boards, newest first; <b>Only its own uploads</b> is the Created tab. A <code>/\_created/</code> link always means its own uploads.

## Actor input object example

```json
{
  "searchQueries": [
    "scandinavian living room"
  ],
  "searchType": "pins",
  "maxPins": 30,
  "includeDetails": false,
  "includeProfile": true,
  "includeBoards": false,
  "profilePins": "all"
}
```

# Actor output Schema

## `rows` (type: `string`):

No description

## `summary` (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": [
        "scandinavian living room"
    ],
    "maxPins": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadyscrape/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": ["scandinavian living room"],
    "maxPins": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("steadyscrape/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": [
    "scandinavian living room"
  ],
  "maxPins": 30
}' |
apify call steadyscrape/pinterest-scraper --silent --output-dataset

```

## MCP server setup

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