# Keyword Ideas Generator — Keyword Research, Volume & CPC (`steadyfetch/keyword-ideas-scraper`) Actor

Keyword ideas from your seed keywords — search volume, CPC, competition, keyword difficulty and search intent for every idea, in 94 countries. From $2.00 per 1,000 ideas plus a $0.19 lookup per 1,000; a seed list with no ideas is never charged.

- **URL**: https://apify.com/steadyfetch/keyword-ideas-scraper.md
- **Developed by:** [Steadyfetch Team](https://apify.com/steadyfetch) (community)
- **Categories:** SEO tools, Agents, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 keyword ideas

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 Ideas Generator — Keyword Research, Volume & CPC

**Keyword ideas from your seed keywords, with the numbers to pick between them.** Give it one seed or
a list and get back new keyword ideas, one row each: monthly search volume, CPC and the top-of-page bid
range, competition, keyword difficulty (0–100), search intent, and the 12-month search series with its
trend — in 94 countries. A seed list with no ideas is never charged.

**Using an AI agent?** Pin this actor in Apify's MCP server with one link: `https://mcp.apify.com?tools=steadyfetch/keyword-ideas-scraper`

- **Actor id:** `steadyfetch/keyword-ideas-scraper`
- **Input:** `{ "keywords": ["coffee grinder"] }` — the one field you have to set. Add `"maxResults": 500` for more ideas.
- **Cap the bill:** set `maxTotalChargeUsd` on the run (a run option, not Actor input), e.g. `0.50` — the run stops when it reaches it, and never buys ideas it cannot sell you.
- **How often it changes:** keyword data refreshes about once a month, so the same seeds asked again inside 30 days are the same ideas — your account gets those back with nothing charged (`repeat: true`) and no lookup fee.
- **Run it on a schedule:** save your input as a Task and run it monthly on an Apify Schedule; each month buys the fresh list.

If it earned its keep, a rating helps other buyers find it, and saving the actor keeps it one click away.

**See a real run before you spend anything:** [sample dataset](https://api.apify.com/v2/datasets/vpaf4VnpCE2vbJqJG/items?clean=true\&format=json) — ten ideas for the seed "home coffee roaster" in the United States from one verified run, unedited, with the run's own summary row last: ten ideas delivered and charged, plus one lookup.

**Just want to see it work?** Click **Start** with nothing set and the run gets ten keyword ideas for the
example seed "coffee grinder" in the United States, charged like any run. Pick a country or a limit but
set no seeds and that same sample runs under your settings, with one uncharged note row; a limit above
ten is capped at ten. Put your own seeds in **Seed keywords** for your own run.

*Unofficial. This actor is not affiliated with, endorsed by, or sponsored by Google. "Google" is a
trademark of Google LLC, used here only to describe where search data comes from.*

### What you get

One row per keyword idea:

```json
{
  "keyword": "burr coffee grinder",
  "seed": "coffee grinder",
  "seedKeywords": ["coffee grinder"],
  "rank": 8,
  "searchVolume": 18100,
  "cpcUsd": 0.84,
  "competition": 1,
  "competitionLevel": "HIGH",
  "lowTopOfPageBidUsd": 0.39,
  "highTopOfPageBidUsd": 0.79,
  "keywordDifficulty": 7,
  "searchIntent": "transactional",
  "otherIntents": [],
  "monthlySearches": [{ "year": 2026, "month": 8, "searchVolume": 9900 }, { "year": 2026, "month": 7, "searchVolume": 9900 }],
  "trendMonthlyPct": 0,
  "trendQuarterlyPct": 0,
  "trendYearlyPct": -55,
  "wordCount": 3,
  "avgBacklinksTop10": 56.6,
  "avgReferringDomainsTop10": 15.2,
  "dataUpdatedAt": "2026-09-13 04:57:38 +00:00",
  "country": "US",
  "language": "en",
  "charged": true,
  "repeat": false
}
```

| Field | What it is |
|---|---|
| `keyword` | The keyword idea. |
| `seed` / `seedKeywords` | The seed it came from. All seeds are expanded together into one list and the source does not say which seed produced which idea, so `seed` is filled only when the run had one seed; `seedKeywords` always lists them. Run one seed at a time when you need every idea tied to its seed. |
| `rank` | The idea's position in the list, in the order you chose (`sortBy`). |
| `searchVolume` | Average monthly searches over the last 12 months. |
| `cpcUsd`, `lowTopOfPageBidUsd`, `highTopOfPageBidUsd` | Cost per click and the top-of-page bid range, in USD. |
| `competition`, `competitionLevel` | Advertiser competition, 0–1, and LOW / MEDIUM / HIGH. |
| `keywordDifficulty` | 0–100: how hard it is to rank in the top 10 organic results. |
| `searchIntent`, `otherIntents` | informational, navigational, commercial or transactional — the main one and any others. |
| `monthlySearches`, `trend*Pct` | The 12-month series, newest first, and the change over 1, 3 and 12 months in percent. |
| `avgBacklinksTop10`, `avgReferringDomainsTop10` | How many links the pages ranking in the top 10 hold, on average — a second read on difficulty. |
| `dataUpdatedAt` | When the source last refreshed this idea's figures. |
| `charged`, `repeat` | Whether this row was billed, and whether it was handed back from your account's earlier delivery. |

A figure the source does not publish comes back `null` — never invented. Rows with a `missReason` are
uncharged notes saying why something was not delivered, and the last row (`_summary`) is the run's
uncharged receipt. Results may change when the source changes; anything not delivered is never charged.

### Settings

| Setting | Field | Default |
|---|---|---|
| Seed keywords | `keywords` | — (a bare Start runs the sample) |
| Country | `country` | `US` — 94 countries; codes, names and `en-GB`-style tags all work |
| Language | `language` | the country's main language; each country offers its own (US: English or Spanish) |
| Max keyword ideas | `maxResults` | 100, up to 5,000 |
| Sort ideas by | `sortBy` | `relevance`; also `search_volume`, `keyword_difficulty` (easiest first), `cpc` |
| Minimum search volume | `minSearchVolume` | none |
| Maximum keyword difficulty | `maxKeywordDifficulty` | none |

The two filters run at the source, so an idea outside them is never delivered or charged. The sort
decides which ideas a limit keeps: `relevance` follows the source's own relevance to your seeds, which
can include broader neighbours of the seed; sort by `search_volume` for the biggest ideas or by
`keyword_difficulty` for the easiest ones.

### Pricing

Pay per event, all-inclusive — no platform-usage charge on top, and no start fee.

| Event | Apify free plan | Bronze | Silver | Gold and above |
|---|---|---|---|---|
| Keyword idea (per idea delivered) | $0.008 | $0.006 | $0.004 | $0.002 |
| Fresh lookup (per request of up to 1,000 ideas) | $0.19 | $0.19 | $0.19 | $0.19 |

A run of 100 ideas is one lookup: $0.39 on Gold, $0.99 on the Apify free plan. 1,000 ideas is still one
lookup; 5,000 is five. Set the run's maximum total charge to at least **$0.25** — one lookup plus a few
ideas — and the run asks only for the ideas that cap can pay for.

**Never charged:** a seed list the source lists no ideas for (no lookup fee either), a request the source
refuses or cannot answer, and an ask your account already received in the last 30 days. A seed made of
emoji, control characters or no letters or digits at all is not sent: it gets its own uncharged row and
the other seeds run. When your search-volume or difficulty filter leaves nothing, the row says so and
names the filter.

### You are never charged twice for the same ask

Every ask — the seed list, the country, the language, the sort and the filters — is remembered for
30 days in a key-value store called `kw-ideas-account` in your own Apify account, with the ideas it
delivered. Ask the same thing again inside 30 days and those ideas come back with `repeat: true`,
`charged: false` and no lookup fee. Ask for more than you had and only the extra ideas are looked up and
charged. Delete the store to buy a fresh list sooner.

### Limits are hard limits

`maxResults` and your maximum total charge stop the run exactly where they bind; the run still finishes
successfully and the last row says what was delivered and what stopped it. A time limit ends the
collecting, never the delivering: ideas a request already returned are always delivered. A run never
works past 30 minutes.

On the Apify free plan, one fresh lookup per account in any 24 hours is included; past it the run stops
with one uncharged row saying when it resets. Paid Apify plans carry no daily allowance.

### Steadyfetch keyword tools

| You want | Actor |
|---|---|
| Monthly search volume and CPC for a keyword list you already have | [Keyword search volume & CPC](https://apify.com/steadyfetch/keyword-search-volume-scraper) |
| New keyword ideas from a seed, with volume, CPC and difficulty | **this actor** |
| Autocomplete suggestions across 5 engines | [Autocomplete keywords](https://apify.com/steadyfetch/google-keyword-suggest-scraper) |
| Rising and Breakout queries with the growth number | [Breakout keywords](https://apify.com/steadyfetch/breakout-keywords-scraper) |
| Interest over time, by country | [Google Trends](https://apify.com/steadyfetch/google-trends-scraper) |

### Feedback & support

Found an issue? Open it on the **Issues tab** — we usually reply within a couple of hours, always within a day.

# Changelog

This Actor's version history is a separate document: https://apify.com/steadyfetch/keyword-ideas-scraper/changelog.md

# Actor input Schema

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

The seed keywords to get keyword ideas for, e.g. \["coffee grinder"] — up to 200 per run, one per line, each up to 80 characters. Ideas come back as one list for all the seeds together; with a single seed every row names it in `seed`. Leave it empty and the run is a 10-idea sample for "coffee grinder", charged like any run.

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

The country to get keyword ideas for — pick one, or type a code or name (US, USA, United Kingdom, en-GB). 94 countries are covered; one country per run.

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

The language of the keyword ideas — a code or name (en, es, German). Leave empty for the country's main language; each country offers its own languages (the United States: English or Spanish).

## `maxResults` (type: `integer`):

How many keyword ideas to deliver, at most, a whole number, e.g. 500 — 100 by default, up to 5,000. Each request returns up to 1,000 ideas, so 1,000 ideas is one lookup and 5,000 is five. Ask for more and the run continues at 5,000, with one uncharged row saying so.

## `sortBy` (type: `string`):

The order the ideas come back in, which also decides which ideas a limit keeps: "relevance" to your seeds (default), "search_volume" (highest first), "keyword_difficulty" (easiest to rank for first) or "cpc" (highest first).

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

Only ideas searched at least this many times a month, a whole number, e.g. 100. The filter runs at the source, so ideas below it are never delivered or charged.

## `maxKeywordDifficulty` (type: `integer`):

Only ideas with a keyword difficulty (0-100, how hard the first page of results is to rank on) at or below this, a whole number, e.g. 30. The filter runs at the source, so harder ideas are never delivered or charged.

## Actor input object example

```json
{
  "keywords": [
    "coffee grinder"
  ],
  "country": "US",
  "maxResults": 100,
  "sortBy": "relevance"
}
```

# Actor output Schema

## `ideas` (type: `string`):

One row per keyword idea: search volume, CPC and the top-of-page bid range in USD, competition, keyword difficulty (0-100), search intent, the 12-month series and its trend. A figure the source does not publish is null, never invented. Every row carries `charged`: only rows with charged = true were billed (plus one keyword-lookup per request that delivered ideas). A row with repeat = true is an idea your account already received for the same seeds, market and settings within 30 days, handed back with charged = false. Seeds are expanded together, so `seed` names the seed only when the run had one; `seedKeywords` always lists them. Rows with a missReason are uncharged notes saying why something was not delivered.

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

Ideas delivered, ideas handed back from your account, what was charged, and what stopped the run.

# 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": [
        "coffee grinder"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadyfetch/keyword-ideas-scraper").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": ["coffee grinder"] }

# Run the Actor and wait for it to finish
run = client.actor("steadyfetch/keyword-ideas-scraper").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": [
    "coffee grinder"
  ]
}' |
apify call steadyfetch/keyword-ideas-scraper --silent --output-dataset

```

## MCP server setup

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

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/zAoenXm3fLX53PnSK/builds/sqbQSEBA9n8bBLLaE/openapi.json
