# Keyword Search Volume - Google Keyword Planner (`adyg/keyword-search-volume`) Actor

Bulk Google keyword search volume from the Google Ads API (Keyword Planner): monthly search volume, 12-month trend, CPC, competition and top-of-page bids for up to thousands of keywords, plus keyword ideas. Any country, region or language. No Google Ads account needed.

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

## Pricing

from $3.30 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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: Google Keyword Planner data in bulk (volume, CPC, competition, trends)

**Keyword Search Volume** gets Google Keyword Planner data for any list of keywords straight from the **Google Ads API**: average monthly search volume, a 12-month search trend, competition, CPC and low/high top-of-page bids. You can also get **keyword ideas** for seed keywords. It works for any country, region, city and language. You don't need a Google Ads account, and keywords without data are free.

### What does Keyword Search Volume do?

Paste your keywords, pick a location and language, and you get one clean row per keyword:

- 📈 **Search volume**: the average monthly Google searches Google Ads reports
- 📅 **12-month trend**: month-by-month search volume, plus % change vs. last month, last quarter and last year (when that much history is available). Set a date range to get up to 4 years of history.
- 🥊 **Competition**: LOW / MEDIUM / HIGH and an index from 0 to 100
- 💰 **CPC** and **top-of-page bids**: low and high range, in USD
- 💡 **Keyword ideas** (optional): new keywords from your seed keywords, like Keyword Planner's "Discover new keywords", with the same metrics

You can run it as a bulk Keyword Planner search volume checker from the browser, the API, a schedule or any integration (Make, Zapier, n8n, Google Sheets, Python, JavaScript, AI agents).

### Why use this keyword search volume tool?

- **Real Google Ads numbers, no ad spend.** You get the exact Keyword Planner averages, not the rounded "1K-10K" ranges Google shows to accounts without active campaigns.
- **Bulk and efficient.** Each Google Ads request covers up to **1,000 keywords**, so large lists are cheap and fast.
- **Clean input handling.** Keywords are trimmed, lower-cased and de-duplicated. Match-type symbols (`[exact]`, `"phrase"`, `+broad`), emojis and characters Google Ads rejects are removed. Keywords longer than 80 characters or 10 words are skipped and listed in the run summary, so one bad keyword never breaks a run.
- **Any market.** 200+ countries, plus states, regions and cities by Google Ads location name, in 40+ languages.
- **Fair pricing.** You pay per keyword with data. Keywords Google has no data for are listed but not charged.

### Use cases

- **SEO keyword research**: size topics before you write and prioritize pages by search demand.
- **PPC planning**: estimate CPC and top-of-page bids before you launch Google Ads campaigns.
- **Content calendars**: spot seasonal peaks in the monthly history.
- **Market research**: compare demand for products, brands or features across countries.
- **Agencies, SaaS and AI agents**: enrich keyword lists in bulk on a schedule through the API.

### How to get keyword search volume

1. Paste your keywords (one per line) into **Keywords**.
2. Set **Location** (e.g. `United States`, `GB`, `2840` or `California,United States`) and **Language** (e.g. `English`).
3. Optionally choose **Keyword ideas** or **Both** under **What to get**, and set a date range for the history.
4. Click **Start**. Download the results as Excel, CSV, JSON or HTML, or fetch them through the API.

#### Input example

```json
{
    "keywords": ["keyword research", "seo tools", "content marketing"],
    "location": "United States",
    "language": "English",
    "mode": "search_volume",
    "includeMonthlySearches": true
}
```

| Field | Description |
| --- | --- |
| `keywords` | Keywords to check, or seed keywords for ideas. Normalized and de-duplicated automatically. Max 80 characters and 10 words each. |
| `location` | Country name, 2-letter code or Google Ads location code. For regions and cities, use the Google Ads name, e.g. `London,England,United Kingdom`. Default: `United States`. |
| `language` | Language name or code (`English`, `es`). Empty = main language of the location. |
| `mode` | `search_volume` (default), `keyword_ideas` or `both`. |
| `includeMonthlySearches` | Add the month-by-month history (default `true`). |
| `dateFrom` / `dateTo` | Optional history range as `YYYY-MM`, up to 4 years back. Default: last 12 months. |
| `maxIdeas` | Max keyword ideas per run (default 100). |
| `minSearchVolume` | Skip ideas below this monthly volume. |
| `dataSource` | `google_ads` (default, live Google Ads API), `keyword_database` (monthly-refreshed Keyword Planner data with keyword difficulty and search intent, countries only, no request fee) or `auto`. |
| `ideasMethod` | Keyword database only: `keyword_ideas`, `keyword_suggestions` (long-tail) or `related_keywords`. |
| `googleAdsMode` | `live` (default, seconds) or `queued` (cheaper request fee, usually takes minutes). |

