# Pinterest Comment & Replies Scraper (`api-empire/pinterest-comment-scraper`) Actor

Pinterest Comment & Replies Scraper: Extract comments and replies from Pinterest pins with usernames, text, timestamps, pin URLs, and engagement data. Analyze audience feedback, discussions, content performance, and user interests for market research and social media insights.

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

## Pricing

from $4.99 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### Pinterest Comment Scraper — Extract Comments, Threads and Profiles

Pinterest Comment Scraper pulls every visible comment and "I tried it" post attached to a public Pinterest pin, returning commenter profiles, like and helpful counts, and attached media as typed JSON — no HTML, no selectors, no login. Point it at one pin or a batch of pin URLs and rows stream into the dataset as each page finishes, with a persistent seen-ID store so scheduled runs return only new comments. Read on for exactly which fields the dataset carries, how delta monitoring works, and where nested-reply linking currently stands.

### What is Pinterest Comment Scraper?

Pinterest Comment Scraper is an Apify Actor that turns a Pinterest pin URL (or numeric pin ID) into a structured feed of the comments, "I tried it" posts, and comment-summary rollups Pinterest attaches to that pin. It requests Pinterest's own comments resource directly — through a Chrome-TLS-impersonated HTTP client, not a headless browser — and normalizes every item it returns into one consistent JSON schema.

No Pinterest account, login, or cookie is required or accepted by the input schema. The Actor runs entirely logged out.

- Scrape top-level comments and "I tried it" posts from any public pin
- Capture the commenter's profile (username, display name, avatar, privacy flag) with every row
- Run bulk pin lists in a single job, across 22 regional Pinterest domains
- Schedule repeat runs that return only newly posted comments (delta mode)
- Export as JSON, CSV, Excel, or read the dataset through the Apify API — no HTML parsing on your end

### 🧵 What data does Pinterest Comment Scraper collect?

Pinterest's own comments endpoint (`UnifiedCommentsResource`) unifies three distinct content types under one feed, plus two embedded object types the Actor normalizes into every row.

| Data Type | Key Fields | JSON Field Names |
| --- | --- | --- |
| Comments | comment text, likes, timestamp | `details`, `like_count`, `done_at`, `type: "comment"` |
| "I tried it" posts | helpful votes, attached photo, review-style text | `helpful_count`, `images`, `marked_helpful_by_me`, `type: "userdiditdata"` |
| Aggregated comment rollups | Pinterest's own grouped-comment summary rows | `type: "aggregatedcomment"`, `comment_count` |
| Commenter profile | username, display name, avatar, private-account flag | `user.username`, `user.full_name`, `user.image_medium_url`, `user.is_private_profile` |
| Reply-thread schema | thread-linking fields, present but not populated on logged-out runs (see Output below) | `isReply`, `parentId` |

Every row also carries `comment_count` — Pinterest's own count of how many replies exist under that comment or "tried it" post — even on rows where the reply bodies themselves aren't fetched.

#### Need more Pinterest data?

If you need the pins themselves rather than their comment threads, **Pinterest Search Scraper** (also published under API Empire) turns a keyword into structured pin results — image and video URLs, creator and board objects, and destination links — and is a natural first step before feeding pin URLs into this Actor.

### Why not build this yourself?

Pinterest's official REST API (v5) does not publish a comments-read endpoint. Its documented OAuth scopes cover boards, pins, catalogs, ads, and user accounts — `ads:read`/`ads:write`, `boards:read`/`boards:write`, `catalogs:read`/`catalogs:write`, `pins:read`/`pins:write`, `user_accounts:read` — with no scope for reading comment threads on a pin (checked against Pinterest's developer documentation at developers.pinterest.com, 2026-07-25). There is no approved, documented path to pull a public pin's comment feed through Pinterest's own API, authenticated or not.

