Pinterest Scraper — Pins, Boards & Profiles
Pricing
from $0.85 / 1,000 result delivereds
Pinterest Scraper — Pins, Boards & Profiles
Search Pinterest or collect pins from public boards, profiles and pin URLs. Returns the flat Automation Lab-compatible pin shape with images, saves, hashtags, creator and board details. $1 per 1,000 delivered results. No login or API key.
Pricing
from $0.85 / 1,000 result delivereds
Rating
0.0
(0)
Developer
Meka.im
Maintained by CommunityActor stats
0
Bookmarked
10
Total users
6
Monthly active users
12 hours ago
Last modified
Categories
Share
Pinterest Scraper
Collect pins by Pinterest search query, public board, public profile, or individual pin URL. The
v0.2 output is the flat Automation Lab-compatible pin shape: image URLs, the observed saves
compatibility value, hashtags, creator and board details, and source provenance.
The Actor reads Pinterest's public web resources through HTTP. It does not need a Pinterest login, cookies, an API key, or a browser.
Version and compatibility
- v0.1 remains the legacy source version. The complete old entrypoint is preserved as
src/main-v1.mjs, and its nested v1 row shape remains insrc/contract.mjsandsrc/product.mjs. Existing users of the legacy input and nested Dataset must pin the retained v0.1 build0.1.11. - v0.2 is the current live default and a breaking input/output contract. Build
0.2.1fromsrc/main.mjsruns the flat Automation Lab contract insrc/automation-runner.mjs. - Publishing v0.2 does not delete older Actor source versions. However, preserving v0.1 source does
not keep unpinned
latestconsumers on the old contract:latestnow points to v0.2.1. Calls that need the nested v1 Dataset must pin build0.1.11.
Compatibility covers input names and the flat row fields. It does not promise that a separate live run returns the same pins, numeric values, or timestamp text as another Actor. Pinterest rotates search results and may expose different counters by request path and time.
Quick start
Search for pins:
{"searchQueries": ["minimalist kitchen design"],"maxPins": 25}
Collect a profile, a board, and specific pins together:
{"boardUrls": ["https://www.pinterest.com/username/board-name/"],"profileUrls": ["https://www.pinterest.com/username/"],"pinUrls": ["https://www.pinterest.com/pin/123456789/"],"maxPins": 50}
Start with a small maxPins value, inspect the dataset, and increase it after checking relevance and
cost.
Input
The v0.2 input has six fields:
| Field | Type | Default | Meaning |
|---|---|---|---|
searchQueries | string[] | [] | Pinterest search terms. Each query can return up to maxPins pins. |
boardUrls | string[] | [] | Public Pinterest board URLs, including the owner username in the path. |
profileUrls | string[] | [] | Public Pinterest profile URLs. Profile pins also receive profile metadata. |
pinUrls | string[] | [] | Individual public Pinterest pin URLs. |
maxPins | integer | 50 | Maximum pins from each query, board, or profile. Range: 1 to 1,000; the editor prefill is 5. |
proxy | object | US residential Apify proxy | Proxy settings; see below. |
At least one source is required. Sources retain input order: searches, then boards, profiles, and pin URLs. Duplicate canonical sources are processed once. Empty strings and malformed Pinterest URLs fail validation before any proxy or Pinterest request is made.
Proxy behavior
The default is the same effective route as the Automation Lab input:
{"useApifyProxy": true,"groups": ["RESIDENTIAL"],"countryCode": "US"}
groups becomes the Apify proxy group list and countryCode is passed to the Apify proxy. The Actor
asks the proxy configuration for a new URL for every HTTP attempt. If a proxy configuration is
present but cannot produce a URL, the run fails instead of silently connecting directly.
Use "proxy": { "useApifyProxy": false } to connect directly when no custom proxy URLs are supplied.
Custom proxyUrls can be supplied instead. They are used through undici.ProxyAgent, and each
request receives a fresh URL from the configuration.
A hosted 256 MB smoke run whose submitted input omitted the proxy field completed 1/1 row;
its stored INPUT contains the default US residential RESIDENTIAL settings, and its
residential transfer byte counter was positive. See the
../../validation/pinterest-online-release-2026-10-20/README.md.
The transport accepts only these Pinterest resource names:
BaseSearchResourcePinResourceUserResourceUserPinsResourceUserActivityPinsResourceBoardResourceBoardFeedResource
Each resource has a fixed Pinterest handler. Request origins, paths, headers, and redirects are managed by the Actor. Product code cannot turn an input URL into an arbitrary request destination.
Profile collection uses UserPinsResource with field_set_key: detailed, so public saved pins are
included even when a profile has no pins it created, and same-response SEO text can fill a missing
title without an additional PinResource request. If that resource fails, the source fails without
a silent fallback to the creation-only activity feed. Board collection continues to request
field_set_key: grid_item, because the observed detailed board feed does not provide usable pin
IDs. createdAt is filled only from the returned pin's raw.created_at.
Output
Every Dataset row is a Pinterest pin. The base fields are:
id, title, description, url, imageUrl, thumbnailUrl, altText, domain, link,
saves, pinnerUsername, pinnerName, pinnerFollowers, boardName, boardUrl,
dominantColor, createdAt, isVideo, hashtags, sourceTypes.
Additional provenance fields appear when their source matched:
sourceUrlsfor board, profile, and pin URL sources.sourceQueriesfor search sources.profileUrl,profileUsername,profileName,profileFollowers, andprofilePinCountfor a profile source.
Example:
{"id": "1020839440598637528","title": "Small Japandi Kitchen Ideas","description": "Warm wood, calm colors, and a compact layout.","url": "https://www.pinterest.com/pin/1020839440598637528/","imageUrl": "https://i.pinimg.com/originals/5d/67/cc/example.png","thumbnailUrl": "https://i.pinimg.com/236x/5d/67/cc/example.jpg","altText": "A small kitchen with wooden cabinets","domain": "Uploaded by user","link": null,"saves": 2,"pinnerUsername": "example","pinnerName": "Example","pinnerFollowers": 336,"boardName": "Kitchen Ideas","boardUrl": "https://www.pinterest.com/example/kitchen-ideas/","dominantColor": "#ae957e","createdAt": "Wed, 04 Mar 2026 22:41:54 +0000","isVideo": false,"hashtags": ["#kitchenideas"],"sourceTypes": ["search"],"sourceQueries": ["small kitchen"]}
The row has no nested pin, creator, media, or schema object, and no entity_type field.
isVideo reports whether Pinterest marks the pin as video. No video file URL is claimed in this
contract.
saves is an observed Automation Lab compatibility field sourced from reaction_counts['1']. A
missing value becomes the integer 0 placeholder. It is not a verified total saves or repins count,
and the product does not use repin_count or aggregatedStats.saves for this field.
Title and description fallbacks
For each pin, title uses the first non-empty trimmed string from raw.title, raw.grid_title,
raw.rich_metadata.title, then raw.seo_title. description uses the first non-empty trimmed
string from raw.description, raw.rich_metadata.description, then raw.seo_description.
raw.rich_metadata is accepted only from the same raw Pin object and only when it is a non-array
object. Hashtags are extracted from the resolved description.
seo_title and seo_description are Pinterest website-generated SEO text. Their use does not
claim that they are the author's original title or description. Image alt text, HTML metadata tied
to another pin, and synthesized text are not used. Search, board, and profile feeds can omit
PinResource-level text, and the Actor does not add per-pin network requests for opaque e1_... feed
IDs. When every supported same-pin value is absent or invalid, title and description remain empty;
non-empty text is not guaranteed for every row.
After source collection, de-duplication, and maxResults selection, the product can issue one
PinResource lookup for a selected feed row when its numeric ID is missing a title or description
and an explicit pinUrls source has not already fetched that same Pin. The response ID must match
the request. The lookup fills only empty text fields, preserves existing text and all other row
fields, and recalculates hashtags only when the description is filled. Fully populated rows,
unselected rows, opaque e1_... IDs, and explicit Pin sources are skipped. A later duplicate raw
record may fill missing text before this stage, avoiding a lookup.
Lookups run with at most three concurrent requests. Starting 30 seconds after this stage begins, no further lookups are started; requests already in flight still follow the transport's existing retry and 30-second timeout behavior, so total run duration can exceed 30 seconds. Optional lookup failures, mismatched IDs, malformed details, and candidates skipped at the launch deadline do not change Dataset rows, source failure status, or delivery billing.
The fallback is a backward-compatible 0.2.x bugfix. It does not change the six-field input, the
flat row fields, or the version in .actor/actor.json.
Board output URLs accept underscore-prefixed slugs, percent-encoded +, and Unicode slugs while
still requiring a Pinterest host, no credentials or custom port, exactly two decoded path segments,
and a safe username. Decoded slash, backslash, control characters, and ./.. traversal are
rejected, as are malformed encodings and foreign hosts. The slug is safely encoded when rebuilding
the output URL. This affects output normalization only and does not widen input URL validation.
Missing text is returned as an empty string when Pinterest does not expose it, unless the field is
documented as nullable. Numeric counters preserve Pinterest's reported value, including zero.
createdAt preserves the timestamp text returned by Pinterest.
Pagination, deduplication, and recovery
The product follows Pinterest bookmarks until each source reaches its per-source maxPins limit,
the source ends, or the overall delivery budget is reached. It completes source collection before
writing rows so a pin found by several inputs is delivered once with merged sourceTypes and source
provenance.
Dataset rows are the identity ledger. On a resumed run, the Actor reads every Dataset page and skips
IDs already present. The STATE record also stores contract version and a hash of the input so a
dataset cannot be silently reused with different input.
Rows are written before the delivery event is charged. A resumed run does not bill an existing row again. If the remaining charge budget is zero, no proxy or Pinterest request is made.
If finite budget collection skips pins because maxResults was reached, the run is marked
budget-exhausted so a later run with more budget can continue. A complete result that merely
equals the available budget, without a skipped pin, remains completed.
Run summary
OUTPUT records:
contractVersion: 2status:completed,partial,budget-exhausted, orfailedrequested,delivered,deliveredThisAttempt, andfailedtextEnrichmentwhen the product reports it, containing only the non-negative safe integer countersattempted,filledTitles,filledDescriptions,failed,skippedOpaque, andskippedBudget- budget and recovery flags where relevant
A source failure with other successful sources produces partial. If every source fails, the run
fails. A successful-looking empty result is also treated as a failure.
Pricing
Pricing remains $0.001 per delivered row, or $1.00 per 1,000 rows. Duplicate rows, failed
lookups, and resumed rows already in the Dataset do not emit another result-delivered event.
API example
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'MY_APIFY_TOKEN' });const run = await client.actor('meka.im/pinterest-scraper').call({searchQueries: ['minimalist kitchen design'],maxPins: 50,proxy: {useApifyProxy: true,groups: ['RESIDENTIAL'],countryCode: 'US',},});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Validation status
On 2026-10-20, hosted runs of this Actor on build 0.2.1 and competitor build 0.1.39
received the same fixed ten Pin URLs, maxPins: 10, and proxy: false. Both returned the same
10 IDs in the same order. The input/output contract passed: 210/210 field checks were valid,
field order matched 10/10 rows, and there were no unknown or missing fields. Observed types
matched in 207/210 cells; the three differences were legal link string/null values.
Full value identity did not pass. Only 77/210 values were strictly equal and 133 differed, so the
evidence records compatibilityPass: true, valuesEqual: false, and overall pass: false.
After trimming, this Actor had non-empty titles on 8/10 rows and descriptions on 7/10; the
reference had 9/10 and 9/10. This Actor had pinner, board, and createdAt data on 10/10 rows,
the reference on 1/10, and this Actor marked 2/10 pins as video versus 0/10. More non-empty
values do not by themselves prove better semantic accuracy.
The earlier source audit did not fetch the pages during this online comparison. Its per-row
evidence remains the old anonymous public HTML embedded Relay JSON captured at
2026-10-20 08:50 UTC, and is partial. This release evidence covers only the fixed ten-Pin
sample; earlier search, board, and profile smoke checks are not a complete production acceptance.
The usageTotalUsd values are platform infrastructure records. The owner's Actor usage is not a
customer price and is not directly comparable with the reference run's $0.04. The recorded
5,222 ms and 10,223 ms spans are one-shot observations, not an SLA.
The transport tests cover asynchronous proxy URLs, proxy configuration failures, retries, response validation, body cleanup, and response-schema checks. Runner tests cover billing order, partial source failure, dataset pagination, completed-state recovery, budget exhaustion, and resume deduplication. See docs/pinterest-automation-compat.md, the ../../validation/pinterest-online-release-2026-10-20/README.md, and the ../../validation/pinterest-automation-compat-2026-10-20/README.md.
Legal
This Actor is an independent tool. It is not affiliated with, endorsed by, sponsored by, or certified by Pinterest, Inc. "Pinterest" and related marks belong to their respective owners and are used only to identify the public source this Actor reads. You are responsible for using the data in compliance with applicable law and the source website's terms.