Google Trends Scraper — Calibrated Keyword Comparison API avatar

Google Trends Scraper — Calibrated Keyword Comparison API

Pricing

Pay per event

Go to Apify Store
Google Trends Scraper — Calibrated Keyword Comparison API

Google Trends Scraper — Calibrated Keyword Comparison API

Compare Google Trends keyword portfolios beyond one request on a common calibrated scale, with uncertainty bounds and API-ready time-series data. One dataset record per keyword: raw series, calibrated series, bounds, anchor provenance.

Pricing

Pay per event

Rating

0.0

(0)

Developer

George Kioko

George Kioko

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

11 days ago

Last modified

Share

Compare Google Trends keyword portfolios beyond one request on a single calibrated scale, with uncertainty bounds and API-ready time-series data.

100 inputs are not necessarily 100 comparable values. This actor makes them comparable.

Google Trends never returns absolute search volume. Every request is normalized to its own 0–100 scale, where 100 = the biggest term in that request. Fetch two batches and the numbers cannot be compared:

Request A: [chatgpt, figma] Request B: [obsidian, miro]
┌──────────────────────────┐ ┌──────────────────────────┐
│ chatgpt ████████── 100 │ │ obsidian ████████── 100
│ figma █────────── 2 │ │ miro █████──── 57
└──────────────────────────┘ └──────────────────────────┘
│ │
└───────────────┬────────────────────────┘
Is obsidian's "100" bigger than figma's "2"?
── You cannot tell. Different requests,
different scales, no shared reference. ──

Send 100 keywords to an ordinary Google Trends API scraper and you get back 20 batches of 5, each on its own private scale. Ranking or charting them together is silently wrong.

How calibration fixes it

Every keyword is measured against an anchor — a term from a pre-built, versioned anchor bank whose terms were chained together through overlapping requests. Because each comparison shares a request with its anchor, the ratio between them is meaningful, and every keyword lands on one common scale:

ANCHOR BANK (built once, versioned, immutable)
┌────────────────────────────────────────────────────────┐
│ chatgpt ──── gmail ──── claude ai ──── cursor ai ──── │
1.00 0.31 0.09 0.02
│ └── ratios chained through shared terms ──┘ │
└────────────────────────────────────────────────────────┘
your keyword ───┤ one request: [your keyword, anchor]
ratio(keyword/anchor) × anchor's known position
┌───────────────────────────────────┐
│ keyword on the COMMON scale │
│ value: 3.57 bounds: [3.2, 4.0]
└───────────────────────────────────┘

What one run does

your keywords (120)
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────────┐
│ batch into │ │ Google Trends │ │ calibration engine │
│ groups of 4 │──▶ (US residential │──▶ │ + versioned anchor │
+ 1 anchor each │ │ proxy, retries) │ │ bank (KVS)
└─────────────────┘ └──────────────────┘ └──────────┬──────────┘
charged only on delivery ▼
┌──────────────────────────────────────────┐
ONE DATASET RECORD PER KEYWORD
│ raw series · calibrated series · bounds │
│ anchor used · bank revision · timestamp │
└──────────────────────────────────────────┘

Keywords that cannot be calibrated (too small to register, transport exhausted) are returned as diagnostic rows and never charged.

What data you get per keyword

  • keyword — your term, as sent
  • calibratedMax — peak interest on the common scale (comparable across ALL your keywords)
  • lo, hi — uncertainty bounds around the calibrated value
  • ratio — the keyword's position relative to the bank's reference term
  • calibratedSeries — weekly time series on the common scale (12 months)
  • rawSeries — the original 0–100 values Google returned
  • anchorUsed, bankRevision — full provenance: which anchor, which bank version
  • snapshotAt — when this measurement was taken

Output example (real run)

{
"keyword": "deepseek",
"ok": true,
"calibratedMax": 3.57,
"lo": 3.21,
"hi": 3.96,
"ratio": 0.0357,
"anchorUsed": "perplexity ai",
"bankRevision": 3,
"snapshotAt": "2026-08-03T06:31:12.000Z",
"calibratedSeries": [
{ "time": 1722643200, "value": 1.964 },
{ "time": 1723248000, "value": 2.107 }
]
}

Measured, not promised (audit of 2026-08-03)

We ran a public-methodology quality audit against the live actor before making any of the claims on this page. The numbers, all dated with run IDs logged:

Cross-anchor agreement 26/26 keywords (100%) — same keyword calibrated
through two independent anchors agreed within bounds
Bounds coverage 52/52 checks (100%)
Ground truth 10/10 clearly-separated rankings matched Google's
own same-request ordering
100-keyword workload 100/100 inputs returned exactly one row each
Billing reconciliation 41/41 audited runs: charges == delivered rows, exact
Bad-run rate 1 of 46 production runs (2.2%)
5-keyword run p50 26s · p95 77s · p95 cost $0.032
Snapshot stability 12 identical requests over 7.5h: median per-point
variation 0%, p95 2.9%