Building it yourself means reverse-engineering Pinterest's internal `UnifiedCommentsResource`, and getting there takes three separate stages before a single comment is returned. First, the pin's HTML has to be fetched to warm a `csrftoken` cookie and Pinterest's routing cookies — the legacy `aggregatedPinData` block this used to expose in server-rendered HTML has since been stripped, so a regex against that HTML is now a fallback path rather than the primary one. Second, the pin's internal `aggregated_pin_id` has to be resolved from Pinterest's closeup GraphQL query, identified by a Pinterest-issued persisted-query hash that Pinterest can rotate without notice, posted to whichever of two internal GraphQL endpoints is currently live. Third, only once that ID is in hand can `UnifiedCommentsResource` be paginated — with the `csrftoken` attached as a header, a page size capped at 100 by Pinterest itself, and a `bookmark` token carried forward between pages. None of these three stages is documented publicly; every one of them was reverse-engineered and has to be re-verified whenever Pinterest redeploys the query. Layered on top of all three: Chrome-accurate TLS and header fingerprints and a proxy escalation path, because Pinterest treats a generic HTTP client as a bot regardless of whether the request itself is correct.

If you already operate inside Pinterest's approved API for your own business account's boards, ads, or catalog, use it. For reading comment threads on arbitrary public pins, there is no official surface to compare against — this is the only route.

### Why do developers and teams scrape Pinterest comments?

#### For AI engineers and agent builders

Pinterest comment threads are unstructured brand and product sentiment that's hard to reach through any official API. Pulling `details`, `like_count`, and `helpful_count` per comment gives an agent or RAG pipeline a ready-made signal for "what are people saying under this pin" without a scraping step inside the agent loop itself. A social-listening tool can index `details` text per `pinUrl` into a vector store, and an agent can be handed a tool that answers "what's the sentiment on our latest product pin" by reading typed JSON rather than parsing rendered comment threads.

#### For marketers and brand teams

`type: "userdiditdata"` rows are Pinterest's "I tried it" posts — real product-use feedback with `helpful_count` votes and attached `images`, distinct from ordinary comments. A brand team monitoring a product pin can pull these separately from `type: "comment"` rows to see which user-generated content is earning helpful votes, and re-run the same pin on a schedule with `continueOnDuplicates` left at its default to catch new UGC as it posts, without re-processing comments already reviewed.

#### For researchers and analysts

Because the Actor returns only what an anonymous visitor already sees, it's usable for public-discourse research on Pinterest engagement patterns without touching gated or private content. `done_at` timestamps let you build a time series of comment volume on a pin, and the `user.is_private_profile` flag lets you separate commenters with public profiles from those Pinterest itself marks private — useful when a study needs to report only on identifiably public participation.

#### For developers building data products

The persistent seen-ID store (`continueOnDuplicates=false` by default) turns this Actor into a delta feed rather than a full re-scrape on every scheduled run: Apify Schedules can trigger it hourly or daily against the same pin list, and only comment IDs not seen in a prior run get pushed and charged. That's the primitive for a moderation queue, a comment-alert pipeline, or an engagement dashboard that updates incrementally instead of reprocessing the same thread every run.

### How to scrape Pinterest comments (step by step)

1. Open Pinterest Comment Scraper on its Apify Store listing and click **Try for free**
2. Paste one or more Pinterest pin URLs or numeric pin IDs into **`urls`** — this is the only required input
3. Optionally set **`domain`** to match the region your pins live in, and **`limit`** to how many comments per pin you want
4. Click **Start**
5. Download results as JSON, CSV, or Excel from the run's dataset, or read it through the Apify API

#### What to do when Pinterest changes its structure

The Actor is maintained, and the output schema — field names and types — stays stable on your end even when Pinterest changes how it serves comment data internally. No specific turnaround time is promised for any given break; the schema contract to your integration is what's maintained.

### ⬇️ Input

Six parameters, only `urls` required, taken directly from the Actor's input schema.

| Parameter | Required | Type | Description | Example Value |
| --- | --- | --- | --- | --- |
| `urls` | Yes | array | Pinterest pin links or numeric IDs to pull comment threads from. Bulk input supported. | `["https://www.pinterest.com/pin/979532987719137952/"]` |
| `domain` | No | string | Pinterest regional domain to request. Match the region where your pins live. Default `"www.pinterest.com"`. One of 22 enum values (below). | `"jp.pinterest.com"` |
| `limit` | No | integer | Caps the number of comments returned per pin. Minimum `1`. Default `10`. | `50` |
| `continueOnDuplicates` | No | boolean | `false` (default) = delta mode: comment IDs seen in previous runs are skipped, so scheduled runs push only new comments. `true` = push every comment every run. | `false` |
| `endPage` | No | integer | Caps how many comment pages are paginated per pin. Minimum `0`. `0` (default) = unlimited — paginate until Pinterest stops returning a bookmark. Use `1`–`2` for quick sampling of high-traffic pins. | `2` |
| `proxyConfiguration` | No | object | Apify Proxy settings. Starts direct (no proxy) by default (`{"useApifyProxy": false}`), then auto-escalates no proxy → datacenter → residential if Pinterest throttles a request. | `{"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}` |

