# Pinterest Pin Details Scraper — Saves & Repins (`apt_marble/pinterest-pin-details-scraper`) Actor

Turn Pinterest pin links into complete records: saves, repins, comments, shares and reactions, the destination link and domain, all image sizes, playable video, the original creator behind each pin, plus parsed recipe details and product prices where a pin carries them. No account needed.

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

## Pricing

$4.00 / 1,000 pin detail scrapeds

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/platform/actors/running/actors-in-store#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 Pin Details Scraper — Saves & Repins

Paste a list of Pinterest pin addresses — or bare pin ids — and get the complete public record for every one of them as a clean, flat row: how often the pin was saved, repinned, shared, reacted to and commented on, where it sends people, every image size Pinterest publishes, the playable video file when there is one, the original creator as well as the account whose copy you pointed at, and the structured extras Pinterest has already worked out for you, such as a fully parsed recipe or the individual products inside a shoppable pin. No Pinterest account, no login, nothing to set up.

### What you can do with it

- **Score pins you already have.** Feed in a list of pin links from a report, a spreadsheet or another actor and get real save, repin, share and comment figures next to each one.
- **Find the creator behind a viral pin.** Every row separates the person who originally published the pin from the account that saved the copy you looked at, with follower counts for both and the creator's verified website.
- **Build a recipe dataset.** Recipe pins come back with the dish name, prep/cook/total time, servings, diets, star rating, and an ingredient list already split into quantity, unit, name and supermarket aisle.
- **Pull real prices out of shoppable pins.** Collection and shop-the-look pins carry their individual products, each with price, currency, stock status and merchant.
- **Collect video files.** Video pins return a direct, playable video file plus its dimensions, duration and thumbnail — useful for archiving or creative analysis.
- **Track outbound traffic.** Destination link, tracked link, campaign-tagged link and the destination domain are all returned, so you can group pins by the site they drive traffic to.

### What you get

One row per pin. Abridged real example:

```json
{
  "type": "pin",
  "id": "38069559344973740",
  "url": "https://www.pinterest.com/pin/38069559344973740/",
  "inputUrl": "https://www.pinterest.com/pin/38069559344973740/",
  "title": "Rich and Moist Chocolate Cake (from scratch recipe)",
  "description": "Rich and Moist Chocolate Cake (from scratch recipe) - Baked Ambrosia",
  "altText": null,
  "dominantColor": "#837268",
  "createdAt": "2026-07-16T16:15:09.000Z",
  "domain": "bakedambrosia.com",
  "imageUrl": "https://i.pinimg.com/originals/fd/49/15/fd49150a45f56427ddc5da1da08861f4.jpg",
  "imageWidth": 1200,
  "imageHeight": 1680,
  "isVideo": false,
  "videoUrl": null,
  "saveCount": 9030,
  "repinCount": 36,
  "commentCount": 3,
  "shareCount": 4,
  "reactionCount": 357,
  "triedCount": 1,
  "boardName": "light dessert",
  "boardUrl": "https://www.pinterest.com/kyresserhea10/light-dessert/",
  "pinnerUsername": "kyresserhea10",
  "pinnerFullName": "mark atkinson",
  "pinnerFollowerCount": 76,
  "creatorUsername": "bakedambrosia",
  "creatorFullName": "Baked Ambrosia",
  "creatorFollowerCount": 15968,
  "creatorDomain": "bakedambrosia.com",
  "creatorDomainVerified": true,
  "pinnedByCreator": false,
  "isRepin": true,
  "isPromoted": false,
  "promotedBy": null,
  "hasRecipe": true,
  "hasProducts": false,
  "productCount": 0,
  "publisher": "Baked Ambrosia",
  "position": 1,
  "scrapedAt": "2026-08-04T10:00:00.000Z"
}
```

The row is abridged above: it also carries the full destination address in `link`, the tracked and campaign-tagged forms of it, every published image size in `images`, the reaction breakdown, and the board and creator identifiers listed in the output table below.

That same pin carries a fully parsed `recipe` object:

```json
{
  "hasRecipe": true,
  "recipe": {
    "name": "Moist Chocolate Cake",
    "servings": "12",
    "servingsSummary": "Serves 12",
    "prepTimeMinutes": 15,
    "cookTimeMinutes": 30,
    "totalTimeMinutes": 45,
    "diets": ["Vegetarian"],
    "ratingValue": 5,
    "ratingCount": 80,
    "reviewCount": 10,
    "ingredientCount": 17,
    "ingredientCategories": ["Refrigerated", "Condiments", "Baking & Spices", "Dairy"],
    "ingredients": [
      { "name": "Eggs", "amount": "3", "quantity": 3, "unit": null, "category": "Refrigerated" },
      { "name": "Honey", "amount": "1/4 cup", "quantity": 0.25, "unit": "cup", "category": "Condiments" }
    ]
  }
}
```

