You want Google Trends numbers in a script, not in a browser tab. Maybe it's a weekly check on demand for a product category, maybe it's comparing five brand names before a campaign. The first attempt usually ends with HTTP 429 Too Many Requests.

This post covers what your options actually are in late 2026, where each one falls short, and a working Python example. One of the options is a tool we built, so read the "when not to use it" section too.

The landscape, checked on 2026-10-31

1. The official Google Trends API (alpha)

Google announced a Trends API on 24 July 2025 (Search Central blog). As of 31 October 2026 its developer page still describes it as an alpha that is "accepting applications for alpha testers", with access limited to a selected group. Google says it prioritises applicants who know what they want to build, can start soon and will give feedback.

What it offers is interesting: a rolling five-year window, daily to yearly aggregation, region and sub-region breakdowns, and values that are not rescaled 0-100 per request, so you can compare more than five terms consistently.

Use it if you get in. It is the first-party source. If you need something today and you are not in the alpha, read on.

2. pytrends

pytrends was the default unofficial Python library for years. The repository was archived by its owner on 17 April 2025 and is now read-only. It still installs, and forks exist, but nobody is fixing the upstream package when Google changes the endpoints it relies on. If it works for you today, pin the version and expect to own the maintenance.

3. Hosted scraping services

Several services return Trends data over an HTTP API. Two families:

  • SERP API providers, for example SerpApi's Google Trends API (interest over time, by region, related queries and topics).
  • Apify Store Actors. A Store search for "google trends" returns several. On 2026-10-26, the two most-used ones listed a lower price per result than ours on their Store pages, and one also covers daily trending searches. Check each page; prices change.

Ours is Google Trends API & Scraper. It is built for a narrower job, described next.

What our Actor does, and does not do

One result is one search term, or one comparison group of up to 5 terms, with every section you asked for in a single record: interest over time, interest by region, related queries, and optionally related topics.

On rate limits, to be precise: it does not make 429s go away. Google limits how often Trends can be queried, and it limits shared cloud IPs most. When the Actor gets a 429, it waits as long as Google's Retry-After header asks, or backs off exponentially, up to 3 tries per term. If a term still fails, you get an error record with error_code: "rate_limited" and the HTTP status, and the run moves on. If two terms in a row are rate-limited, it stops asking and marks the rest as skipped. It does not rotate proxies or IPs.

Error records are free. You pay $5 per 1,000 results ($0.005 per result record) on every Apify plan, plus a $0.00005 start fee per run. error and summary records are not charged, and platform usage is included.

Hands-on: compare terms, export to CSV, pull related queries

You need an Apify account and an API token (Settings → API & Integrations). The code uses apify-client 3.x, where runs come back as objects (run.default_dataset_id); in older 1.x/2.x versions they were dicts (run["defaultDatasetId"]).

pip install "apify-client>=3" export APIFY_TOKEN=your_token_here 

Step 1: run a comparison

import os from decimal import Decimal from apify_client import ApifyClient client = ApifyClient(os.environ["APIFY_TOKEN"]) run_input = { "searchTerms": ["python", "javascript", "rust"], "compareMode": True, # one record, values scaled together "timeRange": "today 12-m", "geo": "US", "interestOverTime": True, "interestByRegion": True, "relatedQueries": True, } run = client.actor("reliable-apps/google-trends-reliable").call( run_input=run_input, max_total_charge_usd=Decimal("0.10"), # hard cap for this run ) if run is None: raise SystemExit("Run did not finish") items = list(client.dataset(run.default_dataset_id).iterate_items()) results = [i for i in items if i["type"] == "result"] errors = [i for i in items if i["type"] == "error"] for err in errors: print(f"{err['searchTerm']}: {err['error_code']} ({err.get('http_status')})") 

Every item has a type: result, error or summary. Always check errors before you trust a chart. A missing term is a visible record, not a silent gap.

Step 2: interest over time to CSV

In a comparison, each point holds one value per term under values, keyed by the term. That maps cleanly to a long-format CSV, which pandas, Sheets and most BI tools read without fuss.

import csv with open("interest_over_time.csv", "w", newline="", encoding="utf-8") as f: writer = csv.writer(f) writer.writerow(["group", "time", "term", "value", "is_partial"]) for rec in results: iot = rec.get("interestOverTime") or {} for point in iot.get("points", []): for term, value in point["values"].items(): writer.writerow([ rec["searchTerm"], point["time"], term, value, # None means Google has no data for that point point["isPartial"], ]) 

Two details worth knowing. The last point can have isPartial: true while the period is still running, so drop it before computing week-on-week changes. And values are Google's relative 0-100 index, not search counts.

Step 3: related queries

relatedQueries is keyed by term, each with a top and a rising list.

for rec in results: for term, lists in (rec.get("relatedQueries") or {}).items(): print(f"\nRising for {term!r}:") for q in lists.get("rising", [])[:5]: print(f" {q['query']:<40} {q['formattedValue']}") for warning in rec.get("warnings", []): print("warning:", warning) 

If Google does not return a section, the record says so in warnings instead of handing you an empty list that looks like real data.

Step 4: schedule it

For a weekly time series, create a Schedule in the Apify Console with the same input, and read the latest run's dataset from your pipeline. Keep batches small: a handful of terms per run is far less likely to hit rate limits than a few hundred.

When not to use it

  • You need hundreds or thousands of terms per day. The Actor sends at most one request per second and stops on repeated 429s. It is built for tracking a known list, not bulk research. A provider that sells volume will suit you better.
  • You are in the official alpha. Use Google's API. It is first-party and avoids the 0-100 rescaling problem.
  • You need daily trending searches ("Trending Now"). We do not collect them.
  • You want the cheapest price per result. On 2026-10-26 other Store Actors listed lower prices. Ours trades price for one-record-per-term output and explicit, free error records.
  • You need absolute search volume. Trends data is relative. No Trends tool gives you volume, whatever the label says.

Responsible use

  • The Actor checks Google's robots.txt on every run and only calls the Trends data paths it allows (/trends/api/...), never the /explore pages.
  • No proxy rotation, no headless browser, no faked fingerprints. A captcha, a consent wall, a 401 or a 403 stops that term with no retry, and the run skips the rest.
  • Trends data is aggregated and anonymised. It contains no personal data.
  • You are still responsible for complying with Google's terms and the law where you work. Treat Trends as a sampled, relative signal.

Links

Not affiliated with Google. Public data only. No logins, no personal data, no captcha or block bypass.

Written with AI assistance and reviewed by the author. These tools are built and maintained by an AI team. Vasilis Linakis owns them and is accountable for them.