`domain` accepts one of: `www.pinterest.com` (US/Global), `jp.pinterest.com` (Japan), `br.pinterest.com` (Brazil), `uk.pinterest.com` (United Kingdom), `au.pinterest.com` (Australia), `nz.pinterest.com` (New Zealand), `co.pinterest.com` (Canada), `de.pinterest.com` (Germany), `fr.pinterest.com` (France), `in.pinterest.com` (India), `es.pinterest.com` (Spain), `it.pinterest.com` (Italy), `nl.pinterest.com` (Netherlands), `pl.pinterest.com` (Poland), `ru.pinterest.com` (Russia), `tr.pinterest.com` (Turkey), `mx.pinterest.com` (Mexico), `ar.pinterest.com` (Argentina), `id.pinterest.com` (Indonesia), `ph.pinterest.com` (Philippines), `th.pinterest.com` (Thailand), `kr.pinterest.com` (South Korea).

`urls` also accepts `{"url": "..."}` objects and a single comma-separated string mixed into the list, for compatibility with output piped in from another tool.

**Domain fallback:** if a pin's internal ID can't be resolved on the `domain` you set, the Actor retries that one pin against `www.pinterest.com` before giving up on it. If the fallback succeeds, that pin's `pinUrl` in the output reflects `www.pinterest.com` rather than your originally requested domain — worth knowing if you're grouping output by domain downstream.

#### Example input

```json
{
  "urls": [
    "https://www.pinterest.com/pin/979532987719137952/",
    "1103982746501823456"
  ],
  "domain": "www.pinterest.com",
  "limit": 50,
  "continueOnDuplicates": false,
  "endPage": 0,
  "proxyConfiguration": { "useApifyProxy": false }
}
```

**Common pitfall:** leaving `limit` at its default of `10` and expecting a full thread history back — raise `limit` (and `endPage`, which is unlimited by default) for deeper extraction. Also remember `continueOnDuplicates` defaults to `false`: a second run against the same pin with no new activity will correctly return zero rows, since every comment ID was already recorded in the seen-ID store on the first run.

#### How delta monitoring persists across runs

`continueOnDuplicates` is backed by a named Apify key-value store, `pinterest-comment-seen-ids`, that survives independently of any single run. At the start of a run the Actor opens that store, reads the `seen_comment_ids` key (an empty set on a fresh account), and holds it in memory. Every comment ID pushed during the run is added to that set, and at the end the union of previously-seen and newly-seen IDs is written back to the same key — so the next scheduled run, regardless of which pins it targets, starts from the full history of every comment ID this Actor has ever pushed on your account. Leaving `continueOnDuplicates` at `false` and pointing an Apify Schedule at the same pin list on an interval is what turns this into a delta feed: the first run returns everything up to `limit`, and every run after that returns only what's new since the last one.

### ⬆️ Output

Every dataset row is one comment, "I tried it" post, or aggregated comment rollup — 18 top-level keys per row, built directly by the Actor's row-normalization step. The default dataset **view** surfaces 11 of those 18 columns (`pinUrl`, `id`, `type`, `isReply`, `parentId`, `details`, `user`, `like_count`, `helpful_count`, `comment_count`, `done_at`); the remaining 7 — `node_id`, `tags`, `videos`, `marked_helpful_by_me`, `image_signatures`, `images`, `liked_by_me` — are still written to every row and are available in the full JSON/CSV/Excel export and via the Apify API. Export as JSON, CSV, Excel, or consume the dataset directly through `apify_client`.

This Actor bills on Apify's pay-per-event model: each dataset row pushed is one charged `row_result` event, so a pin you skip because it's unreachable, or a comment ID your run skips because `continueOnDuplicates` is `false` and it's already in the seen-ID store, is never charged. If a run reaches its configured event charge limit mid-pin, the Actor stops pushing further rows for that pin, logs that the limit was reached, and moves on rather than pushing additional unbilled or partial rows.

