# Pinterest Keyword Research & SEO Tool (`apt_marble/pinterest-keyword-research`) Actor

Turn one seed term into a full Pinterest keyword map. Get the related search terms Pinterest itself suggests, each with its own relevance score, plus the sites and accounts already ranking for them. Expand up to three levels, dedupe automatically, export to CSV. No Pinterest account needed.

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

## Pricing

$3.00 / 1,000 keyword 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 Keyword Research & SEO Tool

Give it a term you care about and it hands back the search terms Pinterest itself suggests around it — each one carrying Pinterest's own relevance score — then expands those terms again, and again, into a deduplicated keyword map. Every term also arrives with the sites and the accounts currently ranking for it, so you can see not just *what* people search on Pinterest but *who is already winning it*. Built for content marketers, Pinterest SEO specialists, agencies and shop owners planning pins, boards and blog posts.

### What you can do with it

- **Build a Pinterest keyword map from one idea.** Start with `coffee recipe`, come back to `iced coffee recipe`, `cold brew coffee recipe`, `protein coffee recipes`, `nespresso coffee recipes` — scored and ranked by Pinterest, not guessed.
- **Prioritise by Pinterest's own relevance score.** Every suggested term carries the score Pinterest attaches to it, so a hundred ideas sort themselves into an order worth working through.
- **See who already ranks.** Each keyword lists the destination sites that show up for it and how often, plus the accounts behind those pins and their follower counts.
- **Spot commercial vs inspirational terms.** The share of top pins that link out to a website separates terms people use to buy from terms people use to browse.
- **Find your competitors' keyword footprint.** Run their niche terms and read the site column — the domains that keep reappearing are the ones taking the traffic.
- **Feed a content calendar.** Export the whole map to CSV or Excel, sort by score, and turn the top rows into pin titles, board names and article headlines.

### What you get

One row per keyword. Abridged real output:

```json
{
  "type": "keyword",
  "id": "coffee recipe",
  "keyword": "coffee recipe",
  "displayTerm": null,
  "score": null,
  "scoreRank": null,
  "depth": 0,
  "parentKeyword": null,
  "rootKeyword": "coffee recipe",
  "isSeed": true,
  "searchUrl": "https://www.pinterest.com/search/pins/?q=coffee%20recipe",
  "hasRelatedTerms": true,
  "relatedKeywordCount": 10,
  "relatedKeywords": [
    { "term": "iced coffee recipe", "display": "Iced", "score": 11.266658062298308, "rank": 1 },
    { "term": "cold coffee recipes", "display": "Cold", "score": 10.256698227609977, "rank": 2 }
  ],
  "pinsAnalyzed": 24,
  "promotedPinCount": 1,
  "promotedBy": ["roastycoffee"],
  "linkedPinCount": 10,
  "linkedPinShare": 0.417,
  "topDomain": "coffeelink.com",
  "topDomains": [
    { "domain": "coffeelink.com", "pinCount": 2, "bestPosition": 6, "share": 0.083 },
    { "domain": "tr.ee", "pinCount": 1, "bestPosition": 2, "share": 0.042 }
  ],
  "topCreator": "kate526",
  "topCreators": [
    { "username": "kate526", "fullName": "Kate Carnahan Andrews", "followerCount": 475, "pinCount": 2, "bestPosition": 2 }
  ],
  "topPins": [
    {
      "position": 1,
      "id": "1142366261761747210",
      "url": "https://www.pinterest.com/pin/1142366261761747210/",
      "title": "5 Easy Coffee Recipes to Make at Home",
      "imageUrl": "https://i.pinimg.com/originals/e7/95/e0/e795e0f89045dd448725dfc1753579b5.png",
      "domain": null,
      "pinnerUsername": "ambvasc",
      "pinnerFollowerCount": 1,
      "reactionCount": 3
    }
  ],
  "country": "us",
  "servedCountry": "us",
  "scrapedAt": "2026-08-04T13:59:41.171Z"
}
```

This is a seed row, so it has no score of its own — the scores belong to the ten terms it discovered. Note `promotedPinCount` and `promotedBy`: one of the pins Pinterest showed for this term was a paid placement by `roastycoffee`, so that advertiser is named separately and is deliberately absent from `topDomains`.

