# Keyword Search Volume & CPC API + Google Trends (`meridianlabs/keyword-search-volume`) Actor

Keyword search volume API from $3 per 1,000 keywords: monthly volume, CPC and competition (Google Keyword Planner figures, no Ads account needed), difficulty, intent and 12-month history, plus a Google Trends summary per keyword: rising or falling, seasonal, peak month. Failed lookups are free.

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

## Pricing

from $3.00 / 1,000 keyword metrics

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 + Google Trends** looks up **search volume, CPC, competition, keyword difficulty and search intent for hundreds of keywords in one run**, the same monthly figures Google's Keyword Planner shows, and adds a **Google Trends summary for every keyword**: is interest **rising or falling**, how it compares **year on year**, when it **peaks** and whether it's **seasonal**. Volume, trend and seasonality in **one row per keyword**. The input form is pre-filled, so the easiest way to try it is to click **Start**. A 5-keyword run costs $0.03.

![Keyword Search Volume + Google Trends result: monthly searches, CPC, keyword difficulty, Google Trends direction, seasonality and a 12-month sparkline per keyword](https://raw.githubusercontent.com/leewilliam200/meridianlabs-apify-assets/main/keyword-search-volume/keyword-search-volume-google-trends-result.jpg)

It's built for **SEO and content marketers**, **e-commerce and Amazon/Etsy/Shopify sellers doing product research**, **PPC managers** and **AI agents** who need keyword data for more than a handful of keywords, without a Semrush or Ahrefs subscription.

### What keyword data do you get?

For each keyword, Keyword Search Volume + Google Trends returns:

- 🔢 **Search volume** (`searchVolume`): average monthly searches over the last 12 months (Google Ads figure).
- 📅 **12-month search history** (`monthlySearches`): searches per month, oldest first, plus the volume change month on month, quarter on quarter and year on year (`searchVolumeTrend`).
- 💰 **CPC and competition** (`cpc`, `competition`, `competitionLevel`, `lowTopOfPageBid`, `highTopOfPageBid`): what advertisers pay per click in USD, and how contested the keyword is.
- 🧗 **Keyword difficulty** (`keywordDifficulty`, 0–100): how hard it is to rank in Google's top 10 organic results.
- 🎯 **Search intent** (`searchIntent`): informational, navigational, commercial or transactional.
- 📈 **Google Trends summary** (`trends`, optional, on by default) with the key numbers as separate, filterable fields:
  - momentum: rising, falling or stable over the last 13 weeks
  - change year on year
  - peak date, and "now" compared with the average
  - seasonality, e.g. *peaks every October*, including seasons across the new year such as November–January
  - a one-sentence plain-English summary

### Why use this keyword search volume tool?

- 🧩 **Volume + trend + seasonality in one row.** Search volume tells you how big a keyword is; Google Trends tells you where it's heading and when it peaks. Other keyword tools give you one or the other. Sort 500 keywords by volume and filter to "rising and seasonal in Q4" in one spreadsheet.
- ✅ **Keyword Planner figures.** Volumes, CPC and competition are Google Ads data (see *Data source* below). In our September 2026 test they matched Google Ads figures exactly on 175 of 175 keywords.
- 🚀 **Bulk by design.** Paste hundreds or thousands of keywords; volumes are fetched in bulk, and Trends lookups run in parallel.
- 🌍 **94 countries**, each with its main language pre-selected (or pick another, e.g. French in Canada).
- 💸 **Fair billing.** You pay per keyword. Failed lookups are free, the Trends part is only charged when it answers, and the run stops exactly at your maximum spending limit.
- 🤖 **AI-agent ready.** A documented output schema, a keyword table view and stable field names. It works from the Apify API, integrations (Make, Zapier, n8n, Google Sheets) and MCP clients.

### How do I check search volume for a list of keywords?

1. Enter your **keywords**, one per line (paste a whole list).
2. Choose the **country** (and a language, only if the country has several).
3. Keep **Add a Google Trends summary** on for trend and seasonality, or turn it off for volumes only ($3 per 1,000).
4. Click **Start**. Open the **Keyword table** view for one line per keyword, or export everything as JSON, CSV or Excel.

![Keyword Search Volume input form: a list of keywords, the country, and the Google Trends summary switch with its time range](https://raw.githubusercontent.com/leewilliam200/meridianlabs-apify-assets/main/keyword-search-volume/keyword-search-volume-input-form.png)

#### Can I get Google Keyword Planner data without a Google Ads account?

Yes. You don't need a Google Ads account, Google Ads API access or a running ad campaign: the Actor returns the monthly Keyword Planner figures (search volume, CPC, competition and top-of-page bids) for your list, plus keyword difficulty, search intent and the Google Trends summary.

### How much does it cost to get keyword search volume?

**$3 per 1,000 keywords for search volume and metrics, plus $3 per 1,000 for the Google Trends summary: $6 per 1,000 keywords with both. Failed lookups are free.**

| Event | Price | Charged when |
|---|---|---|
| Keyword metrics | $0.003 per keyword | The volume lookup answered, including keywords Google has **no data** for or **withholds** (see Limitations): the lookup ran and answered. |
| Google Trends summary | $0.003 per keyword | *Add a Google Trends summary* is on **and** the Trends lookup answered (including "too little Trends data"). |

- 🆓 **Free:** errors, invalid keywords, Trends lookups that fail, keywords Google has no search data for at all (their Trends lookup is skipped), and keywords skipped because the run reached your **maximum spending limit** or its **time limit**.
- Examples: 5 keywords with Trends = $0.03; 100 keywords = $0.30 volumes only or $0.60 with Trends; 1,000 keywords = $3 or $6.
- **Free to try:** Apify's free plan includes $5 of platform usage every month, which covers about **1,650 keywords** volumes-only, or about **830 keywords** with the Google Trends summary. Platform usage is included in the price.
- Set a **maximum cost per run** in the run options and the Actor stops exactly there. Keywords it didn't reach are listed as `skipped` and not charged.

### Input

| Field | What it does |
|---|---|
| `keywords` | Search terms, one per line. Duplicates are removed. Google Ads limits: 80 characters and 10 words per keyword. |
| `country` | Two-letter country code, e.g. `US`, `GB`, `DE`, `AU`, `CA` (94 countries). Used for both volume and Trends. |
| `language` | Optional: `en`, `fr`, `French`... Empty = the country's main language. |
| `includeTrends` | Add the Google Trends summary (default on, +$0.003 per keyword). |
| `trendsTimeRange` | Past 90 days, Past 12 months, Past 5 years (default; needed for seasonality) or 2004 to present. |
| `maxConcurrency` | Trends lookups in parallel (1–10). |
| `failOnErrors` | Mark the run failed if any lookup errors (for schedules and monitoring). Failed lookups are still free. |

Example:

```json
{
  "keywords": ["air fryer", "standing desk", "halloween costumes", "pickleball paddle", "crm software"],
  "country": "US",
  "includeTrends": true,
  "trendsTimeRange": "past_5_years"
}
```

### Output example

Volumes, CPC and competition: Google Ads keyword data via DataForSEO (each row's `volumeDataSource`). Trends: data source: Google Trends (https://www.google.com/trends) (each row's `trends.dataSource`).

The **Keyword table** view on the Output tab gives one line per keyword:

![Keyword Search Volume Keyword table in Apify Console: monthly searches, Google Trends direction, seasonal peak, CPC, competition, difficulty, intent and year-on-year change per keyword](https://raw.githubusercontent.com/leewilliam200/meridianlabs-apify-assets/main/keyword-search-volume/keyword-search-volume-output-table.png)

One row per keyword (trimmed; real output from September 2026):

```json
{
  "keyword": "halloween decorations",
  "status": "ok",
  "country": "US",
  "language": "en",
  "searchVolume": 135000,
  "cpc": 0.85,
  "competitionLevel": "HIGH",
  "keywordDifficulty": 22,
  "searchIntent": "commercial",
  "searchVolumeTrend": { "monthlyPct": 82, "quarterlyPct": 507, "yearlyPct": 0 },
  "monthlySearches": [
    { "month": "2025-09", "searchVolume": 450000 },
    { "month": "2025-10", "searchVolume": 673000 },
    "...",
    { "month": "2026-08", "searchVolume": 246000 }
  ],
  "trends": {
    "status": "ok",
    "timeRange": "past_5_years",
    "text": "Interest is rising (+310% vs the previous 13 weeks); down 11% year on year. Peak: October 2021. Seasonal: peaks every October.",
    "momentum": "rising",
    "yearOnYearChangePct": -11,
    "peakDate": "2021-10-03",
    "seasonal": true,
    "seasonalPeakMonth": "October",
    "seasonalWindow": "September–November",
    "charged": true,
    "dataSource": "Google Trends (https://www.google.com/trends)"
  },
  "volumeDataSource": "Google Ads keyword data (Keyword Planner figures) via DataForSEO Labs, refreshed monthly. Not affiliated with Google.",
  "scrapedAt": "2026-09-25T08:58:13Z"
}
```

`status` is one of:

- `ok`: search volume returned.
- `no_data`: Google Ads has no volume for this keyword (`noDataReason`: `withheld` for restricted topics, `not_found` for keywords with too few searches). Charged, because the lookup ran and answered.
- `error`: the lookup failed; not charged.
- `skipped`: not looked up because the run hit its spending, time or data-cost limit; not charged.

### How to read the numbers

- **Search volume is a monthly average** over the last 12 months, rounded the way Google Ads rounds it (e.g. 8,100, 9,900, 12,100). Use `monthlySearches` to see the season.
- **Trends values are relative, not searches.** The Trends summary compares a keyword with its own past (100 = its peak in the range). Use volume for "how big", Trends for "which way and when".
- **Both come from the same country**, so a keyword's volume and trend describe the same market.
- **Volumes refresh monthly.** `volumeUpdatedAt` shows when the figure was last updated.

### How do I refresh keyword volumes every month?

Google Ads volumes update monthly, so a monthly schedule keeps a keyword list current:

1. Fill in the input (your keyword list and country) and click **Save as a new task**.
2. Open **Schedules** → **Create new**, pick the task and choose **monthly** (e.g. the 3rd of each month).
3. Each run adds a fresh dataset; send it to a spreadsheet or workflow (next section).

500 keywords a month cost **$1.50** volumes-only or **$3** with the Google Trends summary. Set **Fail the run if any lookup fails** on scheduled tasks so a failed run shows up in your run list and monitoring alerts. Failed lookups stay free.

### How do I send keyword data to Google Sheets, Make, Zapier, n8n or an AI agent?

- **Google Sheets and Drive:** on the Actor's or task's **Integrations** tab, add the Google Drive integration, or use Make, Zapier or n8n (below) with a Google Sheets "add rows" step.
- **Make, Zapier and n8n:** each has an official Apify app or node. Trigger on "Actor run finished", then get the dataset items. Ask for the `overview` view to get the Keyword table columns, one row per keyword.
- **Webhooks:** Integrations → **HTTP webhook** on "Run succeeded" sends the run details to your URL.
- **AI agents (MCP):** add `https://mcp.apify.com?actors=meridianlabs/keyword-search-volume` to your MCP client (Claude, Cursor, VS Code and others). The agent can then look up volumes, CPC and trends for any keyword list.
- **Code:** see the Python example in the FAQ below.

### Limitations

- **Google withholds volume for restricted topics.** Keywords in areas such as finance, health, legal, gambling, weapons or VPNs (e.g. *vpn*, *bitcoin price*, *car accident lawyer*, *baby names*) can come back as `no_data` with `noDataReason: "withheld"`. Keyword difficulty, intent and the Google Trends summary are usually still available for them.
- **Very new or very niche keywords** return `no_data` (`not_found`). That's Google's answer, not an error.
- **Country level only.** Volumes are per country, not per city or region.

### FAQ

#### Where does the search volume data come from?

Search volume, CPC and competition are **Google Ads (Keyword Planner) figures**, supplied by the licensed data provider DataForSEO (Labs database, refreshed monthly). Keyword difficulty and intent are DataForSEO estimates. The trend summary is computed from **Google Trends** data. This Actor is **not affiliated with or endorsed by Google**. Data source for trends: Google Trends (https://www.google.com/trends).

#### How is keyword search volume different from Google Trends?

Google Trends shows relative interest (0–100), not how many people search. This Actor gives you the absolute monthly search volume and the ad metrics, and adds the Trends direction and seasonality on top. If you only need Trends data (with regions and rising related searches), use our [Google Trends Scraper](https://apify.com/meridianlabs/google-trends-scraper).

#### Can I use it with AI agents, the API or MCP?

Yes. Run it through the Apify API or client libraries, schedule it, connect it to Make, Zapier, n8n or Google Sheets, or call it from MCP clients (see *How do I send keyword data…* above). All output fields are documented in the dataset schema.

Python (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("meridianlabs/keyword-search-volume").call(run_input={
    "keywords": ["air fryer", "standing desk"], "country": "US",
})
for row in client.dataset(run.default_dataset_id).iterate_items():
    print(row["keyword"], row.get("searchVolume"), row["trends"]["text"] if row.get("trends") else "")
```

#### How many keywords can I look up at once?

Thousands per run. Volumes come back in bulk in seconds; with Trends on, expect roughly 1–2 minutes per 100 keywords at the default 5 parallel lookups.

#### Does the Actor store anything in my account?

Yes, a small cache named `keyword-volume-cache` in your Apify key-value stores, so repeat lookups of the same keyword and country within 30 days are fast. You're charged the same either way. You can delete it at any time.

#### What happens if a run times out or restarts?

If a run approaches its timeout, the Actor stops starting new lookups: keywords whose volumes are already in hand are delivered without the Trends part (only the metrics are charged), and the rest are listed as `skipped` (not charged), so you can run them again. If the platform restarts a run, it picks up where it left off without charging twice.

### More from Meridian Labs

- **[Google Trends Scraper & API](https://apify.com/meridianlabs/google-trends-scraper)**: the full Google Trends data behind the summary (interest over time, by region, rising related searches) for hundreds of keywords, as a maintained pytrends alternative. $5 per 1,000 keyword lookups.
- **[Greenhouse, Lever & Ashby Jobs](https://apify.com/meridianlabs/greenhouse-lever-ashby-jobs-scraper)**: open jobs from companies on six hiring systems, with salary normalised to min, max, currency and period. $2 per 1,000 jobs.

### Support

Something looks wrong, or you need a field we don't return? Open an issue on the **Issues** tab with the input you used. We read every one.

If this saved you time, a rating helps others find it; if something's off, open an issue and we'll fix it fast.

# Actor input Schema

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

Search terms to look up, one per line (paste hundreds at once). Each keyword is one lookup. Duplicates are removed. Google Ads limits: up to 80 characters and 10 words per keyword.

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

Where the searches happen. Search volume and Google Trends both use this country.

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

Language code or name, e.g. en, fr or French. Leave empty for the country's main language. Only matters in multi-language countries (e.g. Canada: en/fr; Switzerland: de/fr/it; United States: en/es).

## `includeTrends` (type: `boolean`):

Adds momentum (rising / falling / stable), change year on year, peak and seasonality with a plain-English summary. Costs an extra $0.003 per keyword; only charged when the Trends lookup answers.

## `trendsTimeRange` (type: `string`):

Seasonality and year-on-year change need weekly data over more than a year: keep Past 5 years unless you need recent momentum only.

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

How many Google Trends lookups run at once. Search volumes are fetched in bulk regardless.

## `failOnErrors` (type: `boolean`):

Useful for schedules and monitoring: the run is marked failed if any keyword's volume or Trends lookup errors. Failed lookups are still not charged.

## Actor input object example

```json
{
  "keywords": [
    "air fryer",
    "standing desk",
    "halloween costumes",
    "pickleball paddle",
    "crm software"
  ],
  "country": "US",
  "includeTrends": true,
  "trendsTimeRange": "past_5_years",
  "maxConcurrency": 5,
  "failOnErrors": false
}
```

# Actor output Schema

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

One row per keyword: volume, CPC, competition, difficulty, intent and the Trends summary (dataset view 'overview').

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

Every field, including the 12-month search history and the full Trends summary.

# 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": [
        "air fryer",
        "standing desk",
        "halloween costumes",
        "pickleball paddle",
        "crm software"
    ],
    "country": "US"
};

// Run the Actor and wait for it to finish
const run = await client.actor("meridianlabs/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": [
        "air fryer",
        "standing desk",
        "halloween costumes",
        "pickleball paddle",
        "crm software",
    ],
    "country": "US",
}

# Run the Actor and wait for it to finish
run = client.actor("meridianlabs/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": [
    "air fryer",
    "standing desk",
    "halloween costumes",
    "pickleball paddle",
    "crm software"
  ],
  "country": "US"
}' |
apify call meridianlabs/keyword-search-volume --silent --output-dataset

```

## MCP server setup

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