# 📌 Pinterest Comment Scraper (`scrapier/pinterest-comment-scraper`) Actor

Scrape Pinterest comments to extract comment text, usernames, profile URLs, timestamps, and engagement data. Analyze audience feedback, discover trends, monitor competitors, research customer sentiment, and collect valuable insights from Pinterest content for marketing and market research.

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

## Pricing

from $5.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 — Bulk Pins Across 22 Regions

Pinterest Comment Scraper pulls every comment, "Tried It" activity row, like count, and helpful vote off one or many Pinterest pins, using the same internal `UnifiedCommentsResource` endpoint the Pinterest web app itself calls. Feed it pin URLs or bare numeric IDs — one or hundreds at once — and it returns commenter profiles, engagement counts, timestamps, and attached images as clean, typed JSON. Every response is structured JSON, ready to pass directly to an LLM, index into a vector store, or feed a sentiment-monitoring pipeline. No Pinterest login, no browser, no manual pagination — just a query in and a comment feed out.

### What is Pinterest Comment Scraper?

Pinterest Comment Scraper is a bulk comment-extraction Actor: give it a list of pin URLs or IDs and it queries Pinterest's internal comments API for each one, paginating through every comment until it hits your `limit` or Pinterest stops returning data. It does not require a Pinterest account — public pins are readable logged-out, and the Actor resolves the session it needs (a `csrftoken` cookie) by visiting the pin page first, exactly as a browser would. What sets it apart from a single-pin comment fetcher is that it treats the pin list as a batch job across up to 22 regional Pinterest domains in one run, and every row it writes carries the exact `pinUrl` it came from — so a bulk, multi-region job stays fully auditable line by line.

Key capabilities:

- **Bulk pin input** — pass one pin or hundreds in a single `urls` array; no per-pin runs needed
- **22 regional domains** — `www.pinterest.com` plus 21 country subdomains (Japan, Brazil, UK, Australia, Germany, France, India, and more), selectable per run
- **Per-pin comment cap** — the `limit` parameter caps how many comments are pulled per pin, independent of how many pins you queue
- **Commenter profiles** — username, full name, first name, avatar, numeric user ID, and private-profile flag on every row
- **Engagement counts** — `like_count` and `helpful_count`, read straight off Pinterest's `reaction_counts`
- **Live per-row saving** — each comment is pushed to the dataset the moment it's fetched, so a killed or interrupted run still keeps whatever it already collected

Under the hood, the Actor doesn't call a single documented endpoint — it reconstructs the sequence a browser performs. Pinterest no longer embeds the `aggregated_pin_data.id` a comment fetch needs directly in the logged-out pin HTML, so the Actor first requests the pin page to seed a `csrftoken` cookie, resolves the aggregated pin ID through Pinterest's internal `PinResource` endpoint, and only then pages through `UnifiedCommentsResource` using that ID and a `bookmark` cursor. Each page request is capped at 100 items (`PAGE_SIZE`) because Pinterest rejects larger pages for logged-out sessions; the Actor keeps requesting pages until either your `limit` is reached or Pinterest stops returning a `bookmark`.

### What data can you get with Pinterest Comment Scraper?

The Actor returns one dataset row per comment / activity item found under a pin, each carrying the comment content, its author, and engagement counts.

| Result Type | Extracted Fields | Primary Use Case |
| --- | --- | --- |
| Comment / activity row | `id`, `type`, `details`, `done_at`, `like_count`, `helpful_count`, `comment_count`, `tags`, `videos`, `image_signatures`, `images`, `marked_helpful_by_me`, `liked_by_me`, `node_id`, `pinUrl` | Sentiment analysis, UGC mining, engagement tracking |
| Commenter profile (nested `user` object) | `id`, `node_id`, `username`, `first_name`, `full_name`, `image_medium_url`, `is_private_profile`, `type` | Audience research, influencer/commenter identification |

#### Bulk multi-pin, multi-region extraction

