# Pinterest Scraper - Pins, Boards, Comments & User Profiles (`epctex/pinterest-scraper`) Actor

Scrape Pinterest pins, boards, idea pages, comments, replies and user profiles from URLs or a keyword. Full pins at $3.10 per 1,000, summaries at $0.10 per 1,000. Built for social, ecommerce and influencer teams. 25 documented error codes.

- **URL**: https://apify.com/epctex/pinterest-scraper.md
- **Developed by:** [epctex](https://apify.com/epctex) (community)
- **Categories:** SEO tools, Social media
- **Stats:** 3,234 total users, 168 monthly users, 100.0% runs succeeded, 64 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.10 / 1,000 dataset items

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

Pinterest Scraper is an Apify actor that extracts Pinterest pins, pin comments, comment replies, idea pages, boards and user profiles from pin, idea, board, user and search URLs or a search keyword. Full pin details cost **$0.0031 per pin, or $3.10 per 1,000 pins**.

The Pinterest Scraper runs **9 query types**, accepts **13 input fields**, returns **56 pin fields, 28 pin summary fields and 32 user fields**, bills through **10 charge events** and reports **25 error codes**. Every price on this page is a pay-per-event charge.

### What Does the Pinterest Scraper Extract?

The Pinterest Scraper extracts 9 query types: 6 run directly from an input, and 3 (pin comments, comment replies and user collections) attach nested data to pin and user items. The Pinterest Scraper calls a Pinterest board a collection in its input and output, so "board" and "collection" name the same entity on this page.

| Query type | What the Pinterest Scraper returns |
|---|---|
| Pin | Full details of a single pin: title, description, images, owner, board, engagement counts and SEO data. |
| Pin comments | Comments on a pin, nested inside the pin item when `includeComments` is `true`. |
| Comment replies | Replies to pin comments, nested under each comment when `includeCommentReplies` is `true`. |
| Search | Pins that match a keyword search. |
| Idea | Pins listed on a Pinterest idea page. |
| Collection | Pins saved in a user's board. |
| User profile | A user's profile: name, bio, website, follower and following counts, pin and board counts. |
| User pins | URLs of the pins created by the user, nested inside the user item. |
| User collections | The user's boards with name, URL, pin count and dates, nested inside the user item. |

### Which Pinterest URLs Does the Pinterest Scraper Accept?

The Pinterest Scraper accepts 2 input sources: the `startUrls` list and the `search` keyword. `startUrls` takes 5 URL forms, and each URL form maps to one query type.

- **Pin URL** `/pin/{id}/`, such as `https://www.pinterest.com/pin/1054827543951238554/`, runs the pin query.
- **Idea URL** `/ideas/{name}/{id}/`, such as `https://www.pinterest.com/ideas/beauty/935541271955/`, runs the idea query. Hyphens in `{name}` are read as spaces.
- **Board URL** `/{username}/{collection}/`, such as `https://www.pinterest.com/dudadelsanto/nail-inspo/`, runs the collection query.
- **User URL** `/{username}/`, such as `https://www.pinterest.com/dudadelsanto/`, runs the user profile query. `/{username}/_saved` and `/{username}/_created` resolve to the same user profile query.
- **Search URL** `/search/pins/?q={keyword}`, such as `https://www.pinterest.com/search/pins/?q=nail%20art`, runs the search query. The `q` parameter must be non-empty.

The `search` field runs the same search query from a plain keyword, without a URL. The Pinterest Scraper accepts any `http` or `https` host whose name contains a `pinterest` label, so `tr.pinterest.com` and `www.pinterest.com` resolve identically.

### Who Uses the Pinterest Scraper?

Listed below are the 6 roles that run the Pinterest Scraper against Pinterest data.

- **Social media analysts** track pin engagement through `repin_count`, `like_count`, `share_count`, `favorite_user_count` and `comment_count`.
- **Ecommerce and brand teams** monitor pins that link to their domain through `domain`, `link`, `seo_title` and `seo_description`.
- **Influencer marketers** qualify Pinterest creators through the user item's `follower_count`, `following_count`, `pin_count`, `board_count` and `is_verified_merchant`.
- **Content strategists** read idea pages and keyword searches for `grid_title`, `description`, `alt_text`, `category` and `dominant_color`.
- **Community and sentiment researchers** collect pin comments and replies with `comments[].content`, `comments[].like_count`, `comments[].reply_count` and `comments[].replies[]`.
- **Data engineers** feed Pinterest boards into pipelines through the user item's `collections[]` array, with `pinsCount`, `followerCount`, `createdAt` and `updatedAt` per board.

Each of these roles pays per event, so the cost of a Pinterest Scraper run follows directly from which query types it runs and how many pages it fetches.

### What Does the Pinterest Scraper Cost?

The Pinterest Scraper charges 10 event types. A full pin costs **$0.003 for `pin-detail` plus $0.0001 for `dataset-item`, or $0.0031**, and a pin summary from a search, idea or board page costs **$0.0001 per pin** after the query charge.

The rate card below lists all 10 Pinterest Scraper charge events.

| Query type | Charge event | Price |
|---|---|---|
| Pin (start URL, or every pin fetched with `getDetails`) | `pin-detail` | $0.003 |
| Search | `search-pins` | $0.0015 |
| Idea | `idea-pins` | $0.0015 |
| Collection | `board-pins` | $0.0025 |
| User profile | `user-profile` | $0.003 |
| User pins (per page) | `user-pins` | $0.004 |
| User collections (per page) | `user-boards` | $0.0025 |
| Pin comments (per page) | `pin-comments` | $0.001 |
| Comment replies (per page) | `comment-replies` | $0.002 |
| Every returned item | `dataset-item` | $0.0001 |

The Pinterest Scraper applies 4 billing rules on top of the rate card:

- **Query charges are taken at start.** `pin-detail` for pin URLs, `search-pins`, `idea-pins`, `board-pins` and `user-profile` are charged once per query when the run starts, before the first request.
- **Search, idea and board pagination is not charged per page.** Later pages of a search, idea or collection query add only `dataset-item` charges, plus `pin-detail` per pin when `getDetails` is `true`.
- **User pins, user collections, comments and replies are charged per page.** `user-pins`, `user-boards`, `pin-comments` and `comment-replies` fire once for every page fetched.
- **`dataset-item` is waived for paying users** on items from the first results page of search, idea and collection queries when `getDetails` is `false`.

#### Pinterest Scraper Cost Examples

The table below prices 6 Pinterest Scraper scenarios against the rate card above. Page sizes are set by Pinterest, so the scenarios state page counts and item counts rather than a page size.

| Scenario | Charge events | Calculation | Total cost |
|---|---|---|---|
| 1 pin URL | `pin-detail`, `dataset-item` | $0.003 + $0.0001 | $0.0031 |
| 1 pin URL with 1 comment page | `pin-detail`, `pin-comments`, `dataset-item` | $0.003 + $0.001 + $0.0001 | $0.0041 |
| 1 pin URL with 1 comment page and 1 reply page for 2 comments | `pin-detail`, `pin-comments`, 2 x `comment-replies`, `dataset-item` | $0.003 + $0.001 + 2 x $0.002 + $0.0001 | $0.0081 |
| 1 search returning 100 pins, `getDetails` `true` | `search-pins`, 100 x `pin-detail`, 100 x `dataset-item` | $0.0015 + 100 x $0.0031 | $0.3115 |
| 1 search returning 100 pins, `getDetails` `false`, non-paying user | `search-pins`, 100 x `dataset-item` | $0.0015 + 100 x $0.0001 | $0.0115 |
| 1 user URL with 1 page of pins and 1 page of boards | `user-profile`, `user-pins`, `user-boards`, `dataset-item` | $0.003 + $0.004 + $0.0025 + $0.0001 | $0.0096 |

#### Pinterest Scraper Unit Economics

The 6 figures below are derived from the rate card above. Per-pin figures exclude the one-time query charge of the search, idea or collection that found the pin.

| Metric | Value |
|---|---|
| Cost per full pin, including its dataset item | $0.0031 |
| Cost per 1,000 full pins | $3.10 |
| Full pins per $1 | 322 |
| Cost per 1,000 pin summaries (`getDetails` `false`) | $0.10 |
| Cost per user profile only (`includeUserInfoOnly` `true`) | $0.0031 |
| Ratio between `user-pins` ($0.004) and `dataset-item` ($0.0001) | 40 to 1 |

### How Is the Pinterest Scraper Configured?

The Pinterest Scraper exposes 13 input fields: 2 sources, 4 boolean switches, 2 volume limits, 1 output transform and 4 delivery fields.

| Name | Type | Default | Description |
|---|---|---|---|
| `startUrls` | array | none | Pinterest URLs to start with: pin, idea, board, user or search URLs. |
| `search` | string | none | Keyword to search pins on Pinterest. |
| `getDetails` | boolean | `true` | Fetches full details of every pin found in search, idea and collection results. `false` returns only the summary data of the list results. |
| `includeComments` | boolean | `false` | Includes comments for pins from pin URLs and pins fetched with `getDetails`. |
| `includeCommentReplies` | boolean | `false` | Includes replies for comments that have replies. Requires `includeComments`. |
| `includeUserInfoOnly` | boolean | `false` | Returns only the user profile for user URLs, without the user's pins and boards. |
| `maxItems` | integer | all items | Maximum number of items in the output. |
| `endPage` | integer | no limit | Last page to fetch, applied individually to every search, start URL, user pins list and user collections list. |
| `customMapFunction` | string | none | Single synchronous function that receives each output item and returns the transformed item. Not for filtering. |
| `outputConnector` | string | none | MCP connector to deliver the results to. See [How Do You Send Pinterest Scraper Results to Notion, Todoist and More?](#how-do-you-send-pinterest-scraper-results-to-notion-todoist-and-more) |
| `deliverTarget` | string | none | Where the connector writes: a page or database URL or ID (Notion example: `https://www.notion.so/My-Posts-24f8a1b2c3d44e5f8a9b0c1d2e3f4a5b`). Some services need none. |
| `deliverMode` | string | `perPost` | `perPost` writes one record per item, `summary` one roll-up per run. |
| `deliverMaxItems` | integer | all items | Maximum number of records `perPost` delivers. Ignored in `summary`. |

### Which Input Rules Does the Pinterest Scraper Enforce?

The Pinterest Scraper enforces 12 usage constraints covering sources, URL forms, nesting, item size, cost limits and the map function.

| Rule | Behavior |
|---|---|
| At least one of `startUrls` or `search` must be provided. | The run fails immediately when both are empty. |
| Start URLs must use `http` or `https` and a Pinterest domain. | Other URLs are skipped with an `Invalid URL` warning. |
| Supported URL forms are `/pin/{id}`, `/ideas/{name}/{id}`, `/search/...?q={keyword}`, `/{username}/{collection}` and `/{username}`. | Any other Pinterest URL is skipped with an `Unsupported URL` warning. |
| `/{username}/_saved` and `/{username}/_created` are treated as the user profile URL. | They resolve to the same user profile query. |
| A search URL must contain a non-empty `q` parameter. | Search URLs without a query are skipped with a warning. |
| `includeCommentReplies` only works when `includeComments` is `true`. | Replies are fetched while collecting comments, and only for comments with at least one reply. |
| User pins are returned as URLs. | User pins are not expanded with `getDetails` or comments. Pin details and comments are fetched only for pin, search, idea and collection queries. |
| Comments and replies of one pin are capped at 4 MB. | The cap keeps a single dataset item under the platform item size limit. Comment collection stops once it is reached. |
| The query charges at start must fit the maximum cost per run. | The run exits before fetching anything when the start charges exceed the limit. Non-paying users are charged 10 `dataset-item` events in that case. |
| The run stops when `maxItems` or the maximum cost per run is reached. | Remaining queued requests are cleared. |
| `maxItems` applies to paid-tier runs. | Free-tier runs use the item limit of the free tier. |
| `customMapFunction` cannot contain date operations (`new Date`, `Date.now`, `1970`) and cannot be async or a generator. | The function is rejected with a warning and the original items are saved. A function that throws or returns a non-object is also rejected for the rest of the run. |

### How Do You Scrape Pinterest Search Results with the Pinterest Scraper?

The Pinterest Scraper runs a keyword search from the `search` field or from a search URL in `startUrls`. The input below fetches 2 pages of search results as full pins with comments, and stops at 100 items.

```json
{
    "search": "nail art",
    "getDetails": true,
    "includeComments": true,
    "endPage": 2,
    "maxItems": 100
}
```

Setting `getDetails` to `false` returns pin summaries instead, which removes the `pin-detail` charge per pin.

### How Do You Scrape Pinterest Boards and Idea Pages with the Pinterest Scraper?

The Pinterest Scraper reads board and idea URLs from `startUrls` and paginates each one until `endPage`. The input below returns pin summaries for 1 board and 1 idea page, 3 pages each.

```json
{
    "startUrls": [
        "https://www.pinterest.com/dudadelsanto/nail-inspo/",
        "https://www.pinterest.com/ideas/beauty/935541271955/"
    ],
    "getDetails": false,
    "endPage": 3
}
```

### How Do You Scrape Pinterest User Profiles with the Pinterest Scraper?

The Pinterest Scraper returns one user item per user URL, with the user's pin URLs and boards nested inside it. The input below returns 2 profiles without pins or boards, which charges `user-profile` and `dataset-item` only.

```json
{
    "startUrls": [
        "https://www.pinterest.com/dudadelsanto/",
        "https://www.pinterest.com/example_user/_saved"
    ],
    "includeUserInfoOnly": true
}
```

Setting `includeUserInfoOnly` to `false` adds the `pins` and `collections` arrays, fetched page by page up to `endPage`.

### How Do You Scrape Pinterest Comments and Replies with the Pinterest Scraper?

The Pinterest Scraper attaches comments and replies to the pin item, so a pin URL with both switches on returns one item carrying the full thread. The input below collects comments and replies for 1 pin and reshapes each item with `customMapFunction`.

```json
{
    "startUrls": [
        "https://www.pinterest.com/pin/1054827543951238554/"
    ],
    "includeComments": true,
    "includeCommentReplies": true,
    "customMapFunction": "(object) => { return { id: object.id, url: object.url, comments: object.comments } }"
}
```

### How Do You Send Pinterest Scraper Results to Notion, Todoist and More?

The Pinterest Scraper can deliver its results straight into the tools you already use, through [Apify MCP Connectors](https://apify.com/store/collections/mcp-connectors).

1. Authorize a connector (Notion, Todoist, or any service whose MCP server offers non-destructive write tools) once in [Console → Settings → API & Integrations → MCP connectors](https://console.apify.com/settings/integrations).
2. Pick it in the **Send results to Notion, Todoist, …** field.
3. Fill in where and how to write:
   - **Destination target:** the page or database URL or ID (Notion example: `https://www.notion.so/My-Posts-24f8a1b2c3d44e5f8a9b0c1d2e3f4a5b`). Share it with your connector first through Notion's **••• → Connections** menu. Some services need no target.
   - **Write mode:** `perPost` writes one record per item; `summary` writes a single roll-up for the run.
   - **Max records to deliver** (optional): a cap on how many records `perPost` delivers.

**Notion:** point the target at a Notion **page** and the Actor creates a database with one typed column per field (URL, number, date, text). An **existing database** gets its matching columns filled by name. The connector can't add columns to it, so an empty database receives only titles and the rest of each record goes to the row's page body. Nested fields become columns too: an `owner` object becomes `owner.username`, `owner.follower_count` and so on, and `board` becomes `board.name` and `board.url`. Lists such as `comments` become one JSON text column. Notion caps a text cell at 2,000 characters, so long comment threads are cut off in Notion; the dataset keeps them in full. Fields without a column go to the row's page body, so nothing is lost.

Your credentials stay with you: the Actor writes only through your own connector and only uses non-destructive write tools, so it can't delete or overwrite anything. Delivery runs after the scrape and is best-effort. If it fails, the run still finishes normally with all results in the dataset, and the run log says what went wrong. If the run is close to its timeout, delivery stops early so the run still succeeds, and the log says how many records were delivered.

### Which Fields Does the Pinterest Scraper Output?

The Pinterest Scraper outputs 3 item shapes: a full pin with 56 fields, a pin summary with 28 fields and a user with 32 fields. Every item carries `inputSource`, the start URL or keyword that produced it, and `type`, which is `pin` or `user`.

#### Pinterest Scraper Pin Fields

The full pin item has 56 fields, returned for pin URLs and for list results when `getDetails` is `true`.

| Name | Type |
|---|---|
| `inputSource` | string |
| `type` | string (`pin`) |
| `url` | string |
| `id` | string |
| `aggregated_pin_data.id` | string |
| `aggregated_pin_data.comment_count` | number |
| `alt_text` | string |
| `board.id` | string |
| `board.name` | string |
| `board.url` | string |
| `board.pin_count` | number |
| `board.owner` | object (same shape as `owner`) |
| `category` | string |
| `closeup_attribution.id` | string |
| `closeup_attribution.username` | string |
| `closeup_attribution.full_name` | string |
| `closeup_attribution.image_medium_url` | string |
| `closeup_attribution.follower_count` | number |
| `closeup_description` | string |
| `closeup_unified_description` | string |
| `comment_count` | number |
| `comments_disabled` | boolean |
| `created_at` | string |
| `description` | string |
| `description_html` | string |
| `domain` | string |
| `dominant_color` | string |
| `grid_title` | string |
| `image_signature` | string |
| `images` | object (keyed by image size, each with `url`) |
| `owner.id` | string |
| `owner.username` | string |
| `owner.full_name` | string |
| `owner.first_name` | string |
| `owner.image_medium_url` | string |
| `owner.follower_count` | number |
| `pinner` | object (same shape as `owner`) |
| `pinner_follower_count` | number |
| `pinner_id` | string |
| `isRepin` | boolean |
| `favorite_user_count` | number |
| `repin_count` | number |
| `share_count` | number |
| `like_count` | number |
| `seo_title` | string |
| `seo_description` | string |
| `comments[].id` | string |
| `comments[].created_at` | string |
| `comments[].content` | string |
| `comments[].name` | string |
| `comments[].avatar` | string |
| `comments[].url` | string |
| `comments[].like_count` | number |
| `comments[].reply_count` | number |
| `comments[].helpful_count` | number |
| `comments[].replies[]` | array (same shape as `comments[]`) |

#### Pinterest Scraper Pin Summary Fields

The pin summary item has 28 fields, returned for search, idea and collection results when `getDetails` is `false`.

| Name | Type |
|---|---|
| `inputSource` | string |
| `type` | string (`pin`) |
| `url` | string |
| `id` | string |
| `aggregated_pin_data.id` | string |
| `aggregated_pin_data.comment_count` | number |
| `board.id` | string |
| `board.name` | string |
| `board.url` | string |
| `board.owner` | object (same shape as `owner`) |
| `comment_count` | number |
| `created_at` | string |
| `description` | string |
| `description_html` | string |
| `domain` | string |
| `link` | string |
| `is_video` | boolean |
| `dominant_color` | string |
| `grid_title` | string |
| `images` | object (keyed by image size, each with `url`) |
| `owner.id` | string |
| `owner.username` | string |
| `owner.full_name` | string |
| `owner.first_name` | string |
| `pinner` | object (same shape as `owner`) |
| `pinner_id` | string |
| `repin_count` | number |
| `like_count` | number |

#### Pinterest Scraper User Fields

The user item has 32 fields. `pins` and `collections` are present when `includeUserInfoOnly` is `false`.

| Name | Type |
|---|---|
| `inputSource` | string |
| `type` | string (`user`) |
| `url` | string |
| `id` | string |
| `username` | string |
| `full_name` | string |
| `first_name` | string |
| `about` | string |
| `website_url` | string |
| `image_medium_url` | string |
| `follower_count` | number |
| `following_count` | number |
| `board_count` | number |
| `pin_count` | number |
| `is_private_profile` | boolean |
| `is_verified_merchant` | boolean |
| `created_at` | string |
| `pins` | array of strings (pin URLs) |
| `collections[].id` | string |
| `collections[].name` | string |
| `collections[].url` | string |
| `collections[].slug` | string |
| `collections[].description` | string |
| `collections[].privacy` | string |
| `collections[].pinsCount` | number |
| `collections[].followerCount` | number |
| `collections[].sectionCount` | number |
| `collections[].collaboratorCount` | number |
| `collections[].isCollaborative` | boolean |
| `collections[].coverImageUrl` | string |
| `collections[].createdAt` | string |
| `collections[].updatedAt` | string |

### Which Sample Output Does the Pinterest Scraper Produce?

The Pinterest Scraper produces the 3 sample items below, one per item shape.

#### Pinterest Scraper Pin Example

```json
{
    "inputSource": "https://tr.pinterest.com/pin/973481275688876750/",
    "type": "pin",
    "url": "https://www.pinterest.com/pin/973481275688876750/",
    "aggregated_pin_data": {
        "id": "5304652933210629048",
        "comment_count": 48
    },
    "alt_text": "a person holding a cake with cherries on it",
    "board": {
        "id": "973481344393495401",
        "owner": {
            "id": "973481413112246585",
            "image_medium_url": "https://i.pinimg.com/75x75_RS/8c/b4/95/8cb4954e930e2313c524a7699c2160fc.jpg",
            "full_name": "🍒ARIN🍒",
            "follower_count": 122424,
            "username": "moon19_6tn",
            "first_name": "🍒ARIN🍒"
        },
        "url": "/moon19_6tn/background/",
        "name": "|☆Background☆|",
        "pin_count": 1346
    },
    "category": "",
    "closeup_attribution": {
        "id": "973481413112246585",
        "full_name": "🍒ARIN🍒",
        "username": "moon19_6tn"
    },
    "closeup_description": " ",
    "closeup_unified_description": " ",
    "comment_count": 48,
    "comments_disabled": false,
    "created_at": "Thu, 22 Jun 2023 10:46:14 +0000",
    "description": " ",
    "description_html": " ",
    "domain": "Uploaded by user",
    "dominant_color": "#8a8479",
    "grid_title": "",
    "id": "973481275688876750",
    "image_signature": "be3c0223640873fc19cc051306779359",
    "images": {
        "236x": {
            "url": "https://i.pinimg.com/236x/be/3c/02/be3c0223640873fc19cc051306779359.jpg"
        }
    },
    "owner": {
        "id": "973481413112246585",
        "image_medium_url": "https://i.pinimg.com/75x75_RS/8c/b4/95/8cb4954e930e2313c524a7699c2160fc.jpg",
        "full_name": "🍒ARIN🍒",
        "follower_count": 122424,
        "username": "moon19_6tn",
        "first_name": "🍒ARIN🍒"
    },
    "pinner": {
        "id": "973481413112246585",
        "image_medium_url": "https://i.pinimg.com/75x75_RS/8c/b4/95/8cb4954e930e2313c524a7699c2160fc.jpg",
        "full_name": "🍒ARIN🍒",
        "follower_count": 122424,
        "username": "moon19_6tn",
        "first_name": "🍒ARIN🍒"
    },
    "pinner_follower_count": 122424,
    "pinner_id": "973481413112246585",
    "repin_count": 4799,
    "share_count": 131,
    "like_count": 4964,
    "seo_title": "Delicious Cherry Cake | Bánh ngọt, Ý tưởng quà tặng, Thức ăn",
    "seo_description": "2 thg 2, 2026. Indulge in this mouthwatering cherry cake. Perfect for any occasion.",
    "comments": [
        {
            "id": "5404536928934605458",
            "created_at": "Tue, 24 Dec 2024 16:52:55 +0000",
            "content": "Сплошные красители",
            "name": "elena300787nastya",
            "avatar": "https://i.pinimg.com/75x75_RS/25/82/27/258227c6e853a14ac2c3751e4a4aae28.jpg",
            "url": "https://www.pinterest.com/elena300787nastya",
            "like_count": 50,
            "reply_count": 20,
            "helpful_count": 0,
            "replies": [
                {
                    "id": "3846302704361908736",
                    "created_at": "Thu, 10 Sep 2026 17:19:13 +0000",
                    "content": "@YazheVikaDoYouKnow бля, почему именно неучи продвигают эту идею… какая химия? Химия везде, все состоит из химических веществ, даже ваша ненаглядная свекла.",
                    "name": "0morefd0",
                    "avatar": "https://i.pinimg.com/75x75_RS/2d/28/dd/2d28dda9aa65c4fb8a707b8ed68644bf.jpg",
                    "url": "https://www.pinterest.com/0morefd0",
                    "like_count": 0,
                    "reply_count": 0,
                    "helpful_count": 0
                }
            ]
        }
    ]
}
```

#### Pinterest Scraper Pin Summary Example

```json
{
    "inputSource": "https://www.pinterest.com/search/pins/?q=example",
    "type": "pin",
    "url": "https://www.pinterest.com/pin/1111111111111111111/",
    "aggregated_pin_data": {
        "id": "2222222222222222222",
        "comment_count": 3
    },
    "board": {
        "id": "3333333333333333333",
        "owner": {
            "id": "4444444444444444444",
            "full_name": "Example User",
            "username": "example_user",
            "first_name": "Example User"
        },
        "url": "/example_user/example-collection/",
        "name": "Example Collection"
    },
    "comment_count": 3,
    "created_at": "Mon, 01 Jan 2024 00:00:00 +0000",
    "description": "Example pin description",
    "description_html": "Example pin description",
    "domain": "example.com",
    "link": "https://example.com/article",
    "is_video": false,
    "dominant_color": "#a1b2c3",
    "grid_title": "Example Pin Title",
    "id": "1111111111111111111",
    "images": {
        "236x": {
            "url": "https://i.pinimg.com/236x/00/00/00/example.jpg"
        }
    },
    "owner": {
        "id": "4444444444444444444",
        "full_name": "Example User",
        "username": "example_user",
        "first_name": "Example User"
    },
    "pinner": {
        "id": "4444444444444444444",
        "full_name": "Example User",
        "username": "example_user",
        "first_name": "Example User"
    },
    "pinner_id": "4444444444444444444",
    "repin_count": 120,
    "like_count": 45
}
```

#### Pinterest Scraper User Example

```json
{
    "inputSource": "https://www.pinterest.com/example_user/",
    "type": "user",
    "url": "https://www.pinterest.com/example_user/",
    "id": "4444444444444444444",
    "username": "example_user",
    "full_name": "Example User",
    "first_name": "Example User",
    "about": "Example bio",
    "website_url": "https://example.com",
    "image_medium_url": "https://i.pinimg.com/280x280_RS/00/00/00/example.jpg",
    "follower_count": 1000,
    "following_count": 100,
    "board_count": 2,
    "pin_count": 250,
    "is_private_profile": false,
    "is_verified_merchant": false,
    "created_at": "Mon, 01 Jan 2018 00:00:00 +0000",
    "pins": [
        "https://www.pinterest.com/pin/1111111111111111111/"
    ],
    "collections": [
        {
            "id": "3333333333333333333",
            "name": "Example Collection",
            "url": "https://www.pinterest.com/example_user/example-collection/",
            "slug": "example-collection",
            "description": "Example collection description",
            "privacy": "public",
            "pinsCount": 40,
            "followerCount": 12,
            "sectionCount": 0,
            "collaboratorCount": 0,
            "isCollaborative": false,
            "coverImageUrl": "https://i.pinimg.com/400x300/00/00/00/example.jpg",
            "createdAt": "Mon, 01 Jan 2019 00:00:00 +0000",
            "updatedAt": "Mon, 01 Jan 2024 00:00:00 +0000"
        }
    ]
}
```

### Which Errors Does the Pinterest Scraper Report?

The Pinterest Scraper reports 25 error codes. **22 of the 25 codes are non-terminal**: the run continues with the remaining queries. 3 codes terminate the run: `C098`, `C099` and `C100`.

The 22 non-terminal codes split into 5 recovery behaviors:

- **6 codes** (`C001`, `C002`, `C003`, `C011`, `C012`, `C013`) skip the pin or user.
- **7 codes** (`C004` to `C010`) stop the search, idea or collection query that raised them.
- **6 codes** (`C014` to `C017`, `C022`, `C023`) stop the nested list and push the parent item with the data gathered so far.
- **2 codes** (`C024`, `C025`) stop replies for one comment while the remaining comments continue.
- **1 code** (`C019`) pushes an error item and retries the request after 1 second.

The table below lists all 25 Pinterest Scraper error codes with cause and behavior.

| Error code | Cause | Behavior |
|---|---|---|
| `C001` | Request for a pin failed. | Pin is skipped. |
| `C002` | Pin request returned an empty response. | Pin is skipped. |
| `C003` | Pin does not exist. | Pin is skipped. |
| `C004` | Search request failed. | Search query stops. |
| `C005` | Search returned an unexpected response. | Search query stops. |
| `C006` | Idea request failed. | Idea query stops. |
| `C007` | Idea returned an unexpected response. | Idea query stops. |
| `C008` | Collection request failed. | Collection query stops. |
| `C009` | Collection returned an unexpected response. | Collection query stops. |
| `C010` | Collection does not exist. | Collection query stops. |
| `C011` | User profile request failed. | User is skipped. |
| `C012` | User profile returned an empty response. | User is skipped. |
| `C013` | User does not exist. | User is skipped. |
| `C014` | User pins request failed. | User pins collection stops; the user is pushed with the pins gathered so far. |
| `C015` | User pins returned an unexpected response. | User pins collection stops; the user is pushed with the pins gathered so far. |
| `C016` | User collections request failed. | User collections stop; the user is pushed with the collections gathered so far. |
| `C017` | User collections returned an unexpected response. | User collections stop; the user is pushed with the collections gathered so far. |
| `C019` | Rate limit exceeded for the account. | An error item is pushed, then the request is retried after 1 second. |
| `C022` | Pin comments request failed. | Comment collection stops; the pin is pushed with the comments gathered so far. |
| `C023` | Pin comments returned an unexpected response. | Comment collection stops; the pin is pushed with the comments gathered so far. |
| `C024` | Comment replies request failed. | Reply collection for that comment stops; remaining comments continue. |
| `C025` | Comment replies returned an unexpected response. | Reply collection for that comment stops; remaining comments continue. |
| `C098` | Unhandled promise rejection. | Actor exits. |
| `C099` | Uncaught exception. | Actor exits. |
| `C100` | Run failed to initialize. | Actor exits. |

### Which Pinterest Scraper Questions Come Up Most Often?

#### Does the Pinterest Scraper return Pinterest boards?

Yes. The Pinterest Scraper returns the pins of a board from a board URL, and the list of a user's boards inside the user item's `collections` array.

#### Does the Pinterest Scraper scrape Pinterest comments?

Yes. The Pinterest Scraper nests comments in the pin item when `includeComments` is `true`, and nests replies under each comment when `includeCommentReplies` is also `true`.

#### Does the Pinterest Scraper charge for every search results page?

No. The Pinterest Scraper charges `search-pins` once per search query, and later pages add only `dataset-item` charges plus `pin-detail` per pin when `getDetails` is `true`.

#### What is the difference between a pin and a pin summary in the Pinterest Scraper?

A pin summary is the 28-field item the Pinterest Scraper returns from search, idea and board pages when `getDetails` is `false`. A full pin is the 56-field item returned for pin URLs and for every list result when `getDetails` is `true`.

#### Does the Pinterest Scraper expand a user's pins into full pin items?

No. The Pinterest Scraper returns a user's pins as URLs in the `pins` array. Running those URLs through `startUrls` returns them as full pins.

#### Which Pinterest domains does the Pinterest Scraper accept?

The Pinterest Scraper accepts any `http` or `https` host whose name contains a `pinterest` label, such as `www.pinterest.com` and `tr.pinterest.com`.

#### How does the Pinterest Scraper limit the number of pages?

The Pinterest Scraper stops each search, start URL, user pins list and user collections list at `endPage`. Without `endPage`, the Pinterest Scraper paginates until Pinterest returns an empty page or no next cursor.

#### Why does the Pinterest Scraper stop collecting comments on a large pin?

The Pinterest Scraper caps the comments and replies of one pin at 4 MB, which keeps the pin under the platform item size limit. The pin is pushed with the comments gathered up to the cap.

#### Can the Pinterest Scraper filter results with customMapFunction?

No. The Pinterest Scraper uses `customMapFunction` to transform each item, not to filter. A function that contains date operations, is async or throws is rejected, and the original items are saved.

#### What happens when a Pinterest Scraper run hits the maximum cost per run?

The Pinterest Scraper stops the run and clears the remaining queued requests. A run whose start charges already exceed the limit exits before fetching anything.

#### Does the Pinterest Scraper return an item for a Pinterest URL it cannot read?

No. The Pinterest Scraper skips invalid and unsupported URLs with a warning, and skips pins and users that do not exist with error codes `C003` and `C013`.

### Where Do You Get Pinterest Scraper Support?

Pinterest Scraper support runs through the actor's Issues tab on Apify. Check the run's Log tab in Apify Console for the error code first, then open an issue with the run link attached.

# Actor input Schema

## `startUrls` (type: `array`):

URLs to start with. You can provide pin (/pin/{id}/), idea (/ideas/{name}/{id}/), collection (/{username}/{collection}/), user (/{username}/) or search (/search/pins/?q={keyword}) URLs.

## `search` (type: `string`):

The keyword that you can search on Pinterest

## `getDetails` (type: `boolean`):

Fetches the full details of every pin found in search, idea and collection results. When disabled, only the summary data of the list results is returned.

## `includeComments` (type: `boolean`):

Includes comments for the pins. Applies to pin URLs and to pins fetched with "Get pin details".

## `includeCommentReplies` (type: `boolean`):

Includes replies for the comments that have replies. Requires "Include comments" to be enabled.

## `includeUserInfoOnly` (type: `boolean`):

Includes only user profile info for user URLs, without the pins and collections of the user.

## `maxItems` (type: `integer`):

Maximum number of items that you want as output. Default is all

## `endPage` (type: `integer`):

The page number that you want to end with. By default there is no end page. This applies to every search request, start URL, user pins and user collections individually.

## `customMapFunction` (type: `string`):

Function that takes each of the objects as argument and returns data that will be mapped by the function itself. This function is not intended for filtering, please don't use it for filtering purposes or you will get banned automatically. Must be a single function, e.g. (object) => { return {...object} }. Leave empty if you do not need to transform the output - an unusable function is ignored and the original items are saved instead.

## `outputConnector` (type: `string`):

Pick an MCP connector you authorized in Console → Settings → API & Integrations → MCP connectors (e.g. Notion, Todoist — any service whose MCP server offers non-destructive write tools works best-effort). The scraped results are written through your own connector — the Actor never sees your third-party credentials. Only non-destructive write tools are used; it can never delete or overwrite your existing data.

## `deliverTarget` (type: `string`):

Where to write into the connector — paste the URL or ID. Notion example: https://www.notion.so/My-Posts-24f8a1b2c3d44e5f8a9b0c1d2e3f4a5b. Leave empty for services that need no target (e.g. Todoist Inbox, Slack). For Notion, share the page or database with your connector first (Notion's ••• → Connections menu), and point at a PAGE for structured columns (the Actor builds the database for you) — an empty database receives only the title (the rest of each record goes to the row's body).

## `deliverMode` (type: `string`):

perPost writes one record per scraped item; summary writes a single roll-up for the run.

## `deliverMaxItems` (type: `integer`):

Cap on how many records perPost mode writes to the connector; ignored in summary mode. Leave empty to deliver everything scraped.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.pinterest.com/pin/1054827543951238554/",
    "https://www.pinterest.com/ideas/beauty/935541271955/",
    "https://www.pinterest.com/dudadelsanto/",
    "https://www.pinterest.com/dudadelsanto/nail-inspo/",
    "https://www.pinterest.com/search/pins/?q=Valentine%E2%80%99s%20Nail%20Art&rs=hub_page"
  ],
  "getDetails": true,
  "includeComments": false,
  "includeCommentReplies": false,
  "includeUserInfoOnly": false,
  "maxItems": 20,
  "endPage": 1,
  "customMapFunction": "(object) => { return {...object} }",
  "deliverMode": "perPost"
}
```

# 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 = {
    "startUrls": [
        "https://www.pinterest.com/pin/1054827543951238554/",
        "https://www.pinterest.com/ideas/beauty/935541271955/",
        "https://www.pinterest.com/dudadelsanto/",
        "https://www.pinterest.com/dudadelsanto/nail-inspo/",
        "https://www.pinterest.com/search/pins/?q=Valentine%E2%80%99s%20Nail%20Art&rs=hub_page"
    ],
    "maxItems": 20,
    "endPage": 1,
    "customMapFunction": (object) => { return {...object} }
};

// Run the Actor and wait for it to finish
const run = await client.actor("epctex/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 = {
    "startUrls": [
        "https://www.pinterest.com/pin/1054827543951238554/",
        "https://www.pinterest.com/ideas/beauty/935541271955/",
        "https://www.pinterest.com/dudadelsanto/",
        "https://www.pinterest.com/dudadelsanto/nail-inspo/",
        "https://www.pinterest.com/search/pins/?q=Valentine%E2%80%99s%20Nail%20Art&rs=hub_page",
    ],
    "maxItems": 20,
    "endPage": 1,
    "customMapFunction": "(object) => { return {...object} }",
}

# Run the Actor and wait for it to finish
run = client.actor("epctex/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 '{
  "startUrls": [
    "https://www.pinterest.com/pin/1054827543951238554/",
    "https://www.pinterest.com/ideas/beauty/935541271955/",
    "https://www.pinterest.com/dudadelsanto/",
    "https://www.pinterest.com/dudadelsanto/nail-inspo/",
    "https://www.pinterest.com/search/pins/?q=Valentine%E2%80%99s%20Nail%20Art&rs=hub_page"
  ],
  "maxItems": 20,
  "endPage": 1,
  "customMapFunction": "(object) => { return {...object} }"
}' |
apify call epctex/pinterest-scraper --silent --output-dataset

```

## MCP server setup

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