# Google Trends Scraper - Interest, Regions, Related Queries (`maksym_kotenko/google-trends-scraper`) Actor

Google Trends data without a browser: interest over time, interest by country, region, city or metro, related and rising queries, comparisons of up to 5 terms. Pay per complete report, no start fee, nothing for empty or partial results.

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

## Pricing

from $0.50 / 1,000 reports

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 - Interest, Regions, Related Queries

Get Google Trends data as JSON, CSV or Excel without a browser: interest over time, interest by country, region, city or US metro area, and top and rising related queries. Compare up to 5 terms on one scale, run hundreds of terms and locations in one go, and pay only for complete reports.

### What you get

For every search term (or comparison) and location, one report with:

- **Interest over time** - the 0-100 timeline Google shows, from minutes (past hour) to months (since 2004), with the last incomplete period flagged as `isPartial`.
- **Average, latest and peak** per term - the latest value skips the incomplete period, so it is safe for dashboards and alerts.
- **Interest by region** - countries, regions or states, cities (with coordinates) or US metro areas. Comparisons also get each term's share per region.
- **Related queries** - top and rising queries per term, rising ones with an `isBreakout` flag (growth over 5000%).
- **A link to the same report on trends.google.com**, so every number can be checked by eye.

### Why this actor

- **Pay per complete report, nothing else.** No start fee, no charge for terms without search volume, no charge for a report that is missing a section, no charge for error rows. Check the Pricing tab.
- **Built for rate limits.** Google Trends answers floods of requests with HTTP 429. Requests of a report are spaced out, a rate-limited request is retried with growing pauses, the proxy session is replaced after two failures in a row and, if the datacenter proxy keeps getting blocked, the run continues through a residential proxy at no extra cost to you.
- **No browser.** The actor talks to the same JSON endpoints the Trends page uses, so a report takes a few seconds and 256 MB of memory.
- **Batch friendly.** Terms x locations in one run, several reports in parallel, each through its own proxy session.

### Input

| Field | What it does |
|---|---|
| `searchTerms` | One report per line. `coffee, tea` compares up to 5 terms on one scale. Topic ids such as `/m/02vqfm` work too. |
| `geos` | Location codes: `US`, `GB`, `US-CA`, `US-CA-807`. Empty or `worldwide` for the whole world. Each term is reported for each location. |
| `timeRange` | `now 1-H`, `now 4-H`, `now 1-d`, `now 7-d`, `today 1-m`, `today 3-m`, `today 12-m` (default), `today 5-y`, `all`. |
| `customTimeRange` | Overrides `timeRange`: `2024-01-01 2024-12-31`. |
| `category` | Category id, the `cat=` value of a Trends URL. `0` is all categories. |
| `property` | `web`, `images`, `news`, `shopping` or `youtube` search. |
| `regionResolution` | `auto`, `COUNTRY`, `REGION`, `CITY` or `DMA` (US metro areas). |
| `interestOverTime`, `interestByRegion`, `relatedQueries`, `relatedTopics` | Sections to fetch. Fewer sections means fewer requests and faster runs; the price per report stays the same. |

Example:

```json
{
  "searchTerms": ["coffee", "coffee, tea, matcha"],
  "geos": ["US", "GB"],
  "timeRange": "today 12-m"
}
```

This run returns 4 reports: coffee in the US and in the UK, and the comparison in both.

### Output example

One dataset row per report, shortened here:

```json
{
  "searchTerm": "coffee, tea",
  "searchTerms": ["coffee", "tea"],
  "geo": "US",
  "timeRange": "today 12-m",
  "resolvedTimeRange": "2025-10-18 2026-10-18",
  "timelineResolution": "WEEK",
  "category": 0,
  "property": "web",
  "language": "en-US",
  "hasData": true,
  "averages": [78, 37],
  "latestValues": [68, 32],
  "interestOverTime": [
    { "date": "2025-10-12T00:00:00.000Z", "values": [62, 34], "isPartial": false },
    { "date": "2026-10-11T00:00:00.000Z", "values": [68, 32], "isPartial": false },
    { "date": "2026-10-18T00:00:00.000Z", "values": [88, 34], "isPartial": true }
  ],
  "comparedByRegion": [
    { "geoCode": "US-WY", "geoName": "Wyoming", "shares": [70, 30] },
    { "geoCode": "US-HI", "geoName": "Hawaii", "shares": [68, 32] }
  ],
  "regionResolution": "REGION",
  "terms": [
    {
      "term": "coffee",
      "average": 78,
      "latest": 68,
      "latestDate": "2026-10-11T00:00:00.000Z",
      "peak": 100,
      "peakDate": "2026-04-12T00:00:00.000Z",
      "interestByRegion": [
        { "geoCode": "US-WY", "geoName": "Wyoming", "value": 100 },
        { "geoCode": "US-HI", "geoName": "Hawaii", "value": 45 }
      ],
      "relatedQueries": {
        "top": [
          { "query": "coffee near me", "value": 100, "formattedValue": "100", "link": "https://trends.google.com/trends/explore?q=coffee+near+me&date=today+12-m&geo=US" }
        ],
        "rising": [
          { "query": "national coffee day 2026", "value": 2000, "formattedValue": "+2,000%", "link": "https://trends.google.com/trends/explore?q=national+coffee+day+2026&date=today+12-m&geo=US", "isBreakout": false }
        ]
      },
      "relatedTopics": null
    }
  ],
  "trendsUrl": "https://trends.google.com/trends/explore?date=today%2012-m&q=coffee,tea&geo=US&hl=en-US",
  "complete": true,
  "missingSections": [],
  "fetch": { "requests": 7, "retries": 0, "strategy": "apify-proxy" },
  "scrapedAt": "2026-10-18T18:20:00.000Z"
}
```