This is the capability that separates a batch tool from a single-pin fetcher. The `urls` input accepts a plain array — mix pin links from different campaigns, boards, or accounts in one job — and `domain` lets you point the whole run (or a re-run of the same list) at any of 22 Pinterest country subdomains. Every dataset row still carries its own `pinUrl`, so results from a 50-pin batch across three regions land in one dataset and remain traceable back to the exact pin and domain that produced them. Two competing Pinterest comment scrapers on the Apify Store document a single `pinUrl` / `post_url` string field only — one pin per run (checked on the Apify Store 2026-07-25) — which means looping a batch job yourself, one run per pin.

| | Pinterest Comment Scraper | easyapi's listing | scrapestorm's listing |
| --- | --- | --- | --- |
| Pins per run | Array (`urls`), unlimited entries | Single `pinUrl` string | Single `post_url` string |
| Region / domain selector | 22-value `domain` enum | Not documented | Not documented |
| Live per-row dataset saving | Yes | Not documented | Not documented |
| "Tried It" (Did-It) activity rows | Included (`userdiditdata`) | Included in sample output | Not present in sample output |
| Pricing model | Pay per event (per row) | Pay per event | Flat $9.90/month |

*Comparison built from each Actor's own published Store listing and README, checked 2026-07-25. Pricing and feature claims for competitors are theirs as documented, not independently verified.*

```json
{
  "urls": [
    "https://www.pinterest.com/pin/1618549864585211/",
    "https://jp.pinterest.com/pin/636977941054343221/",
    "824719026351884433"
  ],
  "domain": "www.pinterest.com",
  "limit": 50
}
```

#### Commenter profiles

Every comment row nests a normalized `user` object — not just a username string. That means you get the commenter's numeric Pinterest `id` and GraphQL `node_id` (stable identifiers you can use to de-duplicate or track a commenter across pins), their `full_name` and `username`, an avatar URL, and an `is_private_profile` flag so you know upfront which profiles you can't enrich further. Useful for building a ranked list of your most engaged commenters, or for flagging when the same account keeps showing up across a brand's pins.

### Why not build this yourself?

Pinterest doesn't publish a general-purpose API for reading comments on arbitrary public pins — its official developer platform is scoped to managing your own ads, catalogs, and pins, not pulling engagement data off someone else's content. Building a scraper for this from scratch means solving three problems this Actor already solves: Pinterest strips the `aggregated_pin_data.id` a comment fetch needs out of the logged-out pin HTML, so you have to seed a session and resolve it through the internal `PinResource` endpoint with a live CSRF token; Pinterest's anti-bot layer fingerprints TLS handshakes, so a plain `requests` or `httpx` client gets soft-blocked quickly; and once you do get blocked, you need a proxy escalation path (datacenter, then residential) rather than a hard failure. None of that is exposed anywhere in Pinterest's documentation — it has to be reverse-engineered from the web app's own network traffic, and it changes without notice when Pinterest ships a frontend update. Maintaining that yourself means re-diagnosing broken requests every time Pinterest tweaks its internal API; running it as an Actor means someone else absorbs that churn.

The TLS-fingerprinting piece specifically is easy to underestimate: a standard Python HTTP client (`requests`, `httpx`, even a naive `aiohttp` session) presents a TLS handshake that's trivially distinguishable from a real browser's, and Pinterest's edge layer can soft-block on that signature alone before your request logic ever runs. Matching a real Chrome build's JA3 fingerprint — which is what `curl_cffi`'s `impersonate` parameter does — isn't something you bolt on after the fact; it has to be the transport layer from the start.

### What's the difference between a comment and "Tried It" activity data?

