I was building a small keyword research script and asked a keyword data API for 80 long-tail ideas around "running shoes", sorted by search volume. The top of the list looked like this:
sneaker running shoes 301,000
running on shoes 301,000
shoes running 301,000
running and shoes 301,000
running with shoes 301,000
shoes for running 301,000
runners running shoes 301,000
Seven "ideas", one number. It is the same keyword seven times.
Why this happens
Google Ads does not report search volume per exact wording. It groups close variants together (reordered words, plurals, filler words like "for" and "with") and reports one figure for the whole family. Every tool that resells Google Ads data inherits this.
The data provider then returns each member of the family as its own row. So a "list of 80 keywords" is really a much shorter list, repeated.
I checked how much shorter. Two rows belong to the same family when all their Google Ads figures match: same volume, same cost per click, same competition, and the same twelve months of history. Grouping my 80 rows that way gave:
| Family | Rows |
|---|---|
| running shoes (the seed itself) | 12 |
| on running shoes | 8 |
| nike running shoes | 31 |
| trail running shoes | 18 |
| brooks running shoes | 5 |
| stability running shoes | 4 |
| two single keywords | 2 |
80 rows, 8 distinct keywords. And one of the 8 was the seed I started from.
If you pay per result, or if you hand this list to a writer or an LLM, nine tenths of it is noise.
How to fix it yourself
If you already pull keyword data from an API, the fix is a few lines.
1. Build a signature per row from the figures Google reports:
import json
def signature(row):
info = row["keyword_info"]
return json.dumps([
info["search_volume"],
info["cpc"],
info["competition"],
[m["search_volume"] for m in info["monthly_searches"][:12]],
])
Matching on volume alone is not enough. Google rounds volumes into buckets, so "nike running shoes" and "trail running shoes" can both show 165,000 while being different keywords. Their cost per click and monthly history differ, which is what separates them.
2. Group rows by signature and keep one per group. Picking which one matters, or you end up showing "shoes running" instead of "running shoes". What worked for me, in order: prefer a wording that contains the seed phrase intact, then the shortest one.
3. Drop the group that contains your seed. It is not an idea.
4. Ask for more rows than you need. With roughly ten rows per family, getting 100 real ideas means fetching around 1,000 rows.
Or use the version I packaged
I turned this into a tool: Keyword Ideas Generator on Apify. It does the grouping, returns one clean keyword per family, and lists the other wordings beside it.
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("spokentext/keyword-ideas").call(run_input={
"seedKeywords": ["running shoes"],
"maxResults": 10,
"maxKeywordDifficulty": 40,
})
for row in client.dataset(run.default_dataset_id).iterate_items():
print(f'{row["keyword"]}: {row["searchVolume"]}/month, difficulty {row["keywordDifficulty"]}')
For the same seed, the first results are now different keywords:
running shoes on: 201000/month, difficulty 27
nike running shoes: 165000/month, difficulty 34
trail running shoes: 165000/month, difficulty 3
asics novablast 5 running shoes: 165000/month, difficulty 1
brooks running shoes: 165000/month, difficulty 12
Each row also carries cost per click, advertiser competition, search intent, and a closeVariants field with the wordings that were merged into it. You can filter by minimum volume and maximum difficulty before paying, and choose between long-tail ideas (containing your seed) and related ideas (same topic, different words).
It costs $0.006 per idea plus $0.03 per search, so 100 ideas for one seed is $0.63.
What it does not do
- It needs a paid Apify plan. Every search is bought from a data provider, so the free plan returns labelled sample rows only.
-
The pick is not always perfect. In the output above, "running shoes on" is the brand On, which people type as "on running shoes". The merged wordings are in
closeVariants, so you can see what was grouped. - Country level, Google only, with data refreshed monthly.
- No brand-new topics. Ideas come from keywords people already search for.
The takeaway
Whatever tool you use, check your keyword lists for repeated volumes before acting on them. If twenty rows share the same number, you have one keyword, not twenty.
Disclosure: I built the tool described above. This article was drafted with AI assistance and checked by me.
Top comments (0)