# Keyword Search Volume - Google Ads Volume, CPC & Competition (`scrapewise/keyword-search-volume`) Actor

Get Google Ads keyword data without an Ads account: monthly search volume, competition, competition index and low/high top of page bids (CPC) for any country. Keyword ideas from seed keywords or a website. Error rows are free.

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

## Pricing

from $4.25 / 1,000 keyword delivereds

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 Ads volume, CPC and competition

Get **Google Ads keyword data without a Google Ads account**: average monthly search volume, competition
(LOW, MEDIUM, HIGH), competition index (0 to 100) and the **low and high top of page bids** (the CPC range
advertisers pay to show at the top) for any country.

Give it seed keywords and get **up to 25 keyword ideas per seed**, with the seed row marked and duplicates across
seeds removed. Or check the exact volume of a list you already have. Or paste a website and get the keywords Google
Ads suggests for it.

Built for SEO and PPC work: keyword research, content planning, sizing a niche, pricing a campaign, or feeding
volume and CPC into a spreadsheet, an AI agent or a dashboard.

### At a glance

- **Keyword ideas, Free plan:** US$ 5.00 per 1,000 keywords
- **Exact keywords only, Free plan:** US$ 10.00 per 1,000 keywords
- **Fee per run start:** US$ 0.01, only when Google Ads answers
- **Data:** monthly search volume, competition, competition index, low and high top of page bid (USD)
- **Seed keywords, exact list or a website URL:** Yes
- **Any country:** Yes, by name or 2-letter code (United States by default)
- **Google Ads account or API key:** Not needed
- **Error rows (no data, invalid input, refused session):** Free, with an `errorCode`

### Real rows

From tests on 2026-10-08, United States. The seed row of "web scraping":

```json
{
  "keyword": "web scraping",
  "seedKeyword": "web scraping",
  "isSeed": true,
  "country": "United States",
  "locationId": 2840,
  "searchVolume": 12100,
  "competition": "LOW",
  "competitionIndex": 22,
  "lowTopPageBid": 2.82,
  "highTopPageBid": 13.35,
  "currency": "USD",
  "source": "keyword",
  "scrapedAt": "2026-10-08T14:30:04Z"
}
```

And one of the ideas for the seed "ai agents":

```json
{
  "keyword": "ai agency",
  "seedKeyword": "ai agents",
  "isSeed": false,
  "country": "United States",
  "locationId": 2840,
  "searchVolume": 90500,
  "competition": "MEDIUM",
  "competitionIndex": 46,
  "lowTopPageBid": 3.58,
  "highTopPageBid": 15.64,
  "currency": "USD",
  "source": "keyword",
  "scrapedAt": "2026-10-08T14:30:32Z"
}
```

### How to use it

**Keyword ideas** (the default). Each seed returns itself plus up to 24 related keywords:

```json
{
  "keywords": ["web scraping", "ai agents"],
  "country": "United States"
}
```

**Exact volume of a list.** One row per keyword, nothing else:

```json
{
  "keywords": ["electric car", "credit card", "coffee maker"],
  "country": "GB",
  "mode": "exactOnly"
}
```

**Keywords for a website.** Google Ads reads the page and suggests up to 25 keywords for it:

```json
{
  "websiteUrl": "https://apify.com",
  "country": "United States"
}
```

You can combine seed keywords and a website in the same run.

### Output fields

| Field | Meaning |
|---|---|
| `keyword` | The keyword as Google Ads returns it |
| `seedKeyword` | The seed it came from (or the website URL) |
| `isSeed` | `true` on the row of the seed keyword itself |
| `searchVolume` | Average monthly searches in the chosen country |
| `competition` | LOW, MEDIUM or HIGH (advertiser competition) |
| `competitionIndex` | Competition from 0 to 100 |
| `lowTopPageBid`, `highTopPageBid` | Low and high range of the top of page bid, in USD |
| `country`, `locationId` | Country name and its Google Ads location ID |
| `source` | `keyword` or `website` |
| `scrapedAt` | When the row was read (UTC) |

### Speed

Google Ads answers each browser session about **once every 16 seconds**, and each answer brings up to 25 keywords.
One session reads about 3 to 4 seeds per minute (up to 90 keyword ideas per minute). With more than 6 requests the
Actor opens a second session on another IP. Raise `maxConcurrency` (up to 5) and the run memory (about 750 MB per
session, 4 GB for 5) for long lists. Measured on 2026-10-08: 12 seeds (300 keyword ideas) in 2 minutes 20 seconds
with 2 sessions; 24 exact keywords in 4 minutes 30 seconds with 4 sessions.