#### Full field reference

| Field | Type | Description | In default view? |
| --- | --- | --- | --- |
| `pinUrl` | string | URL of the pin the row belongs to, built from the resolved domain and pin ID | Yes |
| `id` | string | null | Comment or "I tried it" post ID | Yes |
| `node_id` | string | null | Pinterest's internal base64-encoded node identifier for the item | No |
| `type` | string | One of `"comment"`, `"userdiditdata"`, or `"aggregatedcomment"` | Yes |
| `details` | string | The comment or post text; empty string for image-only "I tried it" posts with no caption | Yes |
| `user` | object | Commenter profile — see fields below | Yes |
| `like_count` | integer | Likes on a `"comment"`-type row | Yes |
| `helpful_count` | integer | Helpful votes on a `"userdiditdata"`-type row | Yes |
| `comment_count` | integer | Number of replies Pinterest reports under this item | Yes |
| `images` | array | Attached image objects — see structure below. `[]` when no image is attached | No |
| `image_signatures` | array of strings | Raw pinimg signature hashes the `images` URLs are derived from | No |
| `videos` | array | Attached video objects, if any; typically `[]` | No |
| `tags` | array | Tags Pinterest attaches to the item; typically `[]` | No |
| `liked_by_me` | boolean | Whether the requesting session liked the comment. Always `false` on logged-out runs | No |
| `marked_helpful_by_me` | boolean | Whether the requesting session marked the post helpful. Always `false` on logged-out runs | No |
| `done_at` | string | null | Timestamp the comment/post was created, as returned by Pinterest | Yes |
| `isReply` | boolean | Thread flag. Always `false` — see "How nested replies are represented" above | Yes |
| `parentId` | string | null | Parent comment ID for a reply. Always `null` — see "How nested replies are represented" above | Yes |

