# Google Trends Scraper & API (`symphonic_mullite/google-trends-scraper`) Actor

Google Trends API that actually works: interest over time, interest by region, related queries and topics for any keywords or explore URLs, plus trending-now searches. Cookie warm-up, retries, proxy rotation, no browser. Pay per result.

- **URL**: https://apify.com/symphonic\_mullite/google-trends-scraper.md
- **Developed by:** [Damian Boni](https://apify.com/symphonic_mullite) (community)
- **Categories:** SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 keyword results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Google Trends Scraper & API (that actually works)

Get **Google Trends data as clean JSON, CSV or Excel**: interest over time, interest by region (country, state, metro, city), related queries (top and rising) and related topics for any keyword, comparison or pasted Google Trends link. Plus **Trending now**: what people are searching for right now in any country, with search volume, news articles and pictures.

It uses Google Trends' own data endpoints over plain HTTP (no browser), so runs are fast and cheap, and it was built around one goal: **finish every run with data or a clear reason why not**. No endless loops, no "succeeded with 0 results", and you are never charged for a result that failed.

### What can this Google Trends scraper do?

- **Interest over time**: the 0-100 timeline (dates for daily/weekly data, date-times in your time zone for hourly and minute data), the partial last period flagged, plus average, peak and latest values.
- **Interest by subregion**: countries, regions / states, US metro areas (DMA) or cities (with coordinates). For comparisons you also get each term's share per location.
- **Related queries**: top and rising searches (including "Breakout"), with links.
- **Related topics**: top and rising topics, when Google provides them.
- **Comparisons**: up to 5 terms per comparison, as many comparisons as you like in one run.
- **Paste Google Trends URLs**: explore links keep their own terms, location, time range, category and search type.
- **Trending now**: the current trending searches for any country (or region such as US-CA), with approximate searches, when it started trending, related news and picture.
- Every **location**, **time range** (past hour to 2004-present, or custom dates), **category**, **search type** (web, image, news, YouTube, Google Shopping), **time zone** and **language** the Trends website offers.

### Why this Google Trends API is reliable

Most Google Trends scrapers break the same way: Google answers `429 Too Many Requests`, the scraper retries the same thing forever or finishes "successfully" with an empty dataset. This Actor is designed for exactly that:

- **Cookie warm-up**: every session first gets the cookie Google requires; without it the Trends API answers 429 to everyone.
- **Same data flow as the website**: explore request -> widget tokens -> widget data, the same calls the Trends website makes. Expired tokens are refreshed automatically.
- **Retries with exponential backoff and jitter**, and a **fresh session and IP on every rate limit**.
- **Global adaptive rate limiter**: slows down when Google pushes back, speeds up again when it doesn't.
- **Automatic proxies**: Apify datacenter proxies first, then an automatic switch to residential IPs if Google keeps blocking. You pay the same price per result either way.
- **Circuit breaker and hard deadline**: if Google blocks everything, the run stops early with a clear message instead of burning time; it also stops cleanly before the run timeout and keeps what it already scraped.
- **Honest results**: "not enough data" is returned as a normal result with `hasData: false`; anything that failed is listed in the run's status message and in `RUN_SUMMARY`. A run that gets nothing **fails** with the reason, it never pretends to succeed.

### How to use it

1. Click **Try for free** / **Start**.
2. In **Search terms**, add one comparison per line. `coffee, tea` compares two terms; `bitcoin` on its own line is analysed alone.
3. Pick the **location**, **time range** and, optionally, a **category** and **search type**.
4. Choose what to extract under **What to extract** and press **Start**.
5. Download the results as JSON, CSV, Excel or HTML, or get them through the API.

For **Trending now**, set *What to scrape* to **Trending now** and pick the countries.

#### Input example

```json
{
    "mode": "keywords",
    "searchTerms": ["coffee, tea", "matcha"],
    "geo": "US",
    "timeRange": "today 12-m",
    "category": "71",
    "searchProperty": "web",
    "includeInterestOverTime": true,
    "includeInterestBySubregion": true,
    "subregionResolution": "AUTO",
    "includeRelatedQueries": true,
    "timezone": "America/New_York"
}
```

Other ways to ask:

```json
{ "exploreUrls": ["https://trends.google.com/trends/explore?date=now%207-d&geo=GB&q=bitcoin,ethereum"] }
```

```json
{ "mode": "trendingNow", "trendingCountries": ["US", "GB", "JP"] }
```

| Field | What it does |
| --- | --- |
| `mode` | `keywords` (default), `trendingNow` or `both`. |
| `searchTerms` | One comparison per line, up to 5 comma-separated terms. Topic IDs like `/m/0dl9sd` work too. |
| `exploreUrls` | Google Trends explore links (and trending links, which add a country to Trending now). |
| `geo` | `US`, `US-CA`, `US-CA-807` (metro), `GB-SCT`, ... or `WORLDWIDE`. |
| `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`, `custom` (+ `startDate` / `endDate`), or a raw range like `2024-01-01 2024-06-30`. |
| `category` | Google Trends category id, e.g. `71` Food & Drink (`0` = all). |
| `searchProperty` | `web`, `images`, `news`, `youtube`, `froogle` (Google Shopping). |
| `subregionResolution` | `AUTO`, `COUNTRY`, `REGION`, `DMA` (US metro areas), `CITY`. |
| `includeLowSearchVolumeRegions` | Also list locations with too little data. |
| `includeRelatedTopics` | Off by default (see FAQ). |
| `trendingCountries` | Countries / regions for Trending now. |
| `timezone`, `language` | Time zone for hourly and minute data and for Google's "today"; names in your language (`en-US`, `de`, `ja`, ...). |
| `proxyConfiguration`, `residentialFallback`, `maxConcurrency`, `maxRequestRetries` | Advanced; the defaults work. |

### Output

You get **one result per search term per comparison** (and one per trending search). Results are shown in handy views in the Output tab: *Overview*, *Interest over time* (one row per date), *Interest by subregion* (one row per location), *Related queries*, *Related topics* and *Trending now*.

#### Keyword result (shortened)

```json
{
    "resultType": "keyword",
    "keyword": "coffee",
    "comparisonGroup": ["coffee", "tea"],
    "groupIndex": 1,
    "geo": "US",
    "geoName": "United States",
    "timeRange": "today 12-m",
    "timeRangeLabel": "Past 12 months",
    "resolvedTimeRange": "2025-09-27 2026-09-27",
    "category": 0,
    "categoryName": "All categories",
    "searchProperty": "web",
    "timezone": "UTC",
    "language": "en-US",
    "exploreUrl": "https://trends.google.com/trends/explore?date=today%2012-m&geo=US&q=coffee%2Ctea&hl=en-US",
    "hasData": true,
    "averageInterest": 78,
    "peakInterest": 100,
    "peakDate": "2026-04-12",
    "latestInterest": 76,
    "timelineResolution": "WEEK",
    "timeline": [
        { "date": "2025-09-21", "timestamp": 1758412800, "formattedTime": "Sep 21 – 27, 2025", "value": 65, "hasData": true, "isPartial": false },
        { "date": "2026-09-27", "timestamp": 1790467200, "formattedTime": "Sep 27 – Oct 3, 2026", "value": 82, "hasData": true, "isPartial": true }
    ],
    "geoResolution": "REGION",
    "geoMap": [
        { "geoCode": "US-WY", "geoName": "Wyoming", "value": 100, "hasData": true },
        { "geoCode": "US-HI", "geoName": "Hawaii", "value": 50, "hasData": true }
    ],
    "geoMapCompared": [
        { "geoCode": "US-MT", "geoName": "Montana", "share": 74 }
    ],
    "relatedQueries": {
        "top": [
            { "query": "coffee near me", "value": 100, "formattedValue": "100", "isBreakout": false, "link": "https://trends.google.com/trends/explore?q=coffee+near+me&date=today+12-m&geo=US" }
        ],
        "rising": [
            { "query": "how to brew pour over coffee", "value": 3100, "formattedValue": "+3,100%", "isBreakout": false, "link": "https://trends.google.com/trends/explore?q=how+to+brew+pour+over+coffee&date=today+12-m&geo=US" }
        ]
    },
    "notes": [],
    "errors": [],
    "scrapedAt": "2026-09-27T19:38:39.941Z"
}
```

`notes` explains things like *Not enough search volume* or a resolution fallback. `errors` lists sections that could not be fetched; such results are stored **free of charge**.

#### Trending now result

```json
{
    "resultType": "trendingNow",
    "geo": "US",
    "geoName": "United States",
    "rank": 1,
    "title": "cardinals vs 49ers",
    "approxTraffic": "10000+",
    "approxTrafficNumber": 10000,
    "pubDate": "2026-09-27T19:10:00.000Z",
    "picture": "https://encrypted-tbn1.gstatic.com/images?q=tbn:...",
    "pictureSource": "San Francisco 49ers",
    "newsItems": [
        { "title": "Ways to Watch and Listen: Cardinals vs. 49ers | Week 3", "snippet": null, "url": "https://www.49ers.com/news/ways-to-watch-and-listen-cardinals-vs-49ers-week-3-x8427", "picture": "https://encrypted-tbn1.gstatic.com/images?q=tbn:...", "source": "San Francisco 49ers" }
    ],
    "exploreUrl": "https://trends.google.com/trends/explore?q=cardinals%20vs%2049ers&date=now%201-d&geo=US&hl=en-US",
    "feedUrl": "https://trends.google.com/trending/rss?geo=US",
    "scrapedAt": "2026-09-27T19:25:09.067Z"
}
```

A complete sample dataset is in the Actor's source under `assets/sample-output.json`.

### Pricing

Pay per result, platform usage included:

| Event | Price |
| --- | --- |
| Keyword result (one term of one comparison, all selected widgets) | **$0.004** ($4 per 1,000) |
| Trending now search | **$0.001** ($1 per 1,000) |
| Actor start | $0.00005 (Apify's standard start fee) |

- Compute and proxy costs are included; the price is the same when the Actor has to switch to residential proxies.
- Results with failed sections, and anything beyond your **maximum charge per run**, are not charged.
- A term with *not enough search volume* is a real answer from Google and counts as a result.
- Apify subscribers on higher plans may get lower prices; the Pricing tab shows your price.

Examples: tracking 50 keywords weekly is about 200 results a month, **$0.80**. A daily Trending now check of 20 items for 5 countries is about 3,000 items a month, **$3**.

### Use it through the API, schedules and integrations

Everything in the Console works through the [Apify API](https://docs.apify.com/api/v2): start a run and get the dataset items in one call with the *run-sync-get-dataset-items* endpoint (copy the ready-made URL from the **API** tab of this Actor). You can also schedule runs (e.g. daily trending searches), send results to Google Sheets, Slack, Make, Zapier or n8n, and call the Actor from AI agents through the Apify MCP server.

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("<ACTOR_ID>").call(run_input={"searchTerms": ["coffee, tea"], "geo": "US", "timeRange": "today 5-y"})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["keyword"], item["averageInterest"], len(item["timeline"]))
```

### FAQ

**What do the numbers mean?** Google Trends values are relative, not search counts: 100 is the peak popularity for the selected terms, location and time; 50 is half as popular; 0 means not enough data. In a comparison all terms share one scale.

**How do I compare more than 5 terms?** Google allows 5 per comparison. Put one "anchor" term in every comparison (e.g. `anchor, a, b, c, d` and `anchor, e, f, g, h`) and rescale each group by the anchor's values.

**Why does a term have `hasData: false`?** Google has too little search volume for that term, location, time range and filters. The run still succeeds and the result says so in `notes`.

**Why are related topics empty?** Google currently returns an empty related-topics list for most searches. The option is off by default so you don't wait for empty data; switch it on if you want to check.

**What does "Breakout" mean?** A rising query grew by more than 5,000%.

**Why do values differ slightly from the Trends website or between runs?** Google computes Trends from a sample of searches, so the same request can vary slightly over time. Short time ranges vary most.

**Can I get data for a US city or metro area?** Yes: set *Location* to a metro code (e.g. `US-CA-807` for San Francisco-Oakland-San Jose) or set *Subregion resolution* to `DMA` or `CITY`. Metro areas come with Google's numeric metro (DMA) code, e.g. `807`; cities come with coordinates instead of codes, like on the website.

**Do I need proxies?** No setup needed: Apify Proxy is used automatically. If you prefer, choose your own proxy groups or proxy URLs under *Advanced settings*.

**What happens when Google blocks requests?** The Actor slows down, retries with fresh sessions and IPs, and switches to residential IPs if needed. If Google still refuses, the run stops early, keeps everything it scraped, tells you what failed, and does not charge for failed results.

**Is scraping Google Trends legal?** The Actor collects aggregated, public, non-personal statistics that Google displays to any visitor. You are responsible for how you use the data and for complying with Google's terms; if unsure, ask a lawyer.

**Is this an official Google product?** No. This Actor is not affiliated with, endorsed by or sponsored by Google.

### Limitations

- Google Trends allows at most 5 terms per comparison and returns at most 25 top and 25 rising related queries per term.
- Minute and hour-level data exist only for recent ranges (past hour to past 7 days); long ranges return weekly or monthly points, as on the website.
- Trending now returns what Google's public feed lists (usually 10-20 searches per country) with approximate search volumes; there is no history.
- Metro areas (DMA) exist for the United States only.
- Related topics are often empty because Google does not provide them for most searches at the moment.

### Support

Found a problem or need a field that is missing? Open an issue in the **Issues** tab with your run link and it will be looked at quickly.

### Changelog

- **1.0 (2026-09-27)**: first release. Keyword analysis (interest over time, by subregion, compared breakdown, related queries and topics), explore URLs, Trending now, automatic proxies with residential fallback, pay per result.

# Changelog

This Actor's version history is a separate document: https://apify.com/symphonic\_mullite/google-trends-scraper/changelog.md

# Actor input Schema

## `mode` (type: `string`):

<b>Keyword analysis</b> fetches Google Trends data for your search terms / explore URLs. <b>Trending now</b> fetches the current trending searches for the countries in the <i>Trending now</i> section. <b>Both</b> does both in one run.

## `searchTerms` (type: `array`):

One comparison per line. Put up to 5 comma-separated terms on a line to compare them against each other (values are then relative to the most popular term, exactly like the Trends website). A single term per line gives its own 0-100 scale. You get one result per term. Topic IDs such as /m/0dl9sd also work.

## `exploreUrls` (type: `array`):

Optional. Paste links copied from trends.google.com. Explore URLs (https://trends.google.com/trends/explore?q=...) keep their own terms, location, time range, category and search type; trending URLs (https://trends.google.com/trending?geo=DE) add that country to the trending-now scrape.

## `geo` (type: `string`):

Country code (US), region (US-CA, GB-SCT), US metro area (US-CA-807), or WORLDWIDE. Pick from the list or type a code. Applies to Search terms (explore URLs keep their own location).

## `timeRange` (type: `string`):

Period to analyse. Short ranges return minute/hour data points, long ranges weekly or monthly points. Choose <b>Custom range</b> and fill in the dates below for anything else.

## `startDate` (type: `string`):

Only used when Time range is <b>Custom range</b>. Google Trends data starts on 2004-01-01.

## `endDate` (type: `string`):

Only used when Time range is <b>Custom range</b>. Leave empty for today.

## `category` (type: `string`):

Narrow the data to a category (e.g. <i>Food & Drink</i> for 'java' the island vs. the coffee). Pick a top-level category or type any numeric Google Trends category id (you can copy it from the <code>cat=</code> part of an explore URL).

## `searchProperty` (type: `string`):

Which Google search property the interest data comes from.

## `includeInterestOverTime` (type: `boolean`):

Timeline of 0-100 search interest with dates, including the partial (still running) last period.

## `includeInterestBySubregion` (type: `boolean`):

0-100 interest per country / region / metro / city. For comparisons you also get each term's share per location (geoMapCompared).

## `subregionResolution` (type: `string`):

Level of detail for interest by subregion. <b>Automatic</b> uses Google's default (countries for worldwide, regions for a country). Metro areas (DMA) exist for the US only. If a level is not available for your location the Actor falls back to the default and says so in <code>notes</code>.

## `includeLowSearchVolumeRegions` (type: `boolean`):

Also list locations where Google has too little data (value 0, hasData false), like the checkbox on the Trends website.

## `includeRelatedQueries` (type: `boolean`):

Top and rising searches related to each term (up to 25 each), with links.

## `includeRelatedTopics` (type: `boolean`):

Top and rising topics related to each term. Google currently returns this list only for some searches; for comparisons it costs one extra explore request per term.

## `trendingCountries` (type: `array`):

Countries (or regions such as US-CA) to get the current trending searches for, with approximate search volume, related news articles and picture. Used when <b>What to scrape</b> is Trending now or Both.

## `maxTrendingItemsPerCountry` (type: `integer`):

Limit the number of trending searches per country. 0 = everything Google lists (usually 10-20).

## `timezone` (type: `string`):

Time zone for minute- and hour-level timeline points (past hour to past 7 days) and for Google's notion of "today": an IANA name such as America/New\_York or Europe/London, or an offset such as UTC+2. Daily, weekly and monthly points are calendar dates.

## `language` (type: `string`):

Language code (hl) for location names and related queries, e.g. en-US, de, ja.

## `proxyConfiguration` (type: `object`):

Apify Proxy is used automatically: datacenter IPs first, with a switch to residential IPs if Google keeps rate-limiting (see the next option). You can also pick specific groups or your own proxies.

## `residentialFallback` (type: `boolean`):

If Google answers 'Too many requests' to several fresh datacenter IPs in a row, continue the run on Apify residential proxies. No extra cost for you: the price per result stays the same.

## `maxConcurrency` (type: `integer`):

How many comparisons run in parallel when proxies are used. Higher is faster but more likely to be rate-limited by Google. Direct connections always use 1.

## `maxRequestRetries` (type: `integer`):

Retries for each request that gets rate-limited or fails, with exponential backoff and a fresh session / IP each time. The run also stops early (instead of looping) if Google blocks 30 requests in a row.

## Actor input object example

```json
{
  "mode": "keywords",
  "searchTerms": [
    "coffee, tea",
    "web scraping",
    "iphone 17, pixel 10, galaxy s26"
  ],
  "exploreUrls": [
    "https://trends.google.com/trends/explore?date=now%207-d&geo=GB&q=bitcoin,ethereum",
    "https://trends.google.com/trending?geo=DE"
  ],
  "geo": "US",
  "timeRange": "today 12-m",
  "category": "0",
  "searchProperty": "web",
  "includeInterestOverTime": true,
  "includeInterestBySubregion": true,
  "subregionResolution": "AUTO",
  "includeLowSearchVolumeRegions": false,
  "includeRelatedQueries": true,
  "includeRelatedTopics": false,
  "trendingCountries": [
    "US"
  ],
  "maxTrendingItemsPerCountry": 0,
  "timezone": "UTC",
  "language": "en-US",
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "residentialFallback": true,
  "maxConcurrency": 3,
  "maxRequestRetries": 6
}
```

# Actor output Schema

## `results` (type: `string`):

All results with every field (keyword analysis and trending now).

## `interestOverTime` (type: `string`):

Timeline rows (one per term and period).

## `trendingNow` (type: `string`):

Trending searches.

## `runSummary` (type: `string`):

Counts, failures and HTTP statistics of the run.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "keywords",
    "searchTerms": [
        "coffee, tea"
    ],
    "geo": "US",
    "timeRange": "today 12-m",
    "trendingCountries": [
        "US"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("symphonic_mullite/google-trends-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "keywords",
    "searchTerms": ["coffee, tea"],
    "geo": "US",
    "timeRange": "today 12-m",
    "trendingCountries": ["US"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("symphonic_mullite/google-trends-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "keywords",
  "searchTerms": [
    "coffee, tea"
  ],
  "geo": "US",
  "timeRange": "today 12-m",
  "trendingCountries": [
    "US"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call symphonic_mullite/google-trends-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,symphonic_mullite/google-trends-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/AfjO8q0Mu7PJf1XPV/builds/fU6gkJau8krQglz8W/openapi.json