#### Output example

```json
{
    "keyword": "keyword research",
    "type": "keyword",
    "seed_keyword": null,
    "location": "United States",
    "location_code": 2840,
    "language": "English",
    "language_code": "en",
    "search_volume": 90500,
    "cpc": 14.72,
    "competition": "LOW",
    "competition_index": 1,
    "low_top_of_page_bid": 4.32,
    "high_top_of_page_bid": 19.5,
    "keyword_difficulty": null,
    "search_intent": null,
    "trend": { "monthly": 0, "quarterly": -70, "yearly": null },
    "monthly_searches": [
        { "date": "2025-09", "year": 2025, "month": 9, "search_volume": 74000 },
        { "date": "2025-10", "year": 2025, "month": 10, "search_volume": 8100 },
        { "date": "2026-08", "year": 2026, "month": 8, "search_volume": 135000 }
    ],
    "found": true,
    "source": "google_ads_live",
    "data_updated_at": null,
    "scraped_at": "2026-10-08T07:12:12Z"
}
```

`monthly_searches` lists every month, oldest first. The example above is shortened. Keyword ideas have `"type": "idea"` and the `seed_keyword` they came from. If Google has no data for a keyword, it's still listed with `"found": false` and a short `note`, and you aren't charged for it. The dataset has an **Overview** table and a **Monthly trends** view. The `SUMMARY` record in the key-value store lists skipped or invalid keywords and run statistics.

### Pricing

This Actor uses **pay-per-event** pricing. Keywords without data are free.

| Event | Price |
| --- | --- |
| Keyword result (`keyword-result`) | **$0.004** per keyword or keyword idea with data |
| Google Ads live request (`google-ads-live-request`) | **$0.15** per request (up to 1,000 keywords, or up to 20 seeds for ideas) |
| Google Ads queued request (`google-ads-queued-request`) | **$0.08** per request (`googleAdsMode: queued`) |

| Example run | Cost |
| --- | --- |
| 3 keywords, United States | $0.162 |
| 1,000 keywords, Germany | $4.15 |
| 5,000 keywords | $20.75 |
| 1,000 keywords with `dataSource: keyword_database` (no request fee) | $4.00 |

To cap your spend, set **Maximum cost per run** in the run options. The Actor checks the limit before each Google Ads request and stops cleanly when it's reached.

**Free Apify plan:** runs from free-plan accounts use the keyword database and are limited to 10 keywords and 10 ideas per run, at country level only. Any paid Apify plan removes these limits.

### Related tools

SEO toolkit: keyword demand → competitor authority and traffic → AI search visibility.

