# Keyword Search Volume, CPC, Difficulty & Intent (`keywordlab/keyword-search-volume`) Actor

Bulk Google keyword metrics without a subscription: monthly search volume, CPC, competition, keyword difficulty, search intent, 12-month trend and seasonality for up to 10,000 keywords per run. Pay only for keywords with data.

- **URL**: https://apify.com/keywordlab/keyword-search-volume.md
- **Developed by:** [KeywordLab](https://apify.com/keywordlab) (community)
- **Categories:** SEO tools, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.00 / 1,000 keyword with data

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/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

## Keyword Search Volume, CPC, Difficulty & Intent

Get Google keyword metrics in bulk without a subscription: **monthly search volume, CPC, competition, keyword difficulty, search intent, trend, year-over-year change and seasonality** for up to 10,000 keywords per run, in 28 countries.

Paste a keyword list, pick a country, and download the results as CSV, Excel or JSON, or pull them through the API. **You pay only for keywords that come back with data.**

### What you get for each keyword

| Field | Description |
|---|---|
| `search_volume` | Google's average monthly searches over the last 12 months |
| `median_monthly_searches` | The typical month: unlike the average, not inflated by one-off spikes |
| `has_spike` | `true` when a recent month was at least 4× the typical month, so the average overstates demand |
| `cpc` | Average cost per click in USD |
| `competition`, `competition_level` | Advertiser competition, 0–1 and LOW / MEDIUM / HIGH |
| `low_top_of_page_bid`, `high_top_of_page_bid` | Top-of-page bid range in USD |
| `keyword_difficulty` | How hard it is to rank in the organic top 10, 0–100 |
| `search_intent`, `secondary_intents` | informational, navigational, commercial or transactional |
| `monthly_searches` | Search volume for each of the last 12 months |
| `trend_direction`, `trend_monthly_pct` | rising / stable / falling over the last 12 months, with the typical monthly change |
| `yoy_change_pct` | Typical month this year vs. the year before (median-based, so spikes don't distort it) |
| `is_seasonal`, `peak_month` | `true` when demand peaks in the same month (±1) in at least two of the last three years, and which month |
| `source` | `database` (full metrics) or `google_ads_live` (live Keyword Planner lookup) |

### Why this actor

- **No subscription, no deposit.** Popular keyword tools charge a monthly subscription. Here 1,000 keywords cost $6, and you pay only when you run it.
- **Difficulty and intent are included**, not sold as extras.
- **No charge for keywords without data.** Keywords Google has no data for are listed in the run summary and never billed.
- **Spike-proof trends.** Google's monthly numbers often contain one-off spikes: a keyword searched 12,000 times a month can show 1.5 million for a single month. Typical volume, trend, year-over-year change and seasonality are calculated so a single spike can't distort them, and spikes are flagged.

### How to use it

1. Paste your keywords, one per line.
2. Choose a country. The language defaults to the country's main language.
3. Click **Start** and download the dataset when the run finishes.

#### Input example

```json
{
  "keywords": ["keyword research", "seo tools", "best running shoes"],
  "country": "US"
}
```

#### Output example

```json
{
  "keyword": "iphone",
  "country": "US",
  "language": "en",
  "search_volume": 1220000,
  "cpc": 6.45,
  "competition": 1,
  "competition_level": "HIGH",
  "low_top_of_page_bid": 2.6,
  "high_top_of_page_bid": 5.14,
  "keyword_difficulty": 89,
  "search_intent": "informational",
  "secondary_intents": [],
  "median_monthly_searches": 1220000,
  "has_spike": false,
  "trend_direction": "stable",
  "trend_monthly_pct": 0.0,
  "yoy_change_pct": 22.0,
  "is_seasonal": true,
  "peak_month": "September",
  "monthly_searches": [
    {
      "month": "2024-12",
      "search_volume": 1500000
    },
    {
      "month": "2025-01",
      "search_volume": 1220000
    },
    {
      "month": "2025-02",
      "search_volume": 1220000
    }
  ],
  "source": "database",
  "data_updated_at": "2025-03-06 03:08:24 +00:00"
}
```

(`monthly_searches` is shortened here; you get all 12 months.)

A `SUMMARY` record in the run's key-value store lists how many keywords had data and which ones did not.

### Pricing

Pay per event, no monthly fee:

| Event | Price |
|---|---|
| Run start | $0.02 |
| Keyword with data | $0.006 ($6 per 1,000) |
| Live lookup batch (optional, up to 1,000 missing keywords) | $0.15 |

Example: 500 keywords where 480 have data cost $0.02 + 480 × $0.006 = **$2.90**.

Set a maximum cost per run in the run options. The actor checks that limit before it starts, processes only as many keywords as fit, and never goes over it.

### Use cases

- **SEO content planning:** find keywords with real volume and low difficulty, grouped by intent.
- **PPC budgeting:** estimate CPC and competition before you launch a Google Ads campaign.
- **Search arbitrage and media buying:** compare CPC across keywords and countries to pick profitable terms.
- **Seasonal planning:** see which months your topics peak and which topics are rising.
- **Market research:** compare demand for products, brands or features across 28 countries.
- **AI agents and automations:** call it from the Apify API, Make, Zapier, n8n or an MCP client.

### Supported countries

United States, United Kingdom, Canada, Australia, New Zealand, Ireland, India, Singapore, South Africa, Germany, Austria, Switzerland, France, Belgium, Netherlands, Spain, Mexico, Italy, Portugal, Brazil, Poland, Sweden, Denmark, Finland, Czechia, Ukraine, Turkey and Japan.

Need another country? Open an issue on the actor's Issues tab.

### FAQ

**Where does the data come from?**
From DataForSEO, a licensed provider of Google keyword data. Keywords are answered from its database of Google keyword data, which includes difficulty and intent. Optionally, keywords missing from the database can be checked live in Google Keyword Planner.

**Why is a keyword missing from my results?**
Google has no search data for very rare phrases, typically long ones with six words or more, and for a few restricted topics. Such keywords are listed under `keywords_without_data` in the `SUMMARY` record and are not charged. In our tests the database covered about 95% of short and mid-length keywords and 85% of questions, but only a quarter of very long phrases.

**Should I enable live lookup?**
Usually not. Keywords missing from the database almost always have no Google data at all, so live lookup rarely adds rows. It can help with brand-new or trending terms the database hasn't picked up yet. It costs $0.15 per batch of up to 1,000 missing keywords.

**Why do live results have no difficulty or intent?**
Google Keyword Planner provides volume, CPC and competition only. Difficulty and intent come from the keyword database.

**Are volumes exact?**
They are Google's monthly figures from Keyword Planner data, which Google rounds into buckets (for example 1,000, 1,300, 1,600). Use `median_monthly_searches` when you need the typical month and `search_volume` when you need Google's own average.

**Is there a limit?**
Up to 10,000 keywords per run, each up to 80 characters and 10 words. For more, start several runs or schedule them.

# Actor input Schema

## `keywords` (type: `array`):

One keyword per line, up to 10,000 per run. Duplicates are removed, keywords are lowercased, and characters Google Ads does not accept (such as ? or ,) are replaced with spaces. Max 80 characters and 10 words per keyword.

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

Market to get search volume and CPC for.

## `language` (type: `string`):

Leave empty to use the country's main language (for example German for Germany).

## `liveLookupForMissing` (type: `boolean`):

Off by default. Most keywords missing from the database have no Google search data at all (very long phrases, brand-new terms). Turn this on to also check them live in Google Keyword Planner; it costs $0.15 per batch of up to 1,000 missing keywords, plus the usual price for each keyword that comes back with data. Live results include volume, CPC and competition but no difficulty or intent.

## Actor input object example

```json
{
  "keywords": [
    "keyword research",
    "seo tools",
    "best running shoes",
    "how to start a podcast"
  ],
  "country": "US",
  "liveLookupForMissing": false
}
```

# Actor output Schema

## `keywords` (type: `string`):

One row per keyword with data: search volume, CPC, competition, difficulty, intent, trend, YoY change and seasonality. Only these rows are charged.

## `summary` (type: `string`):

Counts of processed keywords and the list of keywords without data (not charged).

# 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 = {
    "keywords": [
        "keyword research",
        "seo tools",
        "best running shoes",
        "how to start a podcast"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("keywordlab/keyword-search-volume").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 = { "keywords": [
        "keyword research",
        "seo tools",
        "best running shoes",
        "how to start a podcast",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("keywordlab/keyword-search-volume").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 '{
  "keywords": [
    "keyword research",
    "seo tools",
    "best running shoes",
    "how to start a podcast"
  ]
}' |
apify call keywordlab/keyword-search-volume --silent --output-dataset

```

## MCP server setup

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

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/8S5X9SuHfSeFdwDS2/builds/ZrJW67jqR1pOy5Hc0/openapi.json