- Values are Google's relative 0-100 index, not search counts. In a comparison all terms share one scale.
- `hasData: false` means Google has too little search volume for the term; such reports are free.
- `complete: false` lists the sections Google refused in `missingSections`; such reports are free too.
- The **Reports** table view shows one line per report; **Timeline, regions and queries** shows the nested data. Excel and CSV exports flatten the nested fields.
- The key-value store record `SUMMARY` counts complete, free and failed reports, requests, retries and the proxy strategies used.

### Errors

Rows with an `error` field are free:

- `INVALID_INPUT` - a comparison with more than 5 terms or an unknown location code.
- `INVALID_QUERY` - Google rejected the request, for example a category id that does not exist.
- `RATE_LIMITED` - Google kept answering HTTP 429 after all retries. Run again later, lower `Reports in parallel` or keep the residential fallback on.
- `FETCH_FAILED` - network errors after all retries.
- `FORMAT_CHANGED` - Google changed its answer format; the actor is monitored daily and fixed quickly.

### Good to know

- Google Trends data is sampled: the same report can differ by a few points between runs, as on the Trends website.
- Related topics: Google currently sends automated clients an empty topic list, so the section is off by default and reported as `null`.
- Rising queries are exactly what Google returns. Some rising lists contain generic queries that have nothing to do with the term; they come from Google's data, the actor does not filter them.
- Only public, aggregated statistics are collected. No personal data, no Google account, no captcha solving.
- The actor is not affiliated with Google. Google Trends is a trademark of Google LLC.

### Integrations

Schedule the actor in Apify to track terms every day, send results to Google Sheets, Slack or a webhook, or call it from your code through the Apify API and the `apify-client` libraries for JavaScript and Python.

# Actor input Schema

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

One report per line. Separate up to 5 terms with commas to compare them on one scale, for example coffee, tea. Topic ids like /m/02vqfm work too.

## `geos` (type: `array`):

Google Trends location codes, one per line: US, GB, US-CA, US-CA-807. Leave empty or write worldwide for the whole world. Every search term is reported for every location.

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

Period of the report. Google picks the timeline step from it: minutes for the last hours, days up to 9 months, weeks up to 5 years, months beyond.

## `customTimeRange` (type: `string`):

Overrides the time range above: two dates YYYY-MM-DD YYYY-MM-DD, for example 2024-01-01 2024-12-31. Data starts on 2004-01-01.

## `category` (type: `integer`):

Google Trends category id, the cat= value in a Trends URL: 0 all categories, 71 Food and drink, 5 Computers and electronics.

## `property` (type: `string`):

Where the searches happened.

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

Language of related query links and Google's labels, like en-US, de or ja. Search interest does not depend on it.

## `interestOverTime` (type: `boolean`):

Timeline of search interest on a 0-100 scale, plus average, latest and peak value per term.

## `interestByRegion` (type: `boolean`):

Search interest per country, region, city or metro area. Comparisons also get the share of each term per region.

## `relatedQueries` (type: `boolean`):

Top and rising related queries per term, with Breakout flags.

## `relatedTopics` (type: `boolean`):

Top and rising related topics per term, single-term reports only. Google currently sends automated clients an empty topic list, so this is off by default.

## `regionResolution` (type: `string`):

Level of the interest by region table. Auto follows Google: countries for worldwide, regions inside a country. Metro areas (DMA) exist only for the US.

## `includeLowVolumeRegions` (type: `boolean`):

Also list regions with little search volume, like the checkbox on the Trends page.

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

How many reports are fetched at the same time, each through its own proxy session. Requests of one report are spaced by about 1.5 seconds so Google does not rate limit them.

## `maxRetries` (type: `integer`):

How often a rate-limited or failed request is retried with growing pauses; the proxy session is replaced after two failures in a row.

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

Google rate limits shared datacenter addresses quickly. Apify Proxy is on by default and costs you nothing extra.

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

When the first proxy keeps getting rate limited, continue through Apify residential proxy. Included in the price.

## Actor input object example

```json
{
  "searchTerms": [
    "coffee",
    "coffee, tea"
  ],
  "geos": [
    "US"
  ],
  "timeRange": "today 12-m",
  "category": 0,
  "property": "web",
  "language": "en-US",
  "interestOverTime": true,
  "interestByRegion": true,
  "relatedQueries": true,
  "relatedTopics": false,
  "regionResolution": "auto",
  "includeLowVolumeRegions": false,
  "maxConcurrency": 2,
  "maxRetries": 6,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "residentialFallback": true
}
```

# Actor output Schema

## `reports` (type: `string`):

One row per report: timeline, interest by region, related queries, average, latest and peak values; error rows for reports that could not be fetched.

## `summary` (type: `string`):

Complete, free and failed reports, requests, retries and the proxy strategies used.

# 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 = {
    "searchTerms": [
        "coffee",
        "coffee, tea"
    ],
    "geos": [
        "US"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("maksym_kotenko/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 = {
    "searchTerms": [
        "coffee",
        "coffee, tea",
    ],
    "geos": ["US"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("maksym_kotenko/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 '{
  "searchTerms": [
    "coffee",
    "coffee, tea"
  ],
  "geos": [
    "US"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call maksym_kotenko/google-trends-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maksym_kotenko/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/mDXeC7QL6DqdIdKJO/builds/WgWJprUrwLFbyy8cG/openapi.json