### Input reference

| Field | Type | Default | What it does |
| --- | --- | --- | --- |
| `seedKeywords` | array of strings | `["coffee recipe"]` | The terms to start from. Up to 50; blank entries and pasted links are ignored. |
| `depth` | integer 0–3 | `1` | Rounds of expansion. `0` keeps only your seeds, `1` adds the terms related to them, `2` adds the terms related to those. |
| `maxKeywords` | integer 1–1000 | `100` | Hard cap on how many keyword rows the run may produce. The map stops growing the moment it is reached, so this is also your cost ceiling. |
| `includeTopPins` | boolean | `true` | Attach a sample of the pins currently at the top of each keyword, with images, links and accounts. Turn off for a slimmer spreadsheet. |
| `country` | select | `United States` | Which country's Pinterest results to read. Kept the same for every term in a run so the scores are comparable. |

### Output fields

| Field | Type | Description |
| --- | --- | --- |
| `keyword` | string | The search term this row is about. |
| `score` | number | Pinterest's own relevance score for this term against the term it was expanded from. Empty for a seed term you supplied. |
| `scoreRank` | number | Where this term sat in its parent's suggestion list, 1 being strongest. |
| `depth` | number | `0` for a seed, `1` for a term found from a seed, and so on. |
| `parentKeyword` | string | The term this one was expanded from. |
| `rootKeyword` | string | The seed term this branch grew from. |
| `isSeed` | boolean | Whether you supplied this term yourself. |
| `displayTerm` | string | The part of the term Pinterest highlights as the differentiator. |
| `searchUrl` | string | Direct link to this term on Pinterest. |
| `hasRelatedTerms` | boolean | Whether Pinterest publishes any related terms for it. |
| `relatedKeywordCount` | number | How many related terms came back (up to ten). |
| `relatedKeywords` | array | Those terms with `term`, `display`, `score`, `rank` and a link. |
| `pinsAnalyzed` | number | How many top pins were reviewed to build the columns below. |
| `promotedPinCount` | number | How many of the top pins for this term were paid placements. They are kept out of every ranking column below. |
| `promotedBy` | array | The accounts paying for those placements, which is a useful read on how contested a term is. Empty when nobody is advertising against it. |
| `linkedPinCount` | number | How many of those pins point at an outside website. |
| `linkedPinShare` | number | That count as a share of pins reviewed — a quick read on commercial intent. |
| `topDomain` | string | The site appearing most for this term. |
| `topDomains` | array | Up to ten sites with `domain`, `pinCount`, `bestPosition` and `share`. |
| `topCreator` | string | The account appearing most for this term. |
| `topCreators` | array | Up to ten accounts with `username`, `fullName`, `followerCount`, `pinCount` and `bestPosition`. |
| `topPins` | array | Up to five top pins with `position`, `url`, `title`, `altText`, `imageUrl`, `domain`, `link`, `pinnerUsername`, `pinnerFollowerCount` and `reactionCount`. `null` when the option is switched off. |
| `country` | string | The country you asked to browse from. |
| `servedCountry` | string | The country Pinterest actually served this row from. Normally identical to `country`; when the two differ, that row was answered for a different market and should not be compared against rows from another run. |
| `scrapedAt` | string | When the row was collected (ISO 8601). |

### Pricing

You pay per keyword row saved, and nothing else.

| What you pay for | Price |
| --- | --- |
| Each keyword row | **$3.00 per 1,000 keywords** |

Because every row is one keyword, your bill is simply the number of rows you asked for. `maxKeywords` is a hard ceiling, so a run can never surprise you.

**Worked example.** Three seed terms at depth 2 with `maxKeywords` set to 300 produces at most 300 keyword rows: 300 × $0.003 = **$0.90**. The same job at the default `maxKeywords` of 100 costs **$0.30**. A single seed at depth 1 returns eleven rows — about **3 cents**.

### Limits & what this actor cannot do

