# Keyword Research Tool — Ideas, Trend Interest & Seasonality (`northbell/keyword-research-tool`) Actor

Keyword ideas from Google autocomplete (optionally YouTube and Amazon), ranked by Google Trends interest on one shared scale, with trend direction, peak month and rising terms. Set a country and language. No login, no SEO-tool subscription.

- **URL**: https://apify.com/northbell/keyword-research-tool.md
- **Developed by:** [Northbell](https://apify.com/northbell) (community)
- **Categories:** SEO tools, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.60 / 1,000 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 Research Tool — Ideas, Trend Interest & Seasonality

Give it a topic — a seed keyword like `running shoes` — and get **keyword ideas from Google autocomplete** (optionally YouTube and Amazon), **ranked by Google Trends interest on one shared scale**, each with its **trend** (rising, flat or falling), its **peak month** and whether Google Trends lists it as **rising** for your topic. **$2 per 1,000 ideas**, no login, no API key, no SEO-tool subscription.

Run it again — or put it on a weekly schedule — and every idea also tells you **what changed since the last run**: its previous rank, how far it moved, and whether it is **new in the list**. Autocomplete and Google Trends only show you today; this keeps the earlier picture for you.

### What you get

Rows have a `type`: `idea` (one per keyword idea, best first), `summary` (one per seed, free) or `error` (free).

| Field | What it is |
|---|---|
| `seed`, `keyword` | your seed, and the idea. The seed itself is never an idea; every idea contains it |
| `rank`, `relativeInterest` | the rank by Google Trends interest, and the interest on the shared scale: the average weekly interest over the past 12 months, where the best idea of the seed is `100` and an idea that is half as searched is `50`. They are not search counts |
| `trend`, `changePct` | `rising`, `flat` or `falling`: the last 3 months against the 3 months before, and the change in percent (`rising` at +15% or more, `falling` at −15% or less) |
| `peakMonth`, `peakVsAverage` | the calendar month in which the idea was searched the most, and how much busier that month was than the year's average (`2.5` = two and a half times; `1` = no season at all) |
| `isRisingInTrends`, `risingLabel` | `true` when Google Trends lists the idea among the rising related queries of your seed, with Google's own label (`Breakout`, `+350%`) |
| `sources` | the search boxes that suggested it, e.g. `["google","youtube"]` |
| `wordCount`, `geo`, `language`, `observedAt` | words in the idea, the market asked, and when |
| `previousRank`, `rankChange`, `isNew` | the change since your previous run of the same seed (`null` on the first run). `rankChange` is positive when the idea moved up; `isNew` is `true` when it was not in the previous list |
| `note` | why an idea is not fully scored (see Notes); `null` on normal rows |

The `summary` row of each seed has `ideasFound` (all different ideas autocomplete gave that contain the seed), `ideasScored`, `ideasUnscored`, `anchor` (the idea that ties the Google Trends requests together, see How the ranking works; `null` when all ideas fit one request), `topRising` (up to 5 rising queries of the seed that contain it, each with `query`, `risingLabel`, `isBreakout`; `null` when Google Trends could not be read), `newIdeas` and `previousRunAt`. An `error` row has `seed`, `part` (`autocomplete`, `trends` or `trends-rising`) and `message`.

### Run it again and again

- **On a schedule** — save your input as a task and add a **Schedule**: the same seed keywords every week. Send each run to Google Sheets, Slack or email with an integration on the task.
- **Watch for changes** — Keep the same input on the schedule. Each run is its own dataset with the date it ran, so the series builds up run by run and you can compare one day with the last.
- **In bulk** — Put all your **Seed keywords** in one run.

### How the ranking works

1. **Ideas.** The seed and the seed followed by `a` to `z` are typed into the chosen autocomplete boxes. All suggestions are merged without duplicates; phrases that do not contain the seed are dropped. The best `maxIdeas` are kept: phrases that more sources suggest first, then the completions of the seed itself, then the best letter results.
2. **One shared scale.** Google Trends compares at most 5 phrases in one request and sets the busiest week of *that request* to 100, so values from two requests cannot be compared directly. The Actor reads the top 5 ideas in one request and makes the idea in the middle of them the **anchor**. Every further request holds the anchor plus 4 new ideas. How much the anchor changes in value between two requests is exactly how much their scales differ, so every request is converted to the first scale and all ideas end up comparable.
3. **Ranking.** Ideas are ranked by their average weekly interest over the past 12 months on that scale. `trend` and `peakMonth` are read from each idea's own weekly series.

Checked on 8 October 2026: five ideas from different requests were also compared directly in a single Google Trends request. Against the best of them, the shared scale gave 0.45, 0.22, 0.10 and 0.02 and the direct comparison 0.44, 0.22, 0.09 and 0.01.

### Use it for

- **SEO and content planning** — which long-tail phrases around a topic people search most, in order, and which are growing
- **Timing** — the month in which a topic peaks, for launches, ads and publishing calendars
- **Listings and ads** — phrases from YouTube and Amazon search boxes ranked by one Google Trends scale
- **Watching a niche** — schedule it weekly and filter on `isNew` or on `rankChange` to see ideas that just appeared or climbed

### Input

```json
{
  "seeds": ["running shoes", "trail running"],
  "sources": ["google", "youtube"],
  "maxIdeas": 25,
  "geo": "US",
  "language": "en"
}
```

- **`seeds`** — one topic per line, up to 20 per run. Write them in the language you set.
- **`sources`** — `google` (default), `youtube`, `amazon`. Amazon follows `geo` and covers US, GB, DE, FR, IT, ES, CA, JP, AU, MX, BR, NL, SE, PL, TR, AE, SA and SG; in another country Amazon is skipped with a free error row (or the run is refused when Amazon was the only source).
- **`maxIdeas`** — 1 to 100 per seed, default 25.
- **`geo`**, **`language`** — a two-letter country code (`US`, `GB`, `DE`, `JP`) and a language (`en`, `de`, `ja`, `pt-BR`).
- **`proxyConfiguration`** — Apify Proxy for Google Trends, on by default (see Notes).

What changed since the last run is remembered per seed, country, language, sources and ideas per seed in a named key-value store in your Apify account, so the second run of the same input already shows changes. Schedule it (Apify → Schedules) for a regular history.

### Pricing

**$2 per 1,000 ideas** ($0.002 each), plus $0.01 per run. Only ideas that get a Google Trends score are charged: ideas Google Trends has no data for, `summary` rows and `error` rows are free. The $0.01 run-start fee is the one charge every run pays, even one that returns nothing; put all your seeds in one run and you pay it once.

One seed with the defaults (25 ideas) costs $0.06 including the run fee. 100 ideas cost $0.21. Expect roughly 30 to 60 seconds per seed with 25 ideas: Google Trends is asked about one request every 1.5–2 seconds, five ideas in the first request and four more in each next one.

### Notes

- **Relative, not counts.** Google Trends gives interest relative to the busiest point, not the number of searches. There is no search volume and no keyword difficulty here. `relativeInterest` of different seeds, countries or runs belongs to its own scale (the best idea of each seed is 100), so compare ideas within one seed and one run; across runs use `rank` and `rankChange`.
- **Seasonality is one year.** `peakMonth` is the month with the highest average in the past 12 months, so a one-off event looks like a season. `peakVsAverage` tells how strong the peak is; near `1` there is no season. `trend` compares two 3-month windows, so an idea that peaked in spring reads `falling` in autumn — read it together with `peakMonth`. Both are left empty (`null`) for ideas with too little interest, and `changePct` is empty when the idea had no interest at all in the earlier window (`trend` is then `rising`).
- **Low volume.** Google Trends reports whole numbers. An idea whose busiest week stays below 5 of 100 next to the other ideas of its request is scored, but its rank is approximate, `trend` and `peakMonth` are `null` and `note` says so. An idea that Google Trends shows as zero next to the others (too little search volume in that country) is returned last, unscored (`rank` and `relativeInterest` are `null`, `note` says why) and is not charged.
- **Country.** Google Trends interest is measured in exactly the `geo` you give: the same ideas had different interest in the US, Germany, Japan and Britain when we compared them. Autocomplete uses `geo` and `language` as the market, and the lists differ by country (on 8 October 2026 autocomplete listed `for women`, `near me`, `on sale` first for `running shoes` in the US, `for men`, `near me`, `sale`, `adidas`, `under 500` in Britain and `for men`, `nike`, `japan`, `asics` in Japan), but Google also mixes in a few suggestions from the place the request comes from (a test from Japan got `cafe yokohama` for US, German and British `cafe`). Treat the ideas as a strong hint for the country, not an exact list of what people there type. Expansion uses the letters `a` to `z`, also for other languages.
- **Rising.** Google fills its rising list for a seed with a few unrelated phrases now and then (for `running shoes` we saw `laptop stand` and `air fryer`), so `topRising` keeps only phrases that contain your seed. `isRisingInTrends` matches an idea against Google's whole rising list ignoring word order, apostrophes and the words for/the/a/an/of (`running shoes for women` = `women's running shoes`), and, in Japanese, Chinese, Korean and Thai, ignoring spaces. Google lists a limited number of rising queries (18 in our test), so most ideas are `false`; `null` means the list could not be read.
- **Only what autocomplete suggests.** An idea that autocomplete does not suggest for the seed or `seed a`–`seed z` is never scored. If the list looks short or off, raise `maxIdeas` or add `youtube` and `amazon`. For a wider net of phrases without ranking, see the link below.
- **Proxy.** Google Trends answers HTTP 429 (rate limit) to most requests that come straight from cloud servers, so the Actor sends its Google Trends requests through **Apify Proxy (datacenter)** by default, which is part of your Apify plan; autocomplete is asked directly. Measured on Apify on 8 October 2026 with our Google Trends Scraper: without a proxy Google Trends answered 429 to every request, through Apify Proxy it answered every time. If you turn the proxy off and every idea comes back unscored, turn it back on.
- **When Google refuses.** A rate-limited or failed request is retried twice (after 5 and 10 seconds). Ideas whose request still fails are returned unscored with a free `error` row; after repeated refusals the run stops asking. If nothing at all could be scored, the run fails instead of finishing with unranked ideas, and your history from earlier runs is kept. Run it again later or with fewer ideas; after a long burst Google can refuse one connection for an hour or more.
- No personal contact data: a suggestion that is an email address or a phone number is dropped. Public data only: what anyone sees in the search boxes and on Google Trends without signing in.

To get **more phrases without ranking** (`a`–`z`, `0`–`9`, questions, Bing and DuckDuckGo), see [Keyword Suggestions from Autocomplete](https://apify.com/northbell/keyword-suggestions-autocomplete). For **regions, related topics and any period** of one keyword, see [Google Trends Scraper](https://apify.com/northbell/google-trends-tracker). To track **where pages rank on Bing** for your chosen keywords, see [Bing Search Rank Tracker](https://apify.com/northbell/bing-search-rank-tracker).

### For AI agents

`{"seeds": ["running shoes"], "maxIdeas": 10}` returns up to 10 `idea` rows ordered by `rank` (1 = the most searched idea) and one `summary` row. Rows have `type`: `idea`, `summary` or `error`. `relativeInterest` is 0–100 within the seed; `trend` is `rising`, `flat` or `falling`; `peakMonth` is an English month name. For a weekly watch run the same input on a schedule and filter on `isNew: true` or `rankChange > 0`. Only `idea` rows with a `rank` are charged.

# Actor input Schema

## `seeds` (type: `array`):

One topic per line, as you would type it into Google, e.g. running shoes. Each seed gets its own ranked list of ideas. Put all your seeds in one run: the run-start fee is charged once. Up to 20 per run.

## `sources` (type: `array`):

The search boxes whose suggestions become ideas. An idea that more than one of them suggests is listed first before Google Trends ranks the ideas. Amazon follows the country below and covers US, GB, DE, FR, IT, ES, CA, JP, AU, MX, BR, NL, SE, PL, TR, AE, SA and SG.

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

How many ideas to keep and rank for each seed (1 to 100). Only ideas that get a Google Trends score are charged. Every 4 more ideas add one Google Trends request, about 4 seconds.

## `geo` (type: `string`):

Two-letter country code, e.g. US, GB, DE, JP. Google Trends measures the interest in this country. Autocomplete uses it as the market, but Google also mixes in a few suggestions based on where the Actor runs, so treat the ideas as a hint for that country.

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

Language of the suggestions, e.g. en, de, ja, pt-BR. Write your seeds in this language.

## `proxyConfiguration` (type: `object`):

Google Trends answers HTTP 429 (rate limit) to most requests that come straight from cloud servers. Apify Proxy (datacenter, part of your Apify plan) is on by default and used for Google Trends only: in our test on 8 October 2026 every request through it was answered, and none without it. Autocomplete is asked directly.

## Actor input object example

```json
{
  "seeds": [
    "running shoes"
  ],
  "sources": [
    "google"
  ],
  "maxIdeas": 25,
  "geo": "US",
  "language": "en",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Keyword ideas ranked by relative interest, with trend direction, peak month and rising flag.

# 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 = {
    "seeds": [
        "running shoes"
    ],
    "sources": [
        "google"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("northbell/keyword-research-tool").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 = {
    "seeds": ["running shoes"],
    "sources": ["google"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("northbell/keyword-research-tool").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 '{
  "seeds": [
    "running shoes"
  ],
  "sources": [
    "google"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call northbell/keyword-research-tool --silent --output-dataset

```

## MCP server setup

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

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/od3eBF1PkHv8Z3ziw/builds/oQ4C0f1HeIkk5hrZm/openapi.json