- [Domain Authority & Traffic Checker](https://apify.com/adyg/domain-authority-traffic-checker): bulk domain authority, backlinks and organic traffic
- [AI Search Visibility Tracker](https://apify.com/adyg/ai-search-visibility-tracker): check if ChatGPT, Perplexity, Gemini and AI Overviews mention your brand
- [Google Trends Scraper](https://apify.com/adyg/google-trends-scraper): interest over time, by region, related queries and Trending Now
- [Google Ads Transparency Scraper](https://apify.com/adyg/google-ads-transparency-scraper): see competitors' Google, YouTube and Shopping ads

All of these are maintained by the same developer and export flat JSON, CSV or Excel, so you can feed one tool's dataset into the next.

### FAQ

**Where does the data come from?**
From the Google Ads API, which is the same data you see in Google Keyword Planner. With `dataSource: keyword_database`, the Actor reads a database built from Google Ads data and refreshed every month instead. It's cheaper for small runs and adds keyword difficulty and search intent.

**Why is a keyword returned with `found: false`?**
Google has no measurable search volume for it, usually because the phrase is very rare or new. You aren't charged for it.

**Why do similar keywords show identical numbers?**
Google Ads groups close variants (plurals, misspellings, word order) and reports the same volume for all of them. Google also rounds volumes into buckets such as 90,500 or 110,000.

**Can I get search volume for a city or state?**
Yes. Use the Google Ads location name, e.g. `New York,New York,United States`, `California,United States` or `Bavaria,Germany`.

**How many keywords can I check at once?**
Thousands per run. They're sent in batches of 1,000 per Google Ads request. Google Ads allows about 12 live requests per minute, so 10,000 keywords (10 requests) usually take 1-3 minutes.

**Can I use it through the API or on a schedule?**
Yes. Call it through the Apify API, schedule it, or connect it to Make, Zapier, n8n, Google Sheets and other integrations.

**Is this an official Google product?**
No. This Actor isn't affiliated with or endorsed by Google. Google, Google Ads and Keyword Planner are trademarks of Google LLC.

**Found a problem?**
Open an issue on the Issues tab with your run ID.

### Acceptable use

- This Actor is an independent tool. It is not affiliated with, endorsed by or sponsored by Google, Google Ads or DataForSEO.
- Don't use the data to build a competing search engine, or otherwise to compete with or harm Google or the other search engines the data comes from.
- The Actor may not be used from, or for people or organizations in, Russia, Belarus, Cuba, Iran, Syria, Myanmar, North Korea, Crimea or the Russian-occupied territories of Ukraine.
- You are responsible for using the results lawfully, including privacy laws such as GDPR for any personal data they contain.

# Actor input Schema

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

Keywords to look up (one per line). Used as <b>seed keywords</b> when you ask for keyword ideas. Keywords are trimmed, lower-cased and de-duplicated; match-type symbols like <code>\[exact]</code> or <code>"phrase"</code> and characters Google Ads does not accept are removed. Max 80 characters and 10 words per keyword. Large lists are split into batches automatically.

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

<b>Search volume</b>: metrics for exactly the keywords you enter. <b>Keyword ideas</b>: new related keywords (with the same metrics) generated from your seed keywords, like Google Keyword Planner's 'Discover new keywords'. <b>Both</b>: metrics for your keywords plus ideas.

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

Country name (<code>United States</code>, <code>Germany</code>), 2-letter country code (<code>US</code>, <code>GB</code>) or location code (<code>2840</code>). For a state, region or city use the Google Ads location name, e.g. <code>California,United States</code> or <code>London,England,United Kingdom</code> (region/city lookups always use live Google Ads data).

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

Language name (<code>English</code>, <code>Spanish</code>) or code (<code>en</code>, <code>es</code>). Leave empty to use the main language of the location (e.g. German for Germany).

## `includeMonthlySearches` (type: `boolean`):

Add the month-by-month search volume (last 12 months by default, or the date range below) to every result.

## `dateFrom` (type: `string`):

Optional start month of the monthly history, format <code>YYYY-MM</code> (e.g. <code>2024-01</code>). Up to 4 years back. Leave empty for the last 12 months.

## `dateTo` (type: `string`):

Optional end month of the monthly history, format <code>YYYY-MM</code>. Google publishes data for the previous month only, so later months are capped automatically.

## `ideasMethod` (type: `string`):

Only used for keyword ideas. With the <b>Google Ads API</b> data source, ideas come from Keyword Planner's 'Discover new keywords' (up to 20 seed keywords per request) and this setting is ignored. With the <b>keyword database</b>: <b>Keyword Planner-style ideas</b> = keywords about the same topic; <b>Long-tail suggestions</b> = phrases that contain your seed keyword; <b>Related searches</b> = Google's 'related searches' for your seed keyword.

## `maxIdeas` (type: `integer`):

Maximum number of keyword ideas to return in total per run. You only pay for ideas that are returned.

## `minSearchVolume` (type: `integer`):

Skip keyword ideas with a lower average monthly search volume. 0 = keep all ideas that have data.

## `dataSource` (type: `string`):

<b>Google Ads API</b> (default): queries Google Ads (Keyword Planner) live, up to 1,000 keywords per request, and returns a row for every keyword Google knows. Adds a small per-request fee (see Pricing). <b>Keyword database</b>: a database built from Google Ads data, refreshed monthly; no request fee, also returns keyword difficulty and search intent, country-level locations only. <b>Auto</b>: keyword database for country-level searches, Google Ads API for regions/cities or languages the database does not cover.

## `googleAdsMode` (type: `string`):

Only used when the Google Ads API is queried. <b>Live</b> (default): results in seconds. <b>Queued</b>: cheaper per-request fee, but results usually take a few minutes and can take longer at peak times; the run waits for them. If a queued run times out, run it again with the same input to collect the results without paying the request fee again.

## `queuedMaxWaitMinutes` (type: `integer`):

Queued mode only: how long the run waits for Google Ads results before stopping (it never waits past the run timeout).

## Actor input object example

```json
{
  "keywords": [
    "keyword research",
    "seo tools",
    "content marketing"
  ],
  "mode": "search_volume",
  "location": "United States",
  "language": "English",
  "includeMonthlySearches": true,
  "ideasMethod": "keyword_ideas",
  "maxIdeas": 100,
  "minSearchVolume": 0,
  "dataSource": "google_ads",
  "googleAdsMode": "live",
  "queuedMaxWaitMinutes": 120
}
```

# Actor output Schema

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

No description

## `trends` (type: `string`):

No description

## `summary` (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 = {
    "keywords": [
        "keyword research",
        "seo tools",
        "content marketing"
    ],
    "mode": "search_volume",
    "location": "United States",
    "language": "English"
};

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

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

```

## MCP server setup

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