A shoppable pin adds its products:

```json
{
  "hasProducts": true,
  "productCount": 1,
  "pricedProductCount": 1,
  "products": [
    {
      "position": 1,
      "pinId": "872220652852770625",
      "productName": "Ripple Rotating Wall Lamp | Yedwo Design",
      "price": 199,
      "priceCurrency": "USD",
      "priceDisplay": "US$199.00",
      "inStock": true,
      "merchant": "YEDWO",
      "isActive": true
    }
  ]
}
```

### Input reference

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `pins` | list of text | two example pins | One pin per line. Full pin addresses and bare numeric pin ids both work, with or without the title inside the address. **Required.** |
| `maxPins` | number | `100` | Safety cap on how many pins this run scrapes. Maximum 5,000. Anything past the cap is left untouched and reported in the run log. |
| `skipPromoted` | true/false | `false` | Promoted pins are always flagged in the output. Turn this on to leave them out of the dataset entirely. |
| `country` | select | `us` | The country the run browses from. Pinterest tailors what it publishes by market, so pick one and keep it the same between runs you want to compare. |

### Output fields

| Field | Type | What it is |
| --- | --- | --- |
| `id`, `url` | text | The pin id and its address on Pinterest |
| `inputUrl` | text | Exactly what you pasted, so rows join back to your list |
| `title`, `description` | text | The pin's own caption, where it published one |
| `altText` | text | Image description, filled in automatically when a pin has no caption |
| `category` | text | Pinterest's own topic label for the pin |
| `createdAt`, `createdAtRaw` | date / text | When the pin was published |
| `link`, `trackedLink`, `utmLink` | text | Where the pin sends people, in three published forms |
| `domain` | text | The destination site, for grouping pins by where they point |
| `imageUrl`, `imageWidth`, `imageHeight` | text / number | The largest published image and its size |
| `images` | object | Every published image size, keyed by size name |
| `isVideo`, `videoUrl`, `videoMp4Url`, `videoHlsUrl` | true/false, text | Whether the pin is a video and the playable file for it |
| `videoWidth`, `videoHeight`, `videoDurationMs`, `videoThumbnailUrl` | number / text | Video dimensions, length and poster frame |
| `saveCount` | number | How many times the pin has been saved |
| `repinCount` | number | How many times it has been repinned |
| `commentCount` | number | How many comments it has |
| `shareCount` | number | How many times it has been shared |
| `reactionCount`, `reactions` | number / object | Total reactions and the breakdown by reaction type |
| `triedCount` | number | How many people marked the pin as tried |
| `boardId`, `boardName`, `boardUrl`, `boardOwnerUsername` | text | The board this copy of the pin lives on |
| `pinnerUsername`, `pinnerFullName`, `pinnerFollowerCount`, `pinnerImageUrl` | text / number | The account whose copy you scraped |
| `creatorUsername`, `creatorFullName`, `creatorFollowerCount` | text / number | The original creator or merchant behind the pin |
| `creatorDomain`, `creatorDomainVerified`, `creatorIsVerifiedMerchant` | text / true-false | The creator's claimed website and whether Pinterest verified it |
| `pinnedByCreator` | true/false | Whether the creator and the pinner are the same account |
| `isRepin`, `isPromoted` | true/false | Whether this copy is a repin, and whether it is a promoted pin |
| `promotedBy` | text | The advertiser behind a promoted pin, when there is one — usually a different account from whoever saved it |
| `hasRecipe`, `recipe` | true/false / object | Parsed recipe: name, times, servings, diets, rating, ingredients |
| `hasProducts`, `productCount`, `pricedProductCount`, `products` | true/false, number, list | Individual products inside a shoppable pin, with prices |
| `collectionRootPinId` | text | The parent pin of a shoppable collection |
| `isShoppingPin`, `richPinType`, `publisher` | true/false / text | Shopping tagging, the rich-pin kind, and the publishing site |
| `hashtags` | list of text | Hashtags in the pin's caption |
| `dominantColor` | text | The dominant colour of the image |
| `source`, `position`, `scrapedAt` | text / number / date | Where the row came from, its place in your list, and when it was collected |

### Pricing

This actor uses pay per event. You are charged **$4.00 per 1,000 pins scraped** — that is **$0.004 for each pin** that lands in the dataset. Nothing else is billed.

You are not charged for pins that turn out to be unavailable, for short links that could not be read, or for entries that were not recognised as a pin. Those are reported in the run log instead.

**Worked example.** You paste 250 pin addresses. 243 of them are live and land in the dataset, 5 have been deleted and 2 were typed wrongly. You pay 243 × $0.004 = **$0.97**.

Set `maxPins` to put a hard ceiling on any single run, and set a run budget in the Apify console if you want a spending cap on top of that.

