# Bulk Keyword Planner: Keyword Volume Checker for Big Lists (`magenta_waterwheel/bulk-keyword-planner`) Actor

Google Keyword Planner search volume, CPC and competition for big keyword lists. Paste a list or a CSV URL and pick one or many countries. Flat $0.19 per batch of up to 1,000 keywords per location; no per-keyword fee. No Google Ads account needed.

- **URL**: https://apify.com/magenta_waterwheel/bulk-keyword-planner.md
- **Developed by:** [Magenta Waterwheel](https://apify.com/magenta_waterwheel) (community)
- **Categories:** SEO tools, AI, Developer tools
- **Stats:** 2 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $190.00 / 1,000 batch of up to 1,000 keywords

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

## Bulk Keyword Planner: Keyword Volume Checker for Big Lists

**Bulk Keyword Planner** gets **Google Keyword Planner search volume**, **CPC**, top-of-page bids and **competition** for **large keyword lists**, in **one or many countries**, at a **flat price per batch**: **$0.19 per batch of up to 1,000 keywords per location**, with no per-keyword fee. 1,000 keywords cost the same as 10.

Feed it a list, a pasted spreadsheet column or a **CSV file URL**, add the countries you care about, and export the results to JSON, CSV or Excel, or call it from the API, Make, Zapier, n8n or an AI agent. No Google Ads account or API key needed.

### When to use it

- You have **hundreds to tens of thousands of keywords** (keyword research exports, product catalogs, location x service lists) and want volumes for all of them.
- You need the **same list in several markets** (for example US, UK, Canada, Australia) in one run.
- You want a **predictable bill**: you pay per batch, not per keyword.

For a handful of keywords at a time, our [Keyword Search Volume API](https://apify.com/magenta_waterwheel/keyword-search-volume) is the simpler tool.

### Input

| Field | What it does |
| --- | --- |
| `keywords` | List of keywords. |
| `keywordsText` | Paste a long list, one keyword per line. |
| `csvUrl` | Public CSV/TSV URL. Reads the column named keyword, keywords, query or term (or `csvColumn`), else the first column. |
| `locations` | One or more Google Ads locations (names or codes). Each location is a separate lookup. Empty = `location`. |
| `language` | Language code or name, e.g. `en`. |
| `includeCpcCompetition`, `includeMonthlySearches` | Extra fields (on by default). |
| `dateFrom`, `dateTo` | Monthly history range, up to 4 years back. |

All sources are combined, lowercased and de-duplicated. Keywords Google Ads would reject (too long, emoji, `! @ % , ( )`) are skipped for free and listed in the run summary.

```json
{
    "keywordsText": "running shoes\ntrail running shoes\nbest marathon shoes",
    "csvUrl": "https://example.com/my-keywords.csv",
    "locations": ["United States", "United Kingdom", "Canada"],
    "language": "en"
}
```

### Output

One row per keyword per location: `keyword`, `location`, `language`, `searchVolume`, `cpc`, `lowTopOfPageBid`, `highTopOfPageBid`, `competition`, `competitionIndex`, `monthlySearches`, 3-month and year-over-year trend, and `hasData` (false when Google has no data). A `RUN_SUMMARY` record lists counts, skipped keywords and batches.

### Pricing

- **$0.19 per batch** of up to 1,000 keywords for one location, charged only after Google data comes back.
- **No per-keyword fee.** Keywords without data cost nothing extra.
- Examples: 1,000 keywords x 1 country = $0.19. 5,000 keywords x 3 countries = 15 batches = $2.85.
- A tiny Apify start fee ($0.00005) applies. Set a maximum cost per run and the Actor stops before a batch it can't pay for.
- Requires a paid Apify plan, because every batch pays for live Google Ads data.

### FAQ

**Where does the data come from?** Google Ads (Keyword Planner) data via a licensed data provider. Volumes are Google's monthly averages.

**How many keywords can I send?** As many as your list holds; they are split into batches of 1,000 per location. Use the maximum cost per run setting to cap spend.

**Is this the same as Keyword Search Volume API?** Same data source, different use case and price model: this one is built for big lists and many locations with flat batch pricing.

If it saved you time, a quick [rating](https://apify.com/magenta_waterwheel/bulk-keyword-planner/reviews) helps a lot. Problems or ideas: open an issue on the Issues tab.

# Actor input Schema

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

Keywords or phrases, one per item. Combined with pasted text and the CSV file. Up to 80 characters and 10 words each; duplicates are removed and keywords are lowercased. Keywords Google Ads rejects are skipped.

## `keywordsText` (type: `string`):

Paste a long list, one keyword per line (for example copied from a spreadsheet column).

## `csvUrl` (type: `string`):

Public URL of a CSV or TSV file (Google Sheets 'publish to web' CSV links work). Uses the column named keyword, keywords, query or term, else the first column.

## `csvColumn` (type: `string`):

Optional column header to read keywords from.

## `locations` (type: `array`):

One or more Google Ads location names (United States, Germany, "London,England,United Kingdom") or codes (2840). Each location is looked up separately and billed per batch. Leave empty to use Location below.

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

Country, region or city as a Google Ads location name (United States, United Kingdom, Germany, "London,England,United Kingdom") or a numeric location code (2840 = United States). Use Worldwide for global volume.

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

Language code (en, de, fr, es, pt, ja...) or name (English). Leave empty for all languages.

## `includeCpcCompetition` (type: `boolean`):

Add cost per click, low and high top-of-page bids, competition level (LOW, MEDIUM, HIGH) and competition index (0-100).

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

Add month-by-month search volume (last 12 months by default, or your date range).

## `includeKeywordsWithoutData` (type: `boolean`):

Also output keywords Google has no data for (hasData false). These are always free.

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

Start month of the monthly history, e.g. 2024-01. Up to 4 years back. Leave empty for the last 12 months.

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

End month of the monthly history, e.g. 2025-12. Google has no data for the current month.

## `searchPartners` (type: `boolean`):

Include searches on Google search partner sites, not just Google Search.

## `includeAdultKeywords` (type: `boolean`):

Return data for adult keywords (Google may still return no data).

## Actor input object example

```json
{
  "keywords": [
    "buy laptop",
    "cheap laptops for sale",
    "best gaming laptop 2026"
  ],
  "locations": [
    "United States",
    "Canada",
    "Australia"
  ],
  "location": "United States",
  "language": "en",
  "includeCpcCompetition": true,
  "includeMonthlySearches": true,
  "includeKeywordsWithoutData": true,
  "searchPartners": false,
  "includeAdultKeywords": false
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `allRecords` (type: `string`):

No description

## `runSummary` (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 tool",
        "seo tools",
        "best running shoes",
        "how to start a podcast"
    ],
    "locations": [
        "United States",
        "United Kingdom"
    ],
    "location": "United States",
    "language": "en"
};

// Run the Actor and wait for it to finish
const run = await client.actor("magenta_waterwheel/bulk-keyword-planner").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 tool",
        "seo tools",
        "best running shoes",
        "how to start a podcast",
    ],
    "locations": [
        "United States",
        "United Kingdom",
    ],
    "location": "United States",
    "language": "en",
}

# Run the Actor and wait for it to finish
run = client.actor("magenta_waterwheel/bulk-keyword-planner").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 tool",
    "seo tools",
    "best running shoes",
    "how to start a podcast"
  ],
  "locations": [
    "United States",
    "United Kingdom"
  ],
  "location": "United States",
  "language": "en"
}' |
apify call magenta_waterwheel/bulk-keyword-planner --silent --output-dataset

```

## MCP server setup

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

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/46vMjqsS6BSdgNliN/builds/VNk6V2jPM00V3XY8S/openapi.json