For context: the most-used Google Trends scraper on this store showed a 28.9% bad-run share (timed-out + aborted + failed) in its public run statistics when we measured it on 2026-08-02 across 21,682 runs. Sample sizes differ (46 vs 21,682 runs) — judge accordingly; our audit set grows with every scheduled soak run.

One defect was found by this audit and fixed the same day (a dataset-schema rule that crashed diagnostic rows). We publish what we find.

Use cases

  1. SEO keyword research at portfolio scale — rank 20 candidate topics on one scale instead of eyeballing separate Trends charts, before committing content budget.
  2. Brand share of search — measure your brand against competitors and category terms in a single comparable frame, with bounds that tell you when a gap is real.
  3. Product demand validation — compare niche product ideas whose volumes are too far apart to ever share one Google Trends request.
  4. SEO trend analysis pipelines — the calibrated series is API-ready JSON; feed it straight into dashboards, sheets, or your own models via the Apify API.

How to use

  1. Enter 1–20 keywords (defaults work for everything else).
  2. Run. A 5-keyword run typically finishes in 1–5 minutes.
  3. Read the dataset — one record per keyword, all on the same scale — or pull it via the Apify API / scheduled Tasks.

Keep the default proxy setting (US residential). Google Trends aggressively rate-limits datacenter IPs; the default exists because it is the configuration that works.

Use it from Claude, Cursor, or any MCP client

This actor works as a Google Trends MCP tool out of the box — no extra setup on the actor side. Add it to any MCP client through Apify's MCP server:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=george.the.developer/calibrated-google-trends-api",
"headers": { "Authorization": "Bearer YOUR_APIFY_TOKEN" }
}
}
}

Your AI assistant can then compare keyword portfolios on the calibrated scale as part of its own research — "compare search demand for these 15 product ideas" becomes one tool call. MCP clients connected to the general Apify server can also discover this actor dynamically via the server's call-actor tool.

Input parameters

ParameterTypeRequiredDescription
keywordsarrayyes1–20 keywords to calibrate onto one common scale
geostringno"" = Worldwide (default) or US
timeframestringnotoday 12-m (past 12 months, default)
categoryintegernoGoogle Trends category id, default 0 (all)
propertystringnoweb (default)
maxCostUsdintegernoHard cost cap; run is rejected without charge if the keyword count would exceed it (default 3)
proxyConfigurationobjectnoDefault: US residential via Apify Proxy — keep it

(mode and bankSpec are owner-only maintenance inputs for building anchor banks; runs from other accounts exit uncharged.)

Understanding the bounds

Google rounds every value to an integer, so a reported 2 means "somewhere between 1.5 and 2.5". Those rounding errors propagate through each calibration ratio — the bounds make that honest instead of hiding it:

reported value: 2
true value lies in: [1.5 ─────────── 2.5]
after calibration: value 3.57, bounds [3.21 ── 3.96]
Two keywords overlap in bounds? → treat them as tied.
Bounds clearly separated? → the ranking is real.

The same keyword calibrated through two different anchors agrees within these bounds — that is the correctness check the engine is built on.

Pricing

Pay-per-event. You pay for delivered results, not attempts:

  • Actor start: $0.00005
  • Calibrated keyword: $0.15 per successfully calibrated keyword persisted to the dataset

Uncalibratable keywords come back as diagnostic rows at no charge. The maxCostUsd input rejects over-budget runs before any work happens.

Limits (read this)

  • Google's API path accepts max 5 terms per request — that is why keywords are batched with an anchor, and why raw multi-keyword scrapers can't give you one comparable scale.
  • Launch catalog: Worldwide + US, past 12 months, web search, all categories. More dimension combinations ship as their anchor banks are built and validated.
  • Each run is a fresh snapshot of Google Trends at run time. Google's own sampling varies between snapshots; compare values within a run, and use the bounds when you do.
  • Very-low-volume keywords may flatline at zero on every anchor — those are reported as diagnostics, uncharged.

FAQ

Q: Why don't the numbers match what I see on trends.google.com? A: The Trends UI normalizes each chart to its own 0–100. This actor puts all your keywords on one shared scale instead — that is the entire point. The rawSeries field still gives you Google's original per-request values.

Q: What happens to keywords that fail? A: They come back as ok: false rows with a reason, and you are not charged for them.

Q: Why 20 keywords max? A: Each keyword costs real requests against an aggressively rate-limited Google endpoint. The cap keeps runs fast and predictable. Need more? Split into multiple runs — the shared anchor bank keeps results on the same scale within each run's snapshot.

Q: What is an anchor bank? A: A pre-measured chain of reference terms spanning several orders of magnitude of search volume, built through overlapping Trends requests and stored versioned + immutable. Every result records which bank revision measured it, so output is auditable.

Q: Can I schedule this? A: Yes — standard Apify Tasks + Schedules work. Each scheduled run is an independent snapshot with its own timestamp.

More actors by this developer

Support

Found a bug or need a dimension combination (another country, timeframe, or property)? Open an issue on the actor's Issues tab — supported combinations are prioritized by request.

If this actor saved you time, a short review on this page helps other developers find it.