### Limits and good to know

- **Volumes are Google's rounded buckets** (for example 12,100, 40,500, 90,500), the same numbers the Google Ads
  Keyword Planner shows without an active campaign. Close variants (plural, word order) often share one figure.
- **Bids are in USD** for every country.
- **Countries only.** Cities, states and regions are not supported. An unknown country gives a free
  `INVALID_INPUT` row.
- **Keywords up to 80 characters and 10 words**, the Google Ads limit.
- In `exactOnly` mode, when Google Ads answers with related keywords but no row for the exact seed, the Actor uses a
  close variant (plural or word order) if there is one; otherwise you get a free `NO_DATA` row. The ideas mode shows
  what Google returned.
- Some sessions are refused and the Actor moves to a new one on another IP. If a request is refused on 3 different
  IPs you get a free `BLOCKED` row; run again.

### Pricing

Pay per keyword: **US$ 5.00 per 1,000 keywords** in the ideas mode and for website suggestions, **US$ 10.00 per
1,000** in the `exactOnly` mode (each exact row costs a full request to Google Ads), plus US$ 0.01 per run that gets
an answer. Lower on paid Apify plans. Error rows and duplicates across seeds are never charged.

### Error codes

| errorCode | Meaning |
|---|---|
| `INVALID_INPUT` | Unknown country, bad website URL, or a keyword over 80 characters or 10 words |
| `NO_DATA` | Google Ads has no volume for this keyword in this country |
| `BLOCKED` | The request was refused on 3 different IPs; run again, not charged |
| `NOT_REACHED` | The run timeout came before this keyword; raise the timeout or `maxConcurrency` |
| `UNEXPECTED` | Anything else; run again, and open an issue if it repeats |

### FAQ

**Do I need a Google Ads account or API key?** No.

**Is it the same data as the Keyword Planner?** It is Google Ads keyword data: average monthly searches in rounded
buckets, competition and the top of page bid range.

**Can I get monthly trends or 12-month history?** Not in this version.

# Actor input Schema

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

Seed keywords, one per line, for example web scraping, ai agents or best running shoes. Up to 80 characters and 10 words each, as Google Ads accepts them. Each seed is one request to Google Ads and returns average monthly searches, the last 12 months, competition and top-of-page bid range. Leave empty if you only want ideas for a website. Also accepts 'keyword', 'searchTerms' and 'queries'.

## `websiteUrl` (type: `string`):

Optional. A website or page address, for example https://apify.com. Google Ads reads the page and suggests up to 25 keywords for it, with volume, competition and bids, charged as 'Keyword delivered' like keyword ideas. Works with or without seed keywords.

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

Where the searches are counted: a country name in English (United States, United Kingdom, Germany, Brazil, Japan...) or its 2-letter code (US, GB, DE, BR, JP). Default United States. Countries only; cities and regions are not supported.

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

Keyword ideas (default): up to 25 keywords per seed (the seed itself plus related keywords), with 'isSeed' marking the seed row and duplicates across seeds removed, charged as 'Keyword delivered'. Exact keywords only: just the row of each seed keyword, to check the volume of a list you already have, charged as 'Exact keyword delivered' because each row is a full Google Ads request.

## `maxConcurrency` (type: `integer`):

Browser sessions working at the same time, from 1 to 5 (default 2), each on its own IP. Google Ads answers each session about once every 16 seconds, so 1 session reads about 3 to 4 seeds per minute and 4 sessions about 14. A second session only opens when there are more than 6 requests. Each session needs about 750 MB: the default 2 GB of run memory fits 2; use 4 GB for 5. The price per keyword is the same.

## Actor input object example

```json
{
  "keywords": [
    "web scraping",
    "ai agents"
  ],
  "country": "United States",
  "mode": "ideas",
  "maxConcurrency": 2
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `resultsCsv` (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": [
        "web scraping",
        "ai agents"
    ],
    "country": "United States"
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapewise/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": [
        "web scraping",
        "ai agents",
    ],
    "country": "United States",
}

# Run the Actor and wait for it to finish
run = client.actor("scrapewise/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": [
    "web scraping",
    "ai agents"
  ],
  "country": "United States"
}' |
apify call scrapewise/keyword-search-volume --silent --output-dataset

```

## MCP server setup

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