# Keyword Search Volume: Keyword Planner Data, CPC & Trends (`steady-scrape/keyword-search-volume`) Actor

Bulk Google search volume, CPC, competition, top-of-page bids and a 12-month trend for up to 10,000 keywords per run, by country and language. Keyword Planner data without a Google Ads account. 30-day cache, clean JSON for SEO tools and AI agents.

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

## Pricing

from $3.00 / 1,000 keyword results

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: Keyword Planner Data, CPC & Trends

Get **Google search volume, CPC, competition, top-of-page bids and a 12-month trend** for up to 10,000 keywords per run, for any country and language. It's Keyword Planner data **without a Google Ads account**, and you get clean JSON that's ready for spreadsheets, SEO tools and AI agents.

- 📊 **Keyword Planner metrics**: average monthly searches, CPC, competition (LOW/MEDIUM/HIGH plus a 0-100 index), and low/high top-of-page bids
- 📈 **12-month trend**: searches for each month, oldest first
- 🌍 **190+ countries, 50+ languages**: pass names ("Germany", "German"), ISO codes ("DE", "de") or Google Ads location codes (2276)
- ⚡ **Fast by default**: results in seconds. Keywords looked up in the last 30 days come back instantly from a cache
- 🧹 **Clean input**: lowercases, trims and dedupes keywords. Keywords Google Ads rejects are flagged `invalid` and never charged
- 💸 **You pay only for keywords that return data**: `no_data`, `invalid` and `error` rows are free

### Quick start

```json
{
  "keywords": ["keyword research", "seo tools", "best running shoes"],
  "location": "United States",
  "language": "English"
}
```

### Output

One item per keyword, in the same order as your input:

| Field | Example | Notes |
|---|---|---|
| `keyword` | `best running shoes` | Normalized keyword |
| `inputKeyword` | `Best Running Shoes!` | As you typed it |
| `status` | `ok` | `ok`, `no_data`, `invalid` or `error` |
| `searchVolume` | `201000` | Average monthly searches (last 12 months) |
| `monthlySearches` | `[{"month": "2025-10", "searchVolume": 165000}, …]` | Last 12 months |
| `cpc` | `1.42` | USD |
| `competition` / `competitionIndex` | `HIGH` / `100` | Paid-search competition |
| `lowTopOfPageBid` / `highTopOfPageBid` | `0.61` / `2.07` | USD |
| `keywordDifficulty` / `searchIntent` | `71` / `commercial` | Only when the data comes from the keyword database (auto and labs modes) |
| `spellCorrection` | `null` | The spelling Google Ads used, when it corrected the keyword |
| `location`, `locationCode`, `language`, `languageCode` | `United States`, `2840`, `English`, `en` | |
| `dataDate` | `2026-09` | Latest month in the data |
| `source` | `live` | `live` (fetched this run) or `cache` (looked up in the last 30 days) |
| `dataSource` | `google_ads` | `google_ads` (Keyword Planner) or `dataforseo_labs` (keyword database built from Google Ads data) |
| `fetchedAt` | `2026-10-26T22:11:36Z` | When the data was fetched |

The run summary (counts, cached vs fresh, and the mode used) is saved in the key-value store as `OUTPUT`.

### Modes

| Mode | Speed | Data source | Best for |
|---|---|---|---|
| `auto` (default) | seconds | DataForSEO Labs keyword database, then Google Ads live for anything missing | Most lists: fast and complete |
| `live` | ~7 s per 1,000 keywords | Google Ads Keyword Planner (live) | When you want every number straight from Keyword Planner |
| `labs` | seconds | DataForSEO Labs keyword database only | Adds keyword difficulty and search intent; keywords not in the database come back as `no_data` |
| `queue` | 1-3 hours | Google Ads Keyword Planner (standard queue) | Very large lists (5,000+ keywords) where waiting is fine |

All modes return the same fields. Keyword Planner numbers only change once a month, so keywords looked up in the last 30 days for the same country and language can come back instantly from a cache.

### Pricing

Pay per event, no subscription:

| Event | Price | When |
|---|---|---|
| **Lookup** | **$0.12 per run** | Once per run, only when fresh data is requested from the provider. Runs answered fully from the cache don't pay it |
| **Keyword result** | **$0.003 per keyword ($3 per 1,000)** | Per keyword that returns a search volume |
| Actor start | $0.00005 | Apify's standard start fee |

