# Pinterest Email Scraper (`w3crawler/pinterest-email-scraper`) Actor

Observe visibly published email addresses on bounded public Pinterest profile pages.

- **URL**: https://apify.com/w3crawler/pinterest-email-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 emails

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 Email Scraper

Observe email addresses that account owners visibly publish on public Pinterest profile pages. The actor returns a source-bound profile observation for each reachable profile and a separate public-email row for each address found in visible profile content. It never guesses addresses, signs in, reads private messages, or treats an access challenge as data.

### Input

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `startUrls` | array | Pinterest's official profile | One to 20 public HTTPS Pinterest profile URLs. Localized Pinterest subdomains are supported. |
| `maxPages` | integer | `10` | Maximum profiles to process, from 1 to 20. |
| `timeoutSecs` | integer | `30` | Per-profile request timeout, from 5 to 120 seconds. |
| `proxyConfiguration` | object | direct | Optional Apify or custom proxy transport. |

Only HTTPS Pinterest profile paths such as `https://www.pinterest.com/pinterest/` or `https://in.pinterest.com/example/` are accepted. Pin, search, login, arbitrary website, credential-bearing, and private-network URLs are rejected before a request is made.

```json
{
  "startUrls": [
    "https://www.pinterest.com/pinterest/",
    "https://in.pinterest.com/example/"
  ],
  "maxPages": 2,
  "timeoutSecs": 30,
  "proxyConfiguration": { "useApifyProxy": false }
}
```

If a proxy is explicitly requested but cannot be created, the run fails rather than silently sending traffic directly. Proxy credentials are handled by the transport layer and are never logged or stored in dataset rows.

### Collection behavior

The actor fetches public Pinterest HTML and embedded public profile state. It selects the user object whose username exactly matches the requested profile URL, avoiding unrelated board owners and route metadata. Emails are accepted only from rendered page content, the page title/description, and the matching public profile's name or bio. Repeated appearances of the same address on one page are deduplicated.

### Output

Normal rows use `entityType` values `pinterest_profile` and `pinterest_public_email`. Profile rows include the public profile ID, username, name, bio, website, follower count, canonical profile URL, email count, and source URL. Public-email rows include the owning profile ID, username, normalized address, `emailSource: "public-profile-content"`, profile URL, and source URL.

```json
{
  "entityType": "pinterest_public_email",
  "id": "424605208526455283:public@example.com",
  "profileId": "424605208526455283",
  "username": "example",
  "email": "public@example.com",
  "emailSource": "public-profile-content",
  "profileUrl": "https://www.pinterest.com/example/",
  "sourceUrl": "https://www.pinterest.com/example/",
  "scrapedAt": "2026-09-08T00:00:00.000Z"
}
```

Blocked access, redirects away from Pinterest, non-HTML responses, missing public profile state, and profiles without a published email are represented honestly. Diagnostics contain only the requested Pinterest URL, sanitized error, stable code, and timestamp:

```json
{
  "url": "https://www.pinterest.com/example/",
  "error": "The public profile page was reachable, but no email address was present in visible page content.",
  "errorCode": "SOURCE_UNAVAILABLE",
  "scrapedAt": "2026-09-08T00:00:00.000Z"
}
```

A reachable profile without an address still produces a `pinterest_profile` row with `emailsFound: 0`; the no-email observation is not counted as an email. The `OUTPUT_SUMMARY` key-value record contains run status, normal/diagnostic counts, profile/email counts, proxy state, source mode, and completion time. You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

### Run locally

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

Use a batch-specific `APIFY_LOCAL_STORAGE_DIR` when validating alongside other local runs. The actor uses bounded pages, timeouts, sequential requests, strict URL validation, minimal logging, and explicit diagnostics.

### Responsible use and limitations

Collect and use contact data only for lawful purposes with an appropriate legal basis. Honor opt-outs, anti-spam laws, privacy obligations, and Pinterest's terms. Profile owners can edit or remove public content, and Pinterest can change its HTML. Private content, messages, emails, and hidden user data are not collected.

# Actor input Schema

## `startUrls` (type: `array`):

Public HTTPS Pinterest profile URLs. Localized Pinterest subdomains are supported.

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

Maximum public profile pages to inspect.

## `timeoutSecs` (type: `integer`):

Bounded public request timeout per page.

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

Optional Apify or custom proxy settings. Direct access is used by default.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.pinterest.com/pinterest/"
  ],
  "maxPages": 10,
  "timeoutSecs": 30,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Dataset containing public-source records.

## `keyValueStore` (type: `string`):

Key-value store containing the OUTPUT\_SUMMARY run summary.

# 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 = {
    "startUrls": [
        "https://www.pinterest.com/pinterest/"
    ],
    "maxPages": 10,
    "timeoutSecs": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("w3crawler/pinterest-email-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 = {
    "startUrls": ["https://www.pinterest.com/pinterest/"],
    "maxPages": 10,
    "timeoutSecs": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("w3crawler/pinterest-email-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 '{
  "startUrls": [
    "https://www.pinterest.com/pinterest/"
  ],
  "maxPages": 10,
  "timeoutSecs": 30
}' |
apify call w3crawler/pinterest-email-scraper --silent --output-dataset

```

## MCP server setup

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