Apify Actors / Google Trends data without the 429 wall
Apify ActorGoogle Trends data without the 429 wall
Anyone who has tried to pull Google Trends at scale knows the pattern. A few requests work, then Google answers 429 with a consent cookie, and the run dies halfway through a list of keywords. This Actor handles that ladder for you. It retries with the cookie, then moves to a new proxy IP with growing backoff, and only gives up on a comparison after about 50 seconds of waiting.
One row per term per time bucket for interest over time, one row per region, and one row per related query. Comparisons work the way they do on the site. You get up to 5 terms per line, and the values are relative to the highest term in that comparison.
$0.001 per search term with data · pay per result, no subscription
Price
| Event | Price | Charged when |
|---|---|---|
| Term result | $0.001 | Once per search term per comparison that returns at least one row; covers interest over time, by region and related queries for that term |
| Example run | Units | Cost |
|---|---|---|
The prefilled input, coffee, tea in the US (258 rows in our run) | 2 terms | $0.002 |
| 100 single keywords, one per line, in 1 geo | 100 terms | $0.10 |
coffee, tea and bitcoin in US and GB | 6 term results | $0.006 |
What you get
- Interest over time as one row per date bucket, with
resolution(WEEK, DAY, MONTH) and relativevalue. - Interest by region with
regionCode,regionNameand the comparison share, down to state level for a country. - Top and rising related queries, off by default, one row each with the query text.
- Comparisons that behave like the site, with up to 5 terms per line and values relative to the strongest term in the group.
Input
Set the run options in the Apify console, or send the same object through the API.
{
"searchTerms": "coffee, tea",
"geo": "US",
"timeframe": "today 12-m",
"category": 0,
"property": "web",
"includeInterestByRegion": true,
"includeRelatedQueries": true
}The prefilled input. One comparison per line, comma separated, up to 5 terms. Rows are free; you pay only for terms that return data.
Output
{
"type": "interest_over_time",
"comparisonTerms": ["coffee", "tea"],
"term": "coffee",
"geo": "US",
"timeframe": "today 12-m",
"property": "web",
"date": "2025-11-02",
"resolution": "WEEK",
"formattedTime": "Nov 2 – 8, 2025",
"value": 68,
"hasData": true,
"isPartial": false
}One real interest_over_time row from the prefilled run (2026-11-05). The same dataset also holds interest_by_region rows and related_query rows; type tells them apart.
Run it from your own code
The Actor takes the same input as a JSON body. This call starts a run, waits for it and returns the dataset items.
curl -X POST "https://api.apify.com/v2/acts/zovo-one~google-trends-scraper-fast/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"searchTerms": "coffee, tea", "geo": "US", "timeframe": "today 12-m", "category": 0, "property": "web", "includeInterestByRegion": true, "includeRelatedQueries": true}'A sync call waits at most 300 seconds. For longer runs, start a run with POST /v2/acts/zovo-one~google-trends-scraper-fast/runs, wait for it, then read /v2/datasets/<defaultDatasetId>/items.
Limits
The hard caps per run are 5 terms per comparison, 50 geos and 500 comparisons. A term can be 100 characters. Bad input is rejected before any request, for example 6 terms on one line, UK instead of GB, or an end date in the future. Plan roughly 10 to 25 seconds per comparison at concurrency 1; 100 comparisons is 15 to 45 minutes, 500 is 1.4 to 3.5 hours. About 30 seconds before the timeout the Actor stops starting requests and lists the rest as skipped. Terms with a comma inside are not supported, because the comma separates terms.
Questions
Is there a Google Trends API I can call?
Google has no public Trends API for general use. The official alternative is the Trends website or a big-query export. This Actor gives you the same public data as JSON rows through the Apify API, which is what most people mean when they search for a Google Trends API.
Why do I get HTTP 429 from Google Trends?
Google rate-limits Trends per IP and often answers a new visitor with 429 plus a consent cookie. The Actor retries once with that cookie, then switches to a new proxy IP with 1 to 30 seconds of backoff. In one Apify run 6 of 13 requests were rate-limited and the run still finished in 24 seconds.
What happens if a comparison keeps failing?
It gives up after one retry ladder, about 50 seconds, and its other outputs are skipped. After 3 failed comparisons in a row the run stops with a clear message instead of burning your timeout. If that happens on Apify, pick the RESIDENTIAL proxy group and keep maxConcurrency at 1.
Are rising queries included?
They are off by default. Turn on related queries to get them. Rows with no data are free, and the OUTPUT record lists which comparisons were skipped and why.
How are the values scaled?
The same way as on the Trends site. Within one comparison, the strongest term at its peak is 100 and the other terms are relative to it. Comparing two runs with different term groups is not meaningful, which is why the comparison terms are repeated on every row.
Why does a weekly range start a few days early?
Google aligns weekly buckets to its own boundaries, so a range that starts mid-week can include a few extra days in the first bucket. Those rows have the partial flag where Google exposes it.
Support this work
If this Actor saves you time, you can support the work on GitHub Sponsors. Monthly tiers start at $5, and one-time tiers start at $15. Sponsorship is optional, and the tool works the same without it.
Related tools
Built and maintained by Zovo. Actor on Apify · All Actors.