**Keywords without data are free**: `no_data`, `invalid` and `error` rows are never charged as keyword results. The lookup covers the data request itself, so it still applies to a run where fresh keywords were requested but none had data.

Examples: 20 keywords = $0.18, 100 keywords = $0.42, 1,000 keywords = $3.12 (if every keyword has data).

Set **Max cost per run** in the run options to cap spending. The Actor only processes as many keywords as your limit covers.

### Data source

Data comes from [DataForSEO](https://dataforseo.com), from its Google Ads Keyword Planner API and its DataForSEO Labs keyword database. DataForSEO's site says its customers may show its data in tools they sell to their own users. This Actor is built by SteadyScrape and isn't affiliated with Google or DataForSEO.

### Limits & notes

- Each keyword can have at most 80 characters and 10 words. Characters Google Ads rejects are removed when **Clean up keywords** is on.
- Google Ads groups close variants, so for example `running shoe` and `running shoes` can show the same volume.
- Very low-volume keywords may return `no_data`.
- Worldwide (no location) is only available in `live` and `queue` modes.
- Up to 1,000 keywords per run by default (**Max keywords per run**, up to 10,000). Very large fresh lists may be asked to split into smaller runs.

### More tools from SteadyScrape

- [AI Visibility & Share of Voice Tracker](https://apify.com/steady-scrape/ai-brand-visibility-tracker): see whether ChatGPT and Perplexity mention, rank and cite your brand versus your competitors.
- [ATS Job Scraper](https://apify.com/steady-scrape/ats-job-feed): see which roles your competitors are hiring for, straight from their career sites.

### Need something else?

Open an issue in the **Issues** tab. SteadyScrape usually replies within a day.

# Actor input Schema

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

Keywords or phrases, one per line (up to 80 characters and 10 words each, Google Ads limits). Duplicates and casing differences are merged.

## `location` (type: `string`):

Country name ("United States", "Germany"), ISO code ("US", "GB"), Google Ads location code (2840) or a full DataForSEO location name such as "London,England,United Kingdom". Use "worldwide" for all locations (mode live or queue only).

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

Language name ("English", "Spanish", "Chinese (Simplified)") or code ("en", "es").

## `mode` (type: `string`):

Where fresh data comes from. All modes return the same fields; cached keywords are returned instantly in every mode.

## `includeMonthlyTrend` (type: `boolean`):

Add monthlySearches: search volume for each of the last 12 months.

## `normalizeKeywords` (type: `boolean`):

Lowercase, trim, collapse spaces and remove characters Google Ads rejects (! @ % , ? quotes...). Invalid keywords are reported, never charged.

## `dedupe` (type: `boolean`):

Return each normalized keyword once.

## `useCache` (type: `boolean`):

Keyword Planner data changes monthly, so keywords looked up in the last 30 days for the same market come from the cache instantly.

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

Safety limit: keywords beyond this are skipped.

## `queueMaxWaitMinutes` (type: `integer`):

How long a queue-mode run waits for the provider before returning what is ready.

## Actor input object example

```json
{
  "keywords": [
    "keyword research",
    "seo tools",
    "best running shoes"
  ],
  "location": "United States",
  "language": "English",
  "mode": "auto",
  "includeMonthlyTrend": true,
  "normalizeKeywords": true,
  "dedupe": true,
  "useCache": true,
  "maxKeywords": 1000,
  "queueMaxWaitMinutes": 180
}
```

# Actor output Schema

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

One item per keyword. Use /items without ?view for all fields, including the 12-month trend.

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

Counts (ok, no data, invalid, cached vs fresh) and the mode used.

# 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"
    ],
    "location": "United States",
    "language": "English"
};

// Run the Actor and wait for it to finish
const run = await client.actor("steady-scrape/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",
    ],
    "location": "United States",
    "language": "English",
}

# Run the Actor and wait for it to finish
run = client.actor("steady-scrape/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"
  ],
  "location": "United States",
  "language": "English"
}' |
apify call steady-scrape/keyword-search-volume --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,steady-scrape/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/L2EdqCnPxTEDgNzJS/builds/u6FxRPf4pSa86sveO/openapi.json
