Google Keyword Planner only shows exact search volumes if you run an active ad campaign. Without one you get ranges like "1K–10K", which is useless for deciding which article to write first.
This post shows how to get exact monthly search volume, CPC, competition and keyword difficulty for a list of keywords from Python, then save it as a CSV you can sort. No Google Ads account, no OAuth app, no developer token.
What you need
- Python 3.9+
- An Apify account (the free plan includes $5/month of usage) and your API token from Console → Settings → API & Integrations
-
pip install apify-client(this post uses v3)
The data comes from the Keyword Search Volume Actor on Apify, which wraps a Google Ads–sourced keyword data provider and caches results for 30 days.
The script
import csv, os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
keywords = [
"crm software", "crm for small business", "free crm", "best crm",
"crm for startups", "simple crm", "crm app", "real estate crm",
"crm for nonprofits", "what is a crm",
]
run = client.actor("steady-scrape/keyword-search-volume").call(logger=None, run_input={
"keywords": keywords,
"location": "United States",
"language": "English",
"includeMonthlyTrend": True,
})
rows = list(client.dataset(run.default_dataset_id).iterate_items())
def trend(monthly):
"""Last 3 months vs the 3 before, as a % change."""
v = [m["searchVolume"] or 0 for m in sorted(monthly or [], key=lambda m: m["month"])]
if len(v) < 6 or sum(v[-6:-3]) == 0:
return None
return round(100 * (sum(v[-3:]) / sum(v[-6:-3]) - 1))
with open("keywords.csv", "w", newline="") as f:
w = csv.writer(f)
w.writerow(["keyword", "volume", "cpc_usd", "competition", "difficulty", "intent", "trend_3m_pct"])
for r in sorted(rows, key=lambda r: r.get("searchVolume") or 0, reverse=True):
if r.get("status") != "ok":
continue
w.writerow([r["keyword"], r["searchVolume"], r.get("cpc"), r.get("competition"),
r.get("keywordDifficulty"), r.get("searchIntent"), trend(r.get("monthlySearches"))])
print(f'{r["keyword"]:<24} {r["searchVolume"]:>8,} ${r.get("cpc") or 0:>6.2f} KD {r.get("keywordDifficulty")}')
Run it:
export APIFY_TOKEN=... # never commit this
python keyword_volume.py
trend_3m_pct compares the last three months with the three before. It's a quick way to spot keywords that are growing or fading without opening a chart.
Real output (US / English, data month 2026-09)
| keyword | volume | CPC | competition | KD | intent | 3-month trend |
|---|---|---|---|---|---|---|
| crm software | 201,000 | $37.13 | LOW | 59 | commercial | +5% |
| what is a crm | 22,200 | $15.63 | LOW | 70 | informational | +7% |
| free crm | 5,400 | $67.26 | MEDIUM | 38 | commercial | −28% |
| crm for small business | 4,400 | $51.28 | LOW | 31 | commercial | +59% |
| real estate crm | 4,400 | $37.34 | MEDIUM | 36 | commercial | −4% |
| best crm | 2,400 | $63.56 | MEDIUM | 35 | commercial | +9% |
| crm for nonprofits | 2,400 | $58.70 | MEDIUM | 35 | commercial | −4% |
| crm app | 1,300 | $44.41 | LOW | 58 | commercial | −9% |
| simple crm | 590 | $60.53 | MEDIUM | 33 | commercial | −12% |
| crm for startups | 390 | $95.77 | LOW | 10 | commercial | −8% |
Two things jump out that a "1K–10K" range would hide:
- "crm for small business" has 4,400 searches, a difficulty of 31 and is up 59% over three months. That's a much better first article than "crm software" (KD 59).
- "crm for startups" is tiny (390/month) but has the highest CPC ($95.77) and KD 10. Advertisers pay a lot for that click, so it's worth a page even at low volume.
competition is the Google Ads competition level (how many advertisers bid). It is not SEO difficulty. Use keywordDifficulty (0–100) for organic ranking.
What it cost
I ran exactly this 10-keyword list on Nov 1, 2026. At the free-plan list price:
- 1 live lookup for the run: $0.12 (skipped when every keyword is already in the 30-day cache)
- 10 keyword results × $0.003 = $0.03
- Actor start: $0.00005
Total: about $0.15 for 10 keywords, in 3.7 seconds. The fixed lookup fee is per run, so batch your keywords: 1,000 keywords in one run is about $3.12, not 100 × $0.15. Paid Apify plans get lower per-result prices.
Tips
- Pass
"location": "United Kingdom"(or another country) and"language"to get local volumes. The cache is per location and language. - Keywords are normalized and deduplicated by default, so "CRM Software" and "crm software " count once.
- Keep
includeMonthlyTrendon. The 12-month series is what makes seasonality and the trend column possible. - Rows with
statusother thanok(no data, invalid keyword) aren't billed as results. The script skips them.
Disclosure: SteadyScrape publishes the Actor used in this post. Numbers above are from a real run on Nov 1, 2026; volumes change monthly.
Top comments (1)
The '1K–10K is useless for deciding which article to write first' is the exact problem I've had with Keyword Planner. You can't prioritize with a range. Seeing the actual numbers (4,400 for 'crm for small business' vs. 201,000 for 'crm software') changes the decision completely.