# Pinterest Ads Library Scraper (`w3crawler/pinterest-ads-library-scraper`) Actor

Scrape ad campaigns from the Pinterest Ads Library by keyword or advertiser ID and country, including advertiser names, ad titles, media URLs, status, and targeting country.

- **URL**: https://apify.com/w3crawler/pinterest-ads-library-scraper.md
- **Developed by:** [w3crawler](https://apify.com/w3crawler) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.99 / 1,000 ads

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### Pinterest Ads Library Scraper

Collect structured, public advertisement-transparency records from Pinterest's official Ads Repository. The Actor uses the public repository page and its public resource endpoints; it does not log in, bypass access controls, solve CAPTCHAs, or accept Pinterest credentials.

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

### What it returns

Normal rows use `entityType: "pinterest_ad"` and contain the public ad or Pin ID, canonical Pin URL, advertiser identity when available, creative text and media, destination URL and domain, campaign dates, audience targeting, reach ranges, transparency flags, the requested filters, and source position. Optional fields are omitted when Pinterest does not publish them. Rows are deduplicated by Pin ID.

If Pinterest returns no usable rows or access is blocked, the Actor emits one diagnostic row with exactly `url`, `error`, `errorCode`, and `scrapedAt`. The diagnostic is not ad data. The `OUTPUT_SUMMARY` key-value record contains run status, counts, filters, pagination, detail-request, and completion information.

### Input

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `advertiserName` | string | none | Optional public advertiser-name filter, such as `Nike`. |
| `country` | string | `FR` | Supported repository country code. |
| `startDate` | `YYYY-MM-DD` | five days ago | Start of the date window forwarded to Pinterest's Ads Repository API. |
| `endDate` | `YYYY-MM-DD` | run date | End of the date window forwarded to Pinterest's Ads Repository API; the range may be at most 30 days. |
| `vertical` | string | none | Optional Ads Repository category/vertical, such as `BEAUTY`. |
| `gender` | enum | none | `FEMALE`, `MALE`, or `UNSPECIFIED`. |
| `ageBucket` | enum | none | Pinterest API value such as `AGE_18_24`. |
| `maxItems` | integer | `10` | Maximum normal ad rows, from 1 to 50. |
| `maxPages` | integer | `3` | Maximum bookmark pages, from 1 to 10. |
| `includePinDetails` | boolean | `true` | Enrich rows with public Pin media, attribution, and destination data when available. |
| `maxDetailItems` | integer | `10` | Maximum Pin-detail requests, from 0 to 50. |
| `requestDelayMs` | integer | `250` | Delay before each page after the first, from 0 to 10000 ms. |
| `maxConcurrency` | integer | `1` | Bounded crawler concurrency, from 1 to 2. |
| `maxRequestRetries` | integer | `1` | Bounded navigation retries, from 0 to 3. |
| `requestTimeoutSecs` | integer | `60` | Navigation/handler timeout, from 10 to 180 seconds. |
| `proxyConfiguration` | object | direct | Optional Apify or custom proxy configuration. Credentials are not written to output. |

The runtime also accepts legacy `query` as an alias for `advertiserName` and `category` as an alias for `vertical`; supplying both names in either pair is rejected. Pinterest's currently exposed country filters are AT, BE, BR, BG, HR, CY, CZ, DK, EE, FI, FR, DE, GR, HU, IE, IT, LV, LT, LU, MT, NL, NO, PL, PT, RO, SK, SI, ES, SE, and TR.

#### Example input

```json
{
  "advertiserName": "Nike",
  "country": "FR",
  "startDate": "2026-09-02",
  "endDate": "2026-09-07",
  "maxItems": 10,
  "maxPages": 3,
  "includePinDetails": true,
  "proxyConfiguration": { "useApifyProxy": false }
}
```

### Output example

Values depend on the public repository at run time. A normal row has this shape:

```json
{
  "entityType": "pinterest_ad",
  "adId": "4602397446275423616",
  "pinId": "4602397446275423616",
  "pinUrl": "https://www.pinterest.com/pin/4602397446275423616/",
  "advertiserName": "Example advertiser",
  "adTitle": "Example campaign",
  "destinationUrl": "https://example.com/offer",
  "imageUrl": "https://i.pinimg.com/474x/example.jpg",
  "mediaType": "image",
  "countries": ["France"],
  "contentCommercial": true,
  "searchUrl": "https://ads.pinterest.com/ads-repository/?country=FR",
  "pageNumber": 1,
  "itemPosition": 1,
  "scrapedAt": "2026-09-07T12:00:00.000Z"
}
```

### Running locally

```bash
npm install
apify run --purge --input-file qa-inputs/pinterest-ads-library-scraper/local-primary.json
npm test
npm run validate
```

The scraper follows the Ads Repository's bookmark pagination up to `maxPages` and stops at `maxItems`. Direct access is the default; enable standard Apify Proxy only when needed for a permitted request. Website availability and published transparency fields can change, so consumers should tolerate absent optional properties and use the data lawfully under Pinterest's terms and applicable regulations.

#### Date-window semantics

The Actor forwards `startDate` and `endDate` unchanged to Pinterest's public Ads Repository API as `start_date` and `end_date`, and records the effective values in `OUTPUT_SUMMARY.dateFilter` and each normal row's `requestedStartDate`/`requestedEndDate`. Pinterest's response fields `startDate` and `endDate` describe the returned ad's published campaign flight; they are not post-filtered by this Actor and may extend outside the requested API window. The public response does not expose the backend matching dimension, so the Actor does not claim that those campaign dates are a strict subset of the request.

# Changelog

This Actor's version history is a separate document: https://apify.com/w3crawler/pinterest-ads-library-scraper/changelog.md

# Actor input Schema

## `advertiserName` (type: `string`):

Optional public repository advertiser filter. The legacy query alias is accepted by the runtime.

## `query` (type: `string`):

Backward-compatible alias for advertiserName. Do not supply both fields.

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

Pinterest Ads Repository country code.

## `startDate` (type: `string`):

Start of the date window forwarded to Pinterest's Ads Repository API in YYYY-MM-DD format. Defaults to five days before the run.

## `endDate` (type: `string`):

End of the date window forwarded to Pinterest's Ads Repository API in YYYY-MM-DD format. Defaults to the run date; the target currently accepts at most 30 days.

## `vertical` (type: `string`):

Optional Pinterest ad vertical, for example BEAUTY or HOME\_DECOR. The legacy category alias is accepted by the runtime.

## `category` (type: `string`):

Backward-compatible alias for vertical. Do not supply both fields.

## `gender` (type: `string`):

Optional audience gender filter.

## `ageBucket` (type: `string`):

Optional audience age bucket using the repository API value.

## `maxItems` (type: `integer`):

Global maximum of normal ad records emitted across all bookmark pages.

## `maxPages` (type: `integer`):

Maximum Ads Repository bookmark pages fetched for this run.

## `includePinDetails` (type: `boolean`):

When enabled, bounded public Pin detail requests add outbound links, attribution, media metadata, and fallback creative text.

## `maxDetailItems` (type: `integer`):

Maximum Pin detail requests; set to 0 to disable detail requests while keeping includePinDetails true.

## `requestDelayMs` (type: `integer`):

Respectful delay before each page after the first.

## `maxConcurrency` (type: `integer`):

Bounded browser concurrency. The Ads Repository uses one source request, so 1 is recommended.

## `maxRequestRetries` (type: `integer`):

Bounded Crawlee retries for failed page navigation.

## `requestTimeoutSecs` (type: `integer`):

Bounded navigation and handler timeout.

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

Optional standard Apify Proxy configuration. It is wired into the Playwright crawler; proxy credentials are never written to output.

## Actor input object example

```json
{
  "country": "FR",
  "maxItems": 10,
  "maxPages": 3,
  "includePinDetails": true,
  "maxDetailItems": 10,
  "requestDelayMs": 250,
  "maxConcurrency": 1,
  "maxRequestRetries": 1,
  "requestTimeoutSecs": 60,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

No description

## `keyValueStore` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("w3crawler/pinterest-ads-library-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("w3crawler/pinterest-ads-library-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 '{}' |
apify call w3crawler/pinterest-ads-library-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,w3crawler/pinterest-ads-library-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/eETTGZrYcoPsNzVIv/builds/SLxepks8UN4tKlYYq/openapi.json