A **comment** is text someone typed under a pin. **"Tried It" (Did It) activity** is Pinterest's separate engagement mechanism where a user marks that they made or tried the pinned idea, optionally attaching their own photo and a short note — it shows up in the same comment thread UI but is a structurally different object. Pinterest's `UnifiedCommentsResource` — the endpoint this Actor queries — returns both mixed together in the same feed, tagged by a `type` field. This Actor keeps every row whose `type` is `comment`, `aggregatedcomment`, or `userdiditdata` (Pinterest's three valid types for this feed) and normalizes them into the same output shape, so you don't have to write separate parsing logic for each.

The distinction matters if you're doing sentiment analysis: a `userdiditdata` row's `details` field is often empty (someone tried it and said nothing), while `comment` and `aggregatedcomment` rows are almost always straight text. Filter on the `type` field in your downstream pipeline if you only want written commentary, or keep everything if you want the full engagement picture — likes and helpful votes are counted identically across all three types.

`aggregatedcomment` versus plain `comment` is a narrower distinction within the written-text category: Pinterest groups some comments under an aggregated thread node (`aggregatedcomment`) when they're part of a larger comment cluster on high-traffic pins, versus a standalone `comment` node on pins with lighter comment activity. Both carry the same fields in this Actor's output — the same `details`, `user`, `like_count`, and `helpful_count` — so downstream code that doesn't specifically care about Pinterest's internal thread structure can treat the two identically and just branch on `userdiditdata` when it wants to separate "said something" from "did something."

### How to scrape Pinterest comments with Pinterest Comment Scraper?

1. Open **Pinterest Comment Scraper** on the Apify Store and click **Try for free** (or find it in your Apify Console if you've used it before).
2. Paste your pin links or numeric IDs into `urls` — this is the only required field.
3. Set `domain` to match where your pins live (default `www.pinterest.com`), and set `limit` to how many comments you want per pin (default `10`).
4. Click **Start** — the run streams collected comments into the log in real time as they're scraped.
5. Open the **Storage** tab once the run finishes (or mid-run, since rows save live) and export as JSON, CSV, Excel, HTML table, or XML.

```json
{
  "urls": ["https://www.pinterest.com/pin/1618549864585211/"],
  "domain": "www.pinterest.com",
  "limit": 100,
  "proxyConfiguration": { "useApifyProxy": false }
}
```

#### How to run multiple queries in one job

`urls` takes a plain array, so a bulk job is just a longer list — string list editor in the Console, or a JSON array via the API. Each entry can be a full pin URL, a bare numeric pin ID, or `{ "url": "..." }`; the Actor normalizes all three before processing. There's no separate batch mode or bulk-upload file format — the array itself is the batch. Pins are processed sequentially with a randomized 1–2 second delay between requests to stay under Pinterest's rate-limiting radar, so a very large `urls` list will take proportionally longer; the Actor does not expose a configurable concurrency setting.

### ⬇️ Input

Four fields, one required. Configure them in the Apify Console's input form or pass them as JSON via the API.

| Parameter | Required | Type | Default | Constraints |
| --- | --- | --- | --- | --- |
| `urls` | **Yes** | array | — | List of Pinterest pin URLs or numeric IDs. Accepts plain strings or `{ "url": "..." }` objects. Uses the `stringList` editor in the Console. |
| `domain` | No | string | `"www.pinterest.com"` | One of 22 enum values: `www.pinterest.com`, `jp.pinterest.com`, `br.pinterest.com`, `uk.pinterest.com`, `au.pinterest.com`, `nz.pinterest.com`, `co.pinterest.com`, `de.pinterest.com`, `fr.pinterest.com`, `in.pinterest.com`, `es.pinterest.com`, `it.pinterest.com`, `nl.pinterest.com`, `pl.pinterest.com`, `ru.pinterest.com`, `tr.pinterest.com`, `mx.pinterest.com`, `ar.pinterest.com`, `id.pinterest.com`, `ph.pinterest.com`, `th.pinterest.com`, `kr.pinterest.com`. |
| `limit` | No | integer | `10` | Minimum `1`. No maximum is enforced by the schema — internally each API page request is capped at 100 comments, and the Actor pages until it reaches your `limit` or Pinterest stops returning a bookmark. |
| `proxyConfiguration` | No | object | `{ "useApifyProxy": false }` | Standard Apify proxy configuration object. Starts with no proxy; the Actor auto-escalates to Apify Proxy (datacenter, then residential) on repeated failures regardless of this setting — see the pitfall note below. |

#### Example JSON input

```json
{
  "urls": [
    "https://www.pinterest.com/pin/1618549864585211/",
    "https://uk.pinterest.com/pin/824719026351884433/",
    "824719026351884433"
  ],
  "domain": "www.pinterest.com",
  "limit": 100,
  "proxyConfiguration": { "useApifyProxy": false }
}
```

**Common pitfall:** the Actor extracts a pin ID from each `urls` entry by matching the `/pin/<digits>/` pattern in the URL; entries with a `/` that don't match that pattern — a board URL, a profile URL, or a malformed link — will fail to parse. Pass only pin URLs or bare numeric IDs, not board or profile links. Separately, if you set `domain` to a country subdomain (e.g. `jp.pinterest.com`) and that domain fails to resolve the pin's aggregated data, the Actor silently retries once against `www.pinterest.com` before giving up on that pin — the row it eventually returns may then carry a `pinUrl` on the global domain even though you selected a regional one.

### ⬆️ Output

Every result is typed, normalized JSON pushed to the Actor's default dataset, one item per comment or activity row. The schema is identical across runs regardless of which of the three Pinterest row types (`comment`, `aggregatedcomment`, `userdiditdata`) produced it. Export as JSON, JSONL, CSV, Excel, HTML table, or XML from the Storage tab or via the API. The Console's default dataset view surfaces 8 columns (`pinUrl`, `id`, `type`, `details`, `user`, `like_count`, `helpful_count`, `done_at`) for quick scanning — the underlying row carries 16 top-level keys, listed below in full.

#### Scraped results

```json
[
  {
    "pinUrl": "https://www.pinterest.com/pin/1618549864585211/",
    "node_id": "QWdncmVnYXRlZENvbW1lbnQ6NTM2NzQzMTI4NDY0NTczODkwMg==",
    "helpful_count": 0,
    "tags": [],
    "videos": [],
    "comment_count": 0,
    "marked_helpful_by_me": false,
    "image_signatures": [],
    "user": {
      "node_id": "VXNlcjo5OTY2MzI3Mjk5NDY3NTU3MTA=",
      "image_medium_url": "https://i.pinimg.com/75x75_RS/aa/bb/cc/aabbcc.jpg",
      "is_private_profile": false,
      "username": "angelicachel7",
      "first_name": "Angelica",
      "full_name": "Angelica Chel",
      "type": "user",
      "id": "996632729946755710"
    },
    "like_count": 3,
    "images": [],
    "type": "aggregatedcomment",
    "done_at": "Sun, 02 Jun 2024 22:03:45 +0000",
    "details": "Love this!",
    "liked_by_me": false,
    "id": "5367431284645738902"
  },
  {
    "pinUrl": "https://www.pinterest.com/pin/1618549864585211/",
    "node_id": "Q29tbWVudDo1MzY3NDMxMjg0NjQ1NzM4OTAz",
    "helpful_count": 2,
    "tags": [],
    "videos": [],
    "comment_count": 0,
    "marked_helpful_by_me": false,
    "image_signatures": ["de258d5c5e1577b30c8744148baa2fc9"],
    "user": {
      "node_id": "VXNlcjo4MTc0MDM1Mzg1MjYyMjYzOTQ=",
      "image_medium_url": "https://s.pinimg.com/images/user/default_75.png",
      "is_private_profile": false,
      "username": "alinaaskarova2855",
      "first_name": "Alina",
      "full_name": "Alina",
      "type": "user",
      "id": "817403538526226394"
    },
    "like_count": 0,
    "images": [
      {
        "originals": { "url": "https://i.pinimg.com/originals/de/25/8d/de258d5c5e1577b30c8744148baa2fc9.jpg", "width": 810, "height": 1080 },
        "550x": { "url": "https://i.pinimg.com/550x/de/25/8d/de258d5c5e1577b30c8744148baa2fc9.jpg", "width": 550, "height": 733 },
        "150x150": { "url": "https://i.pinimg.com/150x150/de/25/8d/de258d5c5e1577b30c8744148baa2fc9.jpg", "width": 150, "height": 150 }
      }
    ],
    "type": "comment",
    "done_at": "Fri, 30 Aug 2024 05:04:21 +0000",
    "details": "Tried this recipe, turned out great",
    "liked_by_me": false,
    "id": "5383429274252393844"
  },
  {
    "pinUrl": "https://www.pinterest.com/pin/1618549864585211/",
    "node_id": "VXNlckRpZEl0RGF0YTo1MzgzNDI5Mjc0MjUyMzkzODQ0",
    "helpful_count": 0,
    "tags": [],
    "videos": [],
    "comment_count": 0,
    "marked_helpful_by_me": false,
    "image_signatures": [],
    "user": {
      "node_id": "VXNlcjo2Mzk1MTEzNTMyNDUxMTY3Nzk=",
      "image_medium_url": "https://s.pinimg.com/images/user/default_75.png",
      "is_private_profile": false,
      "username": "",
      "first_name": "",
      "full_name": "",
      "type": "user",
      "id": null
    },
    "like_count": 0,
    "images": [],
    "type": "userdiditdata",
    "done_at": "Sat, 09 Aug 2025 13:12:50 +0000",
    "details": "",
    "liked_by_me": false,
    "id": "5445821451433193930"
  }
]
```

All 16 top-level keys, exactly as pushed by the row-builder:

| Field | Type | Description |
| --- | --- | --- |
| `pinUrl` | string | Full URL of the source pin, built from the domain that actually resolved the request |
| `id` | string | Comment / activity item ID |
| `node_id` | string | Pinterest GraphQL node ID |
| `type` | string | `"aggregatedcomment"`, `"comment"`, or `"userdiditdata"` |
| `details` | string | Comment text (empty string for activity rows with no text) |
| `done_at` | string | Timestamp the item was posted, as returned by the API |
| `like_count` | integer | Reaction count for "like", parsed from `reaction_counts` |
| `helpful_count` | integer | Reaction count for "helpful", parsed from `reaction_counts` |
| `comment_count` | integer | Reply count on this item as reported by the API (frequently `0`) |
| `tags` | array | Tags on the item as returned by the API (frequently empty) |
| `videos` | array | Attached video objects as returned by the API (frequently empty) |
| `image_signatures` | array | Raw pinimg signature strings for attached images |
| `images` | array | List of image objects; each has `originals`, `550x`, `150x150` keys → `{ url, width, height }`. URLs are always real; `width`/`height` are `null` when the API doesn't supply dimensions — never fabricated |
| `marked_helpful_by_me` | boolean | API flag; `false` when scraping logged-out |
| `liked_by_me` | boolean | API flag; `false` when scraping logged-out |
| `user` | object | Nested commenter profile: `id`, `node_id`, `username`, `first_name`, `full_name`, `image_medium_url`, `is_private_profile`, `type` |

### How can I use the data extracted with Pinterest Comment Scraper?

- 📊 **Social media managers:** pull every comment on your own brand's pins to catch questions and complaints that need a response, using `details` and `done_at` to build a response queue sorted by recency.
- 🤖 **AI engineers and LLM developers:** the Actor's HTTP-callable run is a clean tool for a grounded agent — the agent submits pin URLs, receives structured comment JSON, and passes `details` plus `user.username` to the model as citation-backed context instead of letting it hallucinate sentiment.
- 🔍 **Market researchers:** run the same competitor pin list on a schedule and track `like_count` / `helpful_count` deltas over time to gauge which campaigns or products are generating real engagement, not just impressions.
- 🎨 **Content and product teams:** mine `userdiditdata` rows (Pinterest's "Tried It" activity) for unsolicited product feedback — these are people who made the thing and came back to say so, a signal most social listening tools never capture because they only read comment text.

Each of these workflows reads from the same 16-key row shape, so there's no separate "lite" output to upgrade from — an AI pipeline pulling `details` and `user.username` for grounding gets the identical dataset a market researcher would export to CSV for a quarterly report.

### 📈 How do you monitor comment engagement over time?

Comment monitoring on Pinterest means running the same `urls` list repeatedly and diffing what changed. Because every row carries a stable `id`, you can track engagement on a fixed set of pins across weeks or months without re-discovering which comments are new.

The fields worth diffing between runs: `id` (new IDs in this run's output that weren't in the last run's = new comments since your last check), `like_count` and `helpful_count` per existing `id` (rising numbers indicate re-engagement on old comments), and `comment_count` per pin overall (a jump signals a conversation is picking up). For "Tried It" tracking specifically, watch for new `userdiditdata` rows — each one is a person who made the pinned item and is worth reaching out to.

A practical workflow: schedule a run across your bulk `urls` list using an [Apify Schedule](https://docs.apify.com/platform/schedules) (daily or weekly, depending on how active the pins are), export each run's dataset, and compare the new run's `id` set against the previous run's. Alert your team when a pin crosses a threshold — say, 5+ new comment `id`s since the last check, or a `helpful_count` spike on a specific comment. The Actor itself doesn't include a built-in diff or alerting feature; the comparison logic lives in whatever you schedule the runs from (a script, a workflow tool, or an Apify integration that reads the dataset after each run).

### 🔌 Integrate Pinterest Comment Scraper and automate your workflow

Pinterest Comment Scraper works with any language or tool that can send an HTTP request — it's an Apify Actor, reachable through the Apify API and the `apify-client` SDKs.

#### REST API with Python

```python
import requests

TOKEN = "<YOUR_API_TOKEN>"
ACTOR = "<YOUR_USERNAME>/pinterest-comment-scraper"

run_input = {
    "urls": ["https://www.pinterest.com/pin/1618549864585211/"],
    "domain": "www.pinterest.com",
    "limit": 100,
}

resp = requests.post(
    f"https://api.apify.com/v2/acts/%7BACTOR%7D/run-sync-get-dataset-items",
    params={"token": TOKEN},
    json=run_input,
)
comments = resp.json()
for c in comments[:5]:
    print(c["user"]["username"], "-", c["details"])
```

#### Scheduled monitoring and delivery

Set up a recurring run from the **Schedules** tab in the Apify Console (cron-based, e.g. daily at a fixed hour) to re-scrape the same `urls` list automatically. Pair it with an [Apify webhook](https://docs.apify.com/platform/integrations/webhooks) firing on `ACTOR.RUN.SUCCEEDED` to push a notification or trigger a downstream job (compare-and-alert, CRM sync, etc.) the moment new comment data lands — no polling required.

### Is it legal to scrape Pinterest comments?

Scraping publicly visible Pinterest pin comments is generally legal — this Actor reads only what any signed-out visitor to the pin page can already see, the same data Pinterest's own web app fetches to render the comment thread. The U.S. Ninth Circuit's ruling in *hiQ Labs v. LinkedIn* (9th Cir. 2019) supports the position that scraping publicly accessible web data does not violate the Computer Fraud and Abuse Act. That said, comment data includes personal data about individual commenters — usernames, full names, and avatar images — so GDPR and CCPA considerations apply if you store or process it in bulk, particularly for EU or California residents; consult your legal team before building a data-retention pipeline around it. Pinterest's own Terms of Service govern automated access separately from data-protection law, and scraping for AI model training carries a different risk profile than scraping for short-term operational monitoring. Consult your legal team for commercial use cases involving bulk data storage.

### ❓ Frequently asked questions

#### Which Pinterest regions does Pinterest Comment Scraper support?

22 regional domains via the `domain` parameter, from `www.pinterest.com` (US/Global) to country-specific subdomains like `jp.pinterest.com`, `de.pinterest.com`, `br.pinterest.com`, and 18 others. Pick the domain that matches where your target pins live; comment data itself isn't region-locked, but resolving the pin correctly sometimes depends on hitting the right subdomain.

#### Can I control how many comments come back per pin?

Yes, with the `limit` parameter — default `10`, minimum `1`, no schema-enforced maximum. Internally, each page request to Pinterest is capped at 100 comments (Pinterest rejects larger pages for logged-out requests), and the Actor pages automatically until it hits your `limit` or Pinterest's `bookmark` pagination runs out, whichever comes first.

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

It impersonates Chrome 131's TLS/JA3 fingerprint via `curl_cffi` rather than sending a plain HTTP client's fingerprint, seeds a real `csrftoken` cookie by requesting the pin page first, and inserts a randomized 1–2 second delay between requests. On failure it retries up to 3 times with exponential backoff, then escalates through Apify Proxy — datacenter first, residential second (with 3 retries) — before giving up on that pin. An empty `resource_response` from Pinterest is treated as a likely soft block and triggers the same escalation path.

#### Does Pinterest Comment Scraper extract bulk, multi-region data in one run?

Yes — `urls` accepts an array, so a single run can process pins from different campaigns or accounts together, and `domain` lets you target any of 22 Pinterest subdomains per run. Every output row carries the exact `pinUrl` it came from, so a mixed batch stays traceable per pin.

#### How many results does Pinterest Comment Scraper return per query?

Per pin, up to your `limit` value (default `10`, no maximum enforced). Across a batch, total output is the sum across every pin in `urls` — there's no run-wide cap beyond what you set per pin.

#### Does it also capture "Tried It" (Did It) activity, not just written comments?

Yes. Pinterest's comment feed API returns three row types — `comment`, `aggregatedcomment`, and `userdiditdata` — and this Actor keeps all three, normalized into the same output shape. `userdiditdata` rows represent someone marking that they made or tried the pin; their `details` field is often empty since that action doesn't require text.

#### How do I use Pinterest Comment Scraper to monitor comment engagement over time?

Run the same `urls` list on a schedule (Apify Schedules), then diff each run's output against the previous one: new `id` values are new comments, and rising `like_count` / `helpful_count` on existing `id`s show re-engagement. See the monitoring section above for the full workflow.

#### Does Pinterest Comment Scraper work with Claude, ChatGPT, and AI agent frameworks?

It isn't reachable through an MCP server, but it's callable as a standard HTTP endpoint through the Apify API from any agent framework that can make a REST call — an agent submits pin URLs, gets back structured comment JSON, and can ground a response in real commenter text instead of guessing at sentiment.

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

Its listing peers document single-pin input only: easyapi's Pinterest Comments Scraper takes one `pinUrl` string per run and scrapestorm's Pinterest Comments Scraper takes one `post_url` string per run (both checked on the Apify Store 2026-07-25). This Actor accepts a `urls` array for bulk, multi-pin, multi-region runs. A broader multi-purpose actor, memo23's Pinterest Scraper, bundles comments as an optional add-on to a pin/board/search/profile crawler rather than as a dedicated comment tool (checked 2026-07-25). Output field names largely overlap across these tools since they all read the same underlying Pinterest API — the differences are in input shape and how many pins one run can process.

#### Can I use Pinterest Comment Scraper without managing proxies or Pinterest login credentials?

Yes to both. No Pinterest account or login is required — public pins are readable logged-out, and the Actor resolves its own session token. Proxy is optional: it starts with direct requests and auto-escalates to Apify Proxy (datacenter, then residential) on its own if Pinterest blocks it, so you don't have to source or configure proxies yourself, though you can supply your own `proxyConfiguration` if you want a specific proxy group or country from the start.

#### Which export formats does Pinterest Comment Scraper support?

Whatever the Apify platform supports for any dataset: JSON, JSONL, CSV, Excel (XLSX), HTML table, RSS, and XML, all selectable from the Storage tab or via the `dataset` API endpoint's `format` parameter. Nested fields like `user` and `images` flatten to dot-notation columns automatically in CSV and Excel exports (e.g. `user.username`, `user.full_name`) — no separate "flatten" toggle to set.

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

Private and login-gated pins aren't accessible logged-out, so they can't be scraped — the Actor logs the pin ID to a "skipped" list at the end of the run rather than failing the whole batch. A pin with zero comments isn't necessarily an empty result: Pinterest's feed can still return `userdiditdata` activity rows even when nobody has left a text comment, so an empty dataset for a given pin usually means genuinely no engagement of either kind, not a scraping failure.

### 💬 Your feedback

Found a bug, hit a pin type this Actor doesn't parse correctly, or need a field it doesn't currently return? Let Scrapier know through the Actor's Issues tab on Apify or via the support link on its Store listing — bug reports and missing-field requests get read and help prioritize the next update.

# Actor input Schema

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

📎 Paste Pinterest pin links or numeric IDs. Supports bulk input — add multiple pins to scrape in one run. Example: https://www.pinterest.com/pin/123456/

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

🗺️ Pick the Pinterest region. Match the domain where your pins live — e.g. jp.pinterest.com for Japan, uk.pinterest.com for UK.

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

📊 Cap comments per pin. Default: 10. Set higher (e.g. 100+) for full comment extraction.

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

🛡️ Optional. Start with no proxy for speed. Auto-fallback: datacenter → residential (3 retries) if blocked.

## Actor input object example

```json
{
  "urls": [
    "https://www.pinterest.com/pin/1618549864585211/"
  ],
  "domain": "www.pinterest.com",
  "limit": 10,
  "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/1618549864585211/"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapier/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/1618549864585211/"],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapier/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/1618549864585211/"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call scrapier/pinterest-comment-scraper --silent --output-dataset

```

## MCP server setup

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