`user` is a normalized commenter object with 8 fields on every row: `node_id`, `id` (falls back to Pinterest's `user_id` when `id` is absent), `username`, `first_name`, `full_name` (falls back to `first_name` when Pinterest doesn't return a full name), `image_medium_url` (falls back to Pinterest's default avatar when the commenter has none), `is_private_profile`, and `type` (always `"user"`).

Each entry in `images` carries three fixed size keys — `originals`, `550x`, `150x150` — each an object of `{ "url": string, "width": integer | null, "height": integer | null }`. `url` is always populated; `width`/`height` are the real values Pinterest's API returned for that size, or `null` when Pinterest didn't report a dimension for it — never a guessed or synthetic number.

#### Scraped comment

```json
{
  "pinUrl": "https://www.pinterest.com/pin/979532987719137952/",
  "node_id": "VXNlckRpZEl0RGF0YTozMTExMzY4MDM0OTM5NjgzMDA4",
  "helpful_count": 0,
  "tags": [],
  "videos": [],
  "comment_count": 12,
  "marked_helpful_by_me": false,
  "image_signatures": ["b9b6949253414ee5f212efdc19e6dca5"],
  "user": {
    "node_id": "VXNlcjoxMTE4MTU5NTUxMTQxODIwOTA3",
    "image_medium_url": "https://i.pinimg.com/75x75_RS/99/b3/18/99b31856b968a39b3ff20eefb3b5fa2b.jpg",
    "is_private_profile": false,
    "username": "ambweb7539",
    "first_name": "Ambweb",
    "full_name": "Ambweb",
    "type": "user",
    "id": "1118159551141820907"
  },
  "like_count": 72,
  "images": [
    {
      "originals": { "url": "https://i.pinimg.com/originals/b9/b6/94/b9b6949253414ee5f212efdc19e6dca5.jpg", "width": 810, "height": 1080 },
      "550x": { "url": "https://i.pinimg.com/550x/b9/b6/94/b9b6949253414ee5f212efdc19e6dca5.jpg", "width": null, "height": null },
      "150x150": { "url": "https://i.pinimg.com/150x150/b9/b6/94/b9b6949253414ee5f212efdc19e6dca5.jpg", "width": 150, "height": 150 }
    }
  ],
  "type": "userdiditdata",
  "done_at": "Wed, 31 Dec 2025 05:13:13 +0000",
  "details": "",
  "liked_by_me": false,
  "id": "3111368034939683008",
  "isReply": false,
  "parentId": null
}
```

`images` entries only have a `width`/`height` when Pinterest's own API response supplied real dimensions for that size — otherwise both are returned as `null` rather than a guessed value, so a `null` means "not reported," not "zero."

A `type: "comment"` row carries the same 18 keys with `details` populated and `helpful_count`/`marked_helpful_by_me` sitting at their zero/`false` defaults instead:

```json
{
  "pinUrl": "https://www.pinterest.com/pin/979532987719137952/",
  "node_id": "Q29tbWVudDoxMDczOTI4Mzc0NjUwMTgyMzQ1Ng==",
  "helpful_count": 0,
  "tags": [],
  "videos": [],
  "comment_count": 0,
  "marked_helpful_by_me": false,
  "image_signatures": [],
  "user": {
    "node_id": "VXNlcjo3NzcwMDExMjIzMzQ0NTU2Njc3",
    "image_medium_url": "https://i.pinimg.com/75x75_RS/61/2a/9e/612a9e2f1b4e6c3d5a7f8901234567ab.jpg",
    "is_private_profile": false,
    "username": "designlover22",
    "first_name": "Dana",
    "full_name": "Dana K.",
    "type": "user",
    "id": "7770112233445566772"
  },
  "like_count": 5,
  "images": [],
  "type": "comment",
  "done_at": "Tue, 03 Feb 2026 09:41:22 +0000",
  "details": "Love this idea for a small backyard!",
  "liked_by_me": false,
  "id": "1073928374650182346",
  "isReply": false,
  "parentId": null
}
```

#### How nested replies are represented

Every row carries `isReply` (boolean) and `parentId` (string or `null`) so the schema is thread-ready: a reply row is designed to carry `"isReply": true` with `parentId` set to the `id` of the comment it replies to, flattening a conversation tree into parent/child rows rather than a nested array — the same pattern shown below is what the schema is built for:

```json
// Top-level comment — designed shape
{ "id": "3111368034939683008", "isReply": false, "parentId": null, "details": "Love this idea!" }

// Reply to that comment — designed shape, currently not produced
{ "id": "3111368034939700111", "isReply": true, "parentId": "3111368034939683008", "details": "Same, saving this." }
```

**Current status:** Pinterest has retired the legacy REST resources that used to serve reply threads (they now return an internal "not a valid resource" error) and now serves nested replies only through an authenticated, UI-gated GraphQL query that isn't reachable from a logged-out request. Because this Actor runs entirely logged out, `isReply` always resolves to `false` and `parentId` always resolves to `null` on every row it currently produces — you get top-level comments and "I tried it" posts only. `comment_count` still tells you how many replies exist under a given comment even though the reply bodies themselves aren't fetched.

### How does Pinterest Comment Scraper compare to other social comment scrapers?

| Feature | Pinterest Comment Scraper | Generic alternative |
| --- | --- | --- |
| Output format | Typed, normalized JSON with a fixed 18-key schema per row | Often raw HTML or an unnormalized API passthrough |
| Entity coverage | Comments, "I tried it" posts, and aggregated comment rollups in one unified feed | Frequently comments only |
| Delta / dedup monitoring | Built-in persistent seen-ID store; `continueOnDuplicates=false` returns only new comments on repeat runs | Usually requires the caller to diff results themselves |
| Login requirement | None — no credential field exists in the input schema | Several comment scrapers on other platforms require pasted session cookies |
| Reply-thread linkage | Schema-ready (`isReply`/`parentId`), not currently populated — documented rather than hidden | Rarely documented when a competitor's reply support is partial |

If you're building an AI agent or RAG pipeline, the output-format row is the decision-maker — parsing HTML inside an agent loop is a reliability failure mode, not a feature, and a fixed JSON schema is what lets a tool call be trusted without a post-processing step.

### How many comments can you scrape with Pinterest Comment Scraper?

`limit` caps comments per pin with no schema-enforced maximum — the default is `10`, and there is no hard ceiling written into the input validation, only a minimum of `1`. Pagination is handled automatically: the Actor requests Pinterest's comments resource in pages of up to 100 items (Pinterest's own comments API rejects a larger page size with an internal "page size is too large" error) and follows the `bookmark` token Pinterest returns until either your `limit` is reached, Pinterest stops returning a bookmark, or `endPage` (default `0`, unlimited) caps the page count for that pin. There is no independently measured benchmark for how long a given `limit` takes to collect — that depends on how many comments the pin actually has and Pinterest's own response times.

