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
13
Total users
6
Monthly active users
7 days ago
Last modified
Categories
Security
Limited permissionsShare
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.5from source55680eb4runs 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.5. 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": 5}
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.
The post-promotion default-latest smoke, run QPzEH87UjCVdhjDJM, used build 0.2.5
with 256 MB and omitted proxy from the submitted input. It completed 1/1 row; the
stored INPUT contains the default US residential RESIDENTIAL settings, and its
residential transfer counter was positive. See the
../../validation/pinterest-text-modes-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, even when the successful
sources return no rows. If every source fails and no usable rows were collected, the run fails. If
rows from earlier pages or sources remain, the run stays partial and delivers them. An explicit
completed summary with zero failures may return zero delivered rows and complete without a charge
when its requested count matches the normalized target count; this count is the product's target
count, not its returned row count. Missing or inconsistent summaries remain failed. A partial source
failure remains partial, including when no rows were returned.
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
Current 0.2.5 four-mode acceptance
On 2026-10-20, eight successful hosted runs compared this Actor's build 0.2.5
(JYgg9RL1uCt7l8unI) with Automation Lab build 0.1.39
(qK0Bfz3UwIYSnhhGA). Each mode had one run per Actor:
- fixed: 10 Pins
- search: 3 queries with 5 rows each
- board: 3 boards with 5 rows each
- profile: 3 profiles with 5 rows each
Both sides returned 55 records in total, all 55 exact string IDs joined, and all
eight runs succeeded. The paired cases used the same stored inputs, 512 MB, and
explicit proxy: false.
All four modes passed the flat-row contract: 1,230/1,230 contract cells were valid, with zero invalid cells, unknown fields, or missing fields. Board order differed; the other three orders matched. Full value equality did not pass in any mode. A compatible contract therefore does not imply equal values or equal feed ordering.
| Mode | Total rows | Title ours/reference | Description ours/reference |
|---|---|---|---|
| Fixed | 10 | 10/9 | 10/9 |
| Search | 15 | 14/14 | 14/14 |
| Board | 15 | 10/10 | 12/12 |
| Profile | 15 | 15/10 | 15/10 |
Pinner, board, and createdAt were non-empty on 10/10 fixed rows here versus 3/10 in
the reference. The reference matched the collection on those counts in the other modes.
This is availability evidence, not proof that every non-empty value is semantically
better.
All four 0.2.5 runs had OUTPUT.status: completed and failed: 0. The optional
text stage attempted and filled descriptions on 5 profile rows, failed on none, and
added no delivery charge. Search and board skipped 2 and 5 opaque IDs respectively.
The current evidence artifacts are:
- ../../validation/pinterest-text-modes-2026-10-20/inputs.json
- ../../validation/pinterest-text-modes-2026-10-20/run-summary.json
- ../../validation/pinterest-text-modes-2026-10-20/comparison-report.json
- ../../validation/pinterest-text-modes-2026-10-20/web-report.json
- ../../validation/pinterest-text-modes-2026-10-20/incident.json
- ../../validation/pinterest-text-modes-2026-10-20/agent-routing.json
Anonymous public HTML independently matched title, description, and original-image URL on 25/25 numeric close-up Pins from the fixed and profile results. The nine source pages returned HTTP 200, but anonymous search HTML exposed no result Pin entities, and board pages supplied less per-row text. This does not verify all 55 rows from the web or constitute a complete authenticated rendered-DOM check.
Version 0.2.4 is not the live build. Its four verification runs failed after writing
valid Datasets because OUTPUT.textEnrichment was missing from the strict published
key-value schema. It was rolled back to 0.2.3. The incident audit inspected 82 run
metadata records to cover the window; only four runs fell inside it, all of them this
task's validation runs. There were no other-user runs or failures in that window. After
PR #687 added an Ajv test for the
actual schema, 0.2.5 passed the four-mode canary and was promoted. The complete
release record is ../../validation/pinterest-text-modes-2026-10-20/README.md.
Historical 0.2.1 comparison
The measurements in the remainder of this section are the older 0.2.1 fixed-ten-Pin
record. They are retained as dated history and are not the current 0.2.5 result.
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.
That historical source audit did not fetch the pages during its 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-text-modes-2026-10-20/README.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.