- **These scores are relevance, not search volume.** Pinterest does not publish how many people search a term. The score tells you how strongly Pinterest associates a term with the one it was expanded from, which is what orders your list — it is not a monthly volume figure, and it should not be compared with one from another platform.
- **Pinterest offers at most ten related terms per search term.** A keyword map therefore grows ten-wide per level, not infinitely, and `depth` is capped at three levels.
- **Some terms simply have no keyword data.** For those, `hasRelatedTerms` is `false`. Pinterest still fills the page with loosely-connected pins in that situation, so for such a term the site and account columns should be treated as noise rather than as a ranking.
- **Top pins carry no save, repin or comment totals.** Pinterest does not publish those alongside search results. Reaction counts, images, links and accounts are included; save counts are not.
- **Results are personalised by country**, so the same seed term read from a different country can return a different map. Each run keeps one country throughout for exactly that reason, and every row states the country it was actually served from in `servedCountry` — so if a run could not be answered for the country you picked, you can see that in the data instead of having to trust the label.
- **Everything is a snapshot.** Scores, follower counts and the ranking sites all move; re-run on a schedule if you need a trend.
- **Many pins are published with no caption of their own.** Those arrive with an automatically generated image description instead.
- **Paid placements are identified and kept out of the rankings.** Pinterest mixes advertising into its own results, and an advertiser who bought a slot is not a site that ranks for the term. Those pins are counted in `promotedPinCount` and the advertisers named in `promotedBy`, so you can read how contested a term is without an advertiser ever appearing in `topDomains` or `topCreators`.
- **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 output 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. Nothing is needed beyond your seed terms.

**Does it need my login or password?**
No. It never asks for one and could not use one.

**Are these monthly search volumes like Google Keyword Planner?**
No, and any tool claiming Pinterest volumes is estimating. What you get here is Pinterest's own relevance score for each suggested term, which is published, real, and good for ranking a list from strongest to weakest.

**Is the data complete?**
It is complete for what Pinterest publishes: up to ten related terms per term, and the top pins Pinterest shows for that term. It is not an exhaustive index of everything on Pinterest, and terms Pinterest has no keyword data for come back marked as such rather than being quietly padded.

**Can I schedule it?**
Yes. Schedule it weekly or monthly and compare the score column over time to see which terms are gaining.

**How do I keep the cost predictable?**
Set `maxKeywords`. The map stops growing the instant that number of rows exists, whatever `depth` says.

**Why did a term I supplied come back with an empty score?**
Seed terms are yours, not Pinterest's suggestions, so Pinterest has no score to attach to them. Every term the run discovers does carry one.

# Actor input Schema

## `seedKeywords` (type: `array`):

The search terms to start from. Each one is expanded into the related terms Pinterest itself suggests, with Pinterest's own relevance score.

## `depth` (type: `integer`):

How many rounds of expansion to run. 0 keeps only your seed terms, 1 adds the terms related to them, 2 adds the terms related to those, and so on.

## `maxKeywords` (type: `integer`):

The hard cap on how many keyword rows this run may produce. The tree stops growing as soon as the cap is reached, so this is also the cap on what the run can cost.

## `includeTopPins` (type: `boolean`):

Attach a sample of the pins currently showing at the top of each keyword's results, with their images, links and accounts. Turn this off for a slimmer, spreadsheet-friendly export.

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

The country whose Pinterest results are collected. Pinterest personalises results by country, so keeping this fixed is what makes the scores in one run comparable to each other.

## Actor input object example

```json
{
  "seedKeywords": [
    "coffee recipe"
  ],
  "depth": 2,
  "maxKeywords": 50,
  "includeTopPins": true,
  "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 = {
    "seedKeywords": [
        "coffee recipe"
    ],
    "depth": 2,
    "maxKeywords": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("apt_marble/pinterest-keyword-research").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 = {
    "seedKeywords": ["coffee recipe"],
    "depth": 2,
    "maxKeywords": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("apt_marble/pinterest-keyword-research").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 '{
  "seedKeywords": [
    "coffee recipe"
  ],
  "depth": 2,
  "maxKeywords": 50
}' |
apify call apt_marble/pinterest-keyword-research --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,apt_marble/pinterest-keyword-research"
        }
    }
}

```

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/nPdjm2N9h7f2gVyQr/builds/z7Pcn1TcdMqrfawCY/openapi.json