### Limits & what this actor cannot do

- **Counts move.** Saves, repins, comments and shares are a snapshot of the moment the pin was collected and keep changing afterwards. Re-run to refresh them.
- **Shortened `pin.it` links cannot be read.** A short link hides which pin it points to, and this actor will not guess. Open one in a browser once and paste the full pin address it lands on — those are skipped and listed in the run log rather than silently scraped as the wrong pin.
- **Pins that are deleted, private or not public in the chosen country come back as unavailable**, counted separately from genuine failures, instead of producing a blank row.
- **Comment text is not published for logged-out visitors.** You get the number of comments, never the comments themselves.
- **Many pins have no caption of their own.** Those arrive with an automatically generated image description in `altText` instead, so plan your text analysis around both fields.
- **Prices only exist on shoppable pins.** Ordinary pins — including plenty of genuine merchant pins — publish no price at all, so this actor deliberately offers no pin-level price column. Prices appear inside `products` for collection and shop-the-look pins, and `pricedProductCount` tells you how many of them actually carried one.
- **Recipe details appear only where Pinterest has parsed a recipe.** A pin can be labelled a recipe pin and still publish no ingredient list; `hasRecipe` is the honest signal.
- **Board follower counts are not published on a pin.** Scrape a board directly if you need them.
- **Results are tailored to the country the run browses from**, so the same pin can differ slightly between markets. Keep `country` fixed across runs you plan to compare.
- **Promoted pins are flagged**, and can be excluded entirely with one switch.
- **Speed depends on the size of the job and on Pinterest's own response times.** No fixed throughput is promised.
- **Pinterest's terms govern automated access.** You are responsible for using the data lawfully, in line with the source site's terms, and for handling any personal data in line with applicable privacy law.

### FAQ

**Do I need a Pinterest account?**
No. The actor only reads what Pinterest shows to the public, so there is nothing to connect and nothing to authorise.

**Does it need my login or password?**
No. It never asks for one, and there is nowhere to enter one.

**Can I schedule it?**
Yes. Schedule it in the Apify console like any other actor — a weekly run over the same list of pins gives you a clean engagement trend.

**Is the data complete?**
It is complete for what Pinterest publishes publicly, which is a lot: engagement, media, destination, creator, recipes and product prices. It is not complete where Pinterest publishes nothing publicly — the text of comments, the list of people who saved a pin, and prices on ordinary non-shoppable pins are all outside what any logged-out visitor can see, so this actor does not pretend to return them.

**Why is `title` empty on some pins?**
Because a lot of pins are published without a caption. When that happens, use `altText`, which carries an automatically generated description of the image and is present on almost every pin.

**Can I paste a `pin.it` short link?**
Not directly. A short link does not say which pin it points to, and guessing would risk scraping a different pin. Open it once in a browser and paste the full pin address instead.

**What happens if one pin in my list is broken?**
Nothing else stops. Each pin is handled on its own, and the run log tells you exactly how many were scraped, how many were unavailable, how many failed and how many entries were not recognised.

# Actor input Schema

## `pins` (type: `array`):

One Pinterest pin per line. Full pin addresses and bare numeric pin ids both work, with or without the title in the address. Shortened pin.it links cannot be read — open one in a browser and paste the full address it lands on.

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

Safety cap on how many pins this run will scrape. Anything beyond it is left untouched.

## `skipPromoted` (type: `boolean`):

Promoted pins are always flagged in the results. Turn this on to leave them out of the dataset entirely.

## `country` (type: `string`):

The country the run browses from. Pinterest personalises what it publishes by country, so pick the market you care about and keep it the same between runs you want to compare.

## Actor input object example

```json
{
  "pins": [
    "https://www.pinterest.com/pin/211174978421744/",
    "https://www.pinterest.com/pin/38069559344973740/"
  ],
  "maxPins": 100,
  "skipPromoted": false,
  "country": "us"
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "pins": [
        "https://www.pinterest.com/pin/211174978421744/",
        "https://www.pinterest.com/pin/38069559344973740/"
    ],
    "maxPins": 100,
    "country": "us"
};

// Run the Actor and wait for it to finish
const run = await client.actor("apt_marble/pinterest-pin-details-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 = {
    "pins": [
        "https://www.pinterest.com/pin/211174978421744/",
        "https://www.pinterest.com/pin/38069559344973740/",
    ],
    "maxPins": 100,
    "country": "us",
}

# Run the Actor and wait for it to finish
run = client.actor("apt_marble/pinterest-pin-details-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 '{
  "pins": [
    "https://www.pinterest.com/pin/211174978421744/",
    "https://www.pinterest.com/pin/38069559344973740/"
  ],
  "maxPins": 100,
  "country": "us"
}' |
apify call apt_marble/pinterest-pin-details-scraper --silent --output-dataset

```

## MCP server setup

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