Google Trends Scraper & API: Interest, Related, Trending
Pricing
from $1.50 / 1,000 results
Google Trends Scraper & API: Interest, Related, Trending
Reliable Google Trends data: interest over time, interest by region, related queries and topics, and Trending Now. Pay-per-event, no browser, partial results still succeed.
Pricing
from $1.50 / 1,000 results
Rating
0.0
(0)
Developer
Sunburst
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
13 hours ago
Last modified
Categories
Share
Get Google Trends data (interest over time, interest by region, related queries and topics, and Trending Now) as clean JSON or CSV, without a browser. It talks to the same public JSON endpoints the Trends website uses. There is no browser, so there is no page-load timeout to abort the run.
Built to be a drop-in alternative to existing Store Actors: the familiar searchTerms, isMultiple, timeRange, geo, category, and startUrls fields still work. Failed widgets become error rows. The run still finishes SUCCEEDED.
Why this Actor
Google Trends does not offer a public official API. The old Python library most tutorials recommend, pytrends, is archived. Browser-based scrapers stall on 429s and timeouts. This Actor is the opposite of that:
- Direct endpoints.
GET /trends/api/explorefor tokens, then onewidgetdatacall per chart. Trending Now uses the currentbatchexecuteRPC (i0OFE), with the public RSS feed as fallback. - Retries that do not kill the run. Exponential backoff with jitter, NID cookie warmup, request pacing, and per-widget retry. A missing related-topics block does not throw away the timeline you already paid to fetch.
- Cheap to run. No Chromium. Default 512 MB. Uses the automatic Apify Proxy. You are billed $0.02 per run and $0.0015 per successful dataset row. Failed items are free.
- Store-test friendly. The default input (
bitcoin, US, past 12 months) returns non-empty interest-over-time and related-queries rows in seconds.
What you get
| Data type | Google Trends UI | Notes |
|---|---|---|
| Interest over time | Explore chart | Minute / day / week / month granularity follows the time range |
| Interest by region | Interest by subregion / city / metro | resolution: COUNTRY, REGION, CITY, DMA |
| Related queries | Top and rising | Returned in Google's own objects. Rising queries are decoy-filtered by default (see Rising queries and decoys) |
| Related topics | Top and rising | Requested; Google often returns an empty list to scripted clients |
| Trending Now | trending.google.com/trending | Country + 4h / 24h / 48h / 7d window |
Compare up to 5 terms per request. Many terms are batched automatically.
Input
Default (daily Store test)
{"searchTerms": ["bitcoin"],"timeRange": "today 12-m","geo": "US","property": "web","dataTypes": ["TIMESERIES", "GEO", "RELATED_QUERIES"],"outputMode": "perDataType"}
Compare terms on one scale
{"searchTerms": ["openai, anthropic, google gemini"],"isMultiple": true,"timeRange": "today 3-m","geo": "US","property": "youtube"}
Start from a Trends URL
{"startUrls": [{ "url": "https://trends.google.com/trends/explore?q=electric%20bike&geo=DE&date=today%2012-m" }]}
Trending Now only
{"fetchTrendingNow": true,"trendingSearchesCountry": "US","trendingSearchesTimeframe": "24","trendingSearchesMaxItems": 50}
Familiar fields (drop-in)
| Field | What it does |
|---|---|
searchTerms | List of keywords. Required unless you use URLs, a sheet, or Trending Now. |
isMultiple | Treat commas as comparison separators (max 5 per group). |
timeRange | now 1-H, now 4-H, now 1-d, now 7-d, today 1-m, today 3-m, today 12-m, today 5-y, all. |
customTimeRange | YYYY-MM-DD YYYY-MM-DD, overrides timeRange. |
geo | Country or region code. Empty = worldwide. |
category | Numeric Trends category id. Empty = all. |
property / gprop | web, news, images, youtube, froogle (Shopping). |
startUrls | Explore URLs; q / geo / date / cat / gprop win per URL. |
spreadsheetId | Public Google Sheet, first column, row 1 is the header. |
viewedFrom | Interface language (en-US). |
maxItems, maxConcurrency, maxRequestRetries | Accepted. Concurrency defaults to 1 on purpose. |
skipDebugScreen, pageLoadTimeoutSecs | Accepted and ignored (no browser). |
Extra fields this Actor adds
| Field | Default | What it does |
|---|---|---|
dataTypes | interest over time, region, related queries | Also RELATED_TOPICS, TRENDING_NOW. |
resolution | Auto | COUNTRY, REGION, CITY, DMA. |
outputMode | perDataType | combined for one nested row per term; flat for CSV. |
risingFilter | strict | strict, balanced, or off. Filters decoy rising queries. See Rising queries and decoys. |
fetchTrendingNow | false | Daily / real-time trending list. |
requestDelayMs | 350 | Pacing between Google calls. |
proxyConfiguration | Automatic Apify Proxy (useApifyProxy: true) | See Proxy. |
Output
perDataType (default) — one clean dataset row per term per widget:
{"dataType": "interest_over_time","status": "ok","searchTerm": "bitcoin","searchTerms": ["bitcoin"],"geo": "US","timeRange": "today 12-m","property": "web","itemCount": 53,"timeline": [{ "time": "1761436800", "value": [32], "formattedAxisTime": "Oct 26, 2025" }],"trendsUrl": "https://trends.google.com/trends/explore?q=bitcoin&geo=US"}
combined — one nested row per term, with the field names other Store Actors already emit:
interestOverTime_timelineData, interestOverTime_averages, interestBy / interestBySubregion / interestByCity / interestByMetro, relatedQueries_top, relatedQueries_rising, relatedTopics_top, relatedTopics_rising.
flat — one row per time point, region, or related item. Easy to open in Google Sheets. Billed per row, so a 5-year weekly series costs more than perDataType.
Error rows look like this and are not charged:
{"dataType": "related_topics","status": "error","errorCode": "NO_DATA","error": "related_topics_empty: Google returned an empty rankedList for RELATED_TOPICS.","searchTerm": "bitcoin"}
Pricing
Pay-per-event. You are not billed for platform compute on top of the event prices (standard PPE). Failed items are free.
| Event | Price | When |
|---|---|---|
apify-actor-start | $0.00005 | Once per run (Apify platform start event) |
run-start | $0.02 | Once per run |
result | $0.0015 | Each successful dataset row |
A typical one-keyword explore (timeline + region + related queries) is about $0.0246. See PRICING.md for compute/proxy cost and margin.
Set a max total charge on the run if you want the Actor to stop cleanly instead of overrunning a budget.
Proxy
Default: automatic Apify Proxy (useApifyProxy: true, no group selected). It works on all Apify plans, including Free, and was sufficient for Trends JSON in our test runs with paced requests.
The GOOGLE_SERP group is not the default. Apify documents it as HTTP-only access to www.google.com Search and Shopping. It cannot fetch trends.google.com. If you select it (or any group your plan cannot access), the Actor falls back to the automatic Apify Proxy, then to direct egress.
Residential proxies work and cost much more. Use them only if 429s persist after retries.
Locally, or on the platform without a proxy password, the Actor runs direct. From a clean VM that is enough for paced requests.
Reliability notes
- Cookie warmup on
trends.google.comto collect anNID. - GET explore (POST explore returned HTTP 500 in live checks).
- One widget call at a time, retried on 429 / 5xx with jittered backoff and proxy rotation.
- Partial success is still success. The dataset always has a row you can filter on
status. - Related topics are requested and often empty. That is a Google-side gap, not a timeout. Related queries still arrive.
Live test results (Apify platform, Oct 31, 2026, automatic Apify Proxy): 16 of 16 runs succeeded, including the default input, keyword comparison, interest by region, and related queries. Run times ranged from 2.3 s to 15.2 s. The default input finished in 6.4 s with 3 result rows.
Rising queries and decoys
Google labels every scripted Trends session USER_TYPE_SCRAPER (you can see it in the explore response as userConfig.userType). The widget token is signed over that label, so it cannot be changed: an edited request gets HTTP 401. Other Actors report the same label on residential IPs and in a real headless Chrome.
For sessions with that label, Google mixes decoy queries into the rising list of every keyword. They are generic phrases unrelated to your keyword, like "pet care tips", "how to cook pasta", "walmart near me", or "cheap flights 2024". Top queries, timelines, and regions match what a browser shows. This is not a parsing bug: the decoys are in Google's raw relatedsearches response.
Every related-queries row now includes:
googleUserType: the label Google put on the session.dataQualityWarning: a plain-language warning when the label isUSER_TYPE_SCRAPER.risingFilter: the filter mode used.rising: the rising queries that passed the filter.suspectedDecoys: removed entries, each withdecoyReasons(knownDecoy,repeatedAcrossKeywords,unrelatedToKeyword). Nothing is deleted.
risingFilter modes:
| Mode | What it does |
|---|---|
strict (default) | Moves an entry if it is a known decoy, if it was rising for an unrelated keyword earlier in the same run, or if it shares no meaningful word with the keyword or its top queries. |
balanced | Moves only known decoys and cross-keyword repeats. Unrelated entries stay in rising with "unverified": true. Good for celebrity and news keywords, where real rising terms often share no words with the keyword. |
off | Google's raw rising list. |
An entry that contains your keyword is never treated as a known decoy, so pasta still gets "how to cook pasta". In flat mode, decoy rows are left out, which means they are not billed, and a note gives the count. Treat rising queries as directional. Top queries are the more reliable list.
Live example (coffee, US, past 12 months, Oct 31, 2026): Google returned 25 rising queries. strict kept 8 that mention coffee and moved 17, including "pet care tips", "learn programming", and "best laptops 2025".
Comparison to other Google Trends Actors
This is not a teardown of anyone else's work. It is a checklist of what to look for:
| This Actor | Browser-based scrapers | Lightweight keyword/trending Actors | |
|---|---|---|---|
| How it fetches | Public JSON endpoints | Headless Chrome | Mixed |
| Typical failure mode | Empty related-topics list | Timeouts, aborts, 429s | Missing widgets |
| Compare 5 terms | Yes | Yes | Sometimes one keyword |
| Trending Now | Current RPC + RSS fallback | Page scrape | Often the main product |
| Default output | One row per data type | One nested row | Custom shapes |
| You pay | $0.02 + $0.0015/row | Events and browser compute | Similar PPE, usually higher |
If you already have a Make/Zapier/API task pointed at another Actor, start with outputMode: "combined" and the same searchTerms / timeRange / geo. Then switch to perDataType if you want cleaner billing.
FAQ
Is there an official Google Trends API? Google has announced a limited official API with access by application. This Actor reads the public Trends website endpoints that any logged-out browser already calls.
Are the numbers search volumes?
No. 100 is the peak within the selected terms, geo, and time range. Use Trending Now's searchVolume field for Google's trending-bucket estimate, not for SEO volume.
Is scraping Google Trends legal? You get publicly visible data. You are responsible for how you use it. Review Google's Terms of Service and your local law before large jobs.
Why did rising queries include unrelated things like "how to cook pasta"?
Google adds them on purpose for automated sessions. See Rising queries and decoys. The default risingFilter: "strict" moves them to suspectedDecoys.
Why are related topics empty?
Google often returns rankedList: [] for the RELATED_TOPICS widget to non-browser clients. The Actor still records an uncharged error row so you can see it. Related queries are populated.
Will the daily default input stay green?
Yes, that is a design constraint. bitcoin + US + past 12 months + three widgets is well under 5 minutes and returns non-empty rows.
Can I run it locally?
python3 -m venv .venvsource .venv/bin/activatepip install -r requirements-dev.txt# uses storage/key_value_stores/default/INPUT.jsonpython -m srcpytestGOOGLE_TRENDS_LIVE_TEST=1 pytest tests/test_live.py
More actors from this developer
- PDF to Markdown: DOCX, PPTX, XLSX, OCR & RAG Chunks: PDF, DOCX, PPTX, XLSX and HTML to clean Markdown and RAG-ready chunks.
- Google News Scraper: Full-Text Articles to Markdown: Google News articles as Markdown and RAG chunks for any topic or company.
- Greenhouse, Lever, Ashby & Workable Jobs API: one clean jobs feed from company job boards, with salaries when posted.
- Website Screenshot & URL to PDF API (Bulk, Full Page): full-page and mobile screenshots (PNG, JPEG, WebP) and PDFs of any URL.
- Wayback Machine API: Snapshots & Archived Pages: every archived capture of a URL or domain, the snapshot closest to a date, and archived pages as Markdown.
Develop and publish
See PUBLISHING.md for Docker build and apify push steps. You do not need Apify credentials to run the unit tests or the live smoke against Google.
Changelog
See CHANGELOG.md.