### Integrate Pinterest Comment Scraper and automate your workflow

Pinterest Comment Scraper works with any language or tool that can send an HTTP request, since it runs as a standard Apify Actor behind the Apify API.

#### REST API integration

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")

run = client.actor("<YOUR_USERNAME>/pinterest-comment-replies-scraper").call(run_input={
    "urls": ["https://www.pinterest.com/pin/979532987719137952/"],
    "limit": 50,
    "continueOnDuplicates": False,
})

for comment in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(comment["type"], comment["user"]["username"], comment["details"])
```

Works in Python, Node.js, Go, Ruby, and cURL — any language that can make an HTTP request against the Apify API.

#### Automation platforms (n8n, Make)

In n8n, the Apify node can start this Actor and read back its dataset directly, or an HTTP Request node pointed at the Apify run endpoint with your token and the same JSON input shown above works identically. In Make, the Apify module can trigger a run on a schedule and map dataset rows straight into a Google Sheets or Airtable step, which is enough to build a scheduled "new Pinterest comments" feed without writing code.

### Is it legal to scrape Pinterest comments?

Scraping publicly accessible data is broadly permitted where no login or authentication is required to view it, and Pinterest Comment Scraper returns only what an anonymous visitor already sees on a public pin's comment thread.

Comment rows include personal data about the commenter — username, display name, and avatar image — so GDPR and CCPA considerations apply to how you store, process, and reuse that data, not just to collecting it. Having a lawful basis for storage and use of any personal data you retain is your responsibility as the data controller.

Consult legal counsel for commercial use cases involving bulk personal data, particularly before combining commenter profile data with other identifying sources.

### ❓ Frequently asked questions

#### Does Pinterest Comment Scraper work without a Pinterest account?

Yes. The input schema has no credential, cookie, or login field of any kind — the Actor runs entirely logged out, using Chrome TLS impersonation to request Pinterest's own comments resource directly. The only account you need is your Apify account, to run the Actor.

#### How often is the scraped data updated?

Each run performs a live fetch against Pinterest at the time you start it — there is no cache. The only thing persisted between runs is the seen-comment-ID store used for delta monitoring, which affects which rows get pushed, not what data is fetched.

#### What happens if a pin is deleted, private, or has no comments?

If the Actor can't resolve the pin's internal ID — because the pin is deleted, geo-restricted, or otherwise login-walled — it raises an error for that pin, logs "Skipped pin `<id>`: Could not resolve aggregated\_pin\_id for pin `<id>` (dead pin or login-walled)," and moves on to the next pin in your list. No row is pushed and nothing is charged for that pin; the run's log lists every skipped pin ID at the end. A pin with zero comments simply returns zero rows for that pin without an error.

#### Can I scrape private or restricted Pinterest comment threads?

No. Only comments visible to an anonymous visitor on a public pin are returned. Pins that are private, deleted, or otherwise gated behind a Pinterest login are skipped, not bypassed.

#### Does Pinterest Comment Scraper actually return nested replies?

Not currently, on logged-out runs. Pinterest retired the REST resources that used to serve reply threads and now gates nested replies behind an authenticated GraphQL query this Actor doesn't call. The `isReply` and `parentId` fields are present on every row for a thread-ready schema, but they resolve to `false`/`null` on every row this Actor currently produces. `comment_count` still reports how many replies exist under a comment even though the reply text isn't fetched — see "How nested replies are represented" in the Output section above.

#### Does Pinterest Comment Scraper work for AI agent workflows and LLM pipelines?

Yes. It's callable as a standard HTTP endpoint through the Apify API, so any agent framework that can make a request — LangChain, CrewAI, a custom tool definition, n8n — can invoke it and receive typed JSON with no parsing step before passing results to an LLM.

#### How does Pinterest Comment Scraper handle Pinterest's anti-bot system?

Requests are sent through `curl_cffi` with a Chrome 131 TLS/JA3 fingerprint rather than a default HTTP client signature, with a `csrftoken` cookie warmed from an initial pin-page request and randomized 1–2 second delays between requests. Failed requests retry up to three times with exponential backoff before the Actor escalates through a no-proxy → Apify Datacenter proxy → Apify Residential proxy chain (with up to three residential retries), so a single throttled pin doesn't require you to manually switch proxy tiers.

#### How does Pinterest Comment Scraper compare to other comment scrapers?

Checked on the Apify Store, 2026-07-25: `apimaestro/linkedin-post-comments-replies-engagements-scraper-no-cookies` covers LinkedIn post comments and replies with sorting options and no login required, and its listing advertises processing posts "in batches very fast" — not measured here. `curious_coder/twitter-replies-scraper` requires pasted Twitter session cookies to run, unlike this Actor's fully logged-out approach. `datadoping/instagram-comments-and-replies-scraper` covers Instagram comments and replies without a cookie and its listing advertises scraping "up to 10,000 comments per post" — not measured here. Pinterest Comment Scraper's difference on its own platform is unifying three real Pinterest content types (comments, "I tried it" posts, and aggregated rollups) into one schema, plus a persistent delta-monitoring store none of the three above document.

#### Does Pinterest Comment Scraper return data in a format LLMs can use directly?

Yes. Every response is typed, normalized JSON with stable field names across runs. No HTML, no selectors. Pass a row directly into an LLM context window, index it into a vector store, or route it through an agent tool.

#### Can I use Pinterest Comment Scraper without managing proxies?

Yes. Left at its default (`{"useApifyProxy": false}`), the Actor starts with no proxy and automatically escalates to Apify Datacenter, then Apify Residential, if Pinterest throttles a request — you never rotate an IP or manage a proxy account yourself. You can also pin `proxyConfiguration` to Residential directly if you expect heavy throttling from the start.

#### What happens when Pinterest changes its structure or blocks the scraper?

The scraper is maintained, and the output schema stays stable on your end — field names and types don't change because Pinterest changed something internally. No specific turnaround time is promised for any given break.

### 🔗 Related scrapers

| Scraper Name | What it extracts |
| --- | --- |
| Pinterest Search Scraper | Pin search results for a keyword — images, videos, creator and board objects, destination links |

### 💬 Your feedback

Found a bug, or need a field that Pinterest's comments resource returns but this Actor doesn't surface yet? Open an issue on the Actor's Issues tab on Apify and it will be looked at. Include a pin URL that reproduces the issue — that's the fastest way to get a fix.

# Actor input Schema

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

Pinterest pin links or numeric IDs to pull comment threads from. Bulk input supported. Example: https://www.pinterest.com/pin/979532987719137952/

## `domain` (type: `string`):

Pinterest regional domain to request. Match the region where your pins live (e.g. jp.pinterest.com for Japan).

## `limit` (type: `integer`):

Caps the number of comments returned per pin. Default: 10. Raise for fuller extraction.

## `continueOnDuplicates` (type: `boolean`):

OFF (default) = delta mode: comment IDs seen in previous runs are skipped, so scheduled runs only push NEW comments. ON = push every comment every run.

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

Cap how many comment pages are paginated per pin. 0 = unlimited (paginate until the end). Use 1-2 for quick sampling of high-traffic pins.

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

Optional. Starts direct, then auto-falls back no proxy -> datacenter -> residential if Pinterest throttles.

## Actor input object example

```json
{
  "urls": [
    "https://www.pinterest.com/pin/979532987719137952/"
  ],
  "domain": "www.pinterest.com",
  "limit": 10,
  "continueOnDuplicates": false,
  "endPage": 0,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

All scraped items in the Actor's default dataset.

# 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 = {
    "urls": [
        "https://www.pinterest.com/pin/979532987719137952/"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("api-empire/pinterest-comment-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 = {
    "urls": ["https://www.pinterest.com/pin/979532987719137952/"],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("api-empire/pinterest-comment-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 '{
  "urls": [
    "https://www.pinterest.com/pin/979532987719137952/"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call api-empire/pinterest-comment-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,api-empire/pinterest-comment-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/3gCbi7PaRpa9SviKz/builds/HplAMNYjXMx6Xt5Mo/openapi.json
