# Google Trends Scraper: Interest Over Time, Regions & Queries (`private_image_hg9/google-trends-scraper`) Actor

Google Trends data that arrives or tells you why not. Interest over time, interest by region, related queries and related topics for up to 5 compared terms, with batching for longer lists. Retries 429s with fresh sessions, never loops, and you pay only for rows delivered.

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

## Pricing

$0.30 / 1,000 result rows

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

Get **Google Trends** data as clean rows: interest over time, interest by region, related queries and related topics, for up to 5 terms compared side by side, in any country or worldwide, for any time range Google offers. Use it as a simple **Google Trends API** from your code, a schedule, Make, Zapier or an AI agent.

**$0.30 per 1,000 rows.** You pay only for rows saved to your dataset. A run that gets no data from Google costs nothing.

### Why this one works

Most Google Trends tools fail quietly. You wait, the run spins, and the dataset is empty. This one is built the other way around:

- **It returns data or tells you exactly why not.** Every request is listed in the `SUMMARY` record with its result. A failure says what happened in plain words, like "Google kept answering 429 Too Many Requests after 5 tries" or "no data for this term (too little search volume for this place and time range)".
- **It never loops.** Each request has a timeout, retries are capped, and the whole run has a hard time limit (10 minutes by default). Nothing is retried after that limit. Rows already saved are kept.
- **It handles Google's rate limits.** A 429 answer is retried with growing waits plus random jitter. Two 429s in a row start a fresh session with a new proxy IP and a new Google cookie. If Google keeps refusing, the run stops early instead of burning your time.
- **You pay only for delivered rows.** Failed requests, terms with no data and regions with no data produce no rows and no charge.
- **It's fast.** It talks to the same endpoints the Google Trends website uses, with no browser. A 2-term comparison with all four outputs takes a few seconds.

### What you can use it for

- **SEO and content planning:** compare keywords, find rising queries before they peak, and see which regions search most.
- **Market and product research:** track demand for a product, brand or category over 5 years or since 2004.
- **Investing and analytics:** feed weekly or daily interest into dashboards and models.
- **News and social monitoring:** watch what's rising in the past hour, 4 hours or day.
- **AI agents:** give an LLM structured trend data without scraping.

### Input

| Field | What it does |
|---|---|
| **Search terms** | Up to 5 terms are compared in one request, like the website's Compare box. Up to 100 per run. |
| **Location** | `US`, `GB`, `DE`, a state like `US-CA`, a US metro like `US-NY-501`. Blank means worldwide. |
| **Time range** | Past hour, 4 hours, day, 7 days, 30 days, 90 days, 12 months, 5 years, 2004 to present, or Custom. |
| **Custom time range** | `2024-01-01 2024-06-30` when Time range is Custom. |
| **Category** | Google Trends category id, e.g. `71` (Food & Drink). `0` is all categories. |
| **Google property** | Web, Image, News, YouTube or Shopping search. |
| **What to return** | Interest over time, interest by region, related queries and related topics. All on by default. Google gives related topics only for a term searched on its own, so compared terms return the other three. |
| **Anchor term** | For more than 5 terms. See below. |
| **Use Apify Proxy / Proxy groups** | On by default. `RESIDENTIAL` gets rate limited far less often than datacenter proxies. |
| **Retries, request timeout, run time limit** | Defaults: 4 retries, 30 seconds per request, 600 seconds per run. |

Example:

```json
{
  "searchTerms": ["coffee", "tea", "matcha"],
  "geo": "US",
  "timeRange": "past-12-months",
  "relatedTopics": false
}
```

#### More than 5 terms

Google compares at most 5 terms at once, and its 0 to 100 values are relative to the highest point inside one comparison. So longer lists are split into groups:

- **Without an anchor term** each group of 5 is its own comparison. Values compare fairly inside a group, not across groups. Rows carry a `requestId` (`comparison-1`, `comparison-2`, ...) so you can tell the groups apart.
- **With an anchor term** every group is the anchor plus 4 other terms. Each interest-over-time row also gets a `scaledValue` that puts every group on the first group's scale, using the anchor's total in each group. Pick a steady, popular term as the anchor. Its own rows come back once, from the first group. Scaled values can go above 100.

### Output

Every row has a `type`, the `requestId` of its comparison, the `term`, and the `geo`, `timeRange`, `category` and `property` it was asked with. Rows are flat, so they open cleanly in Excel or Google Sheets.

Interest over time (one row per term per time point; `isPartial` marks the current, unfinished period):

```json
{"type": "interestOverTime", "requestId": "comparison-1", "term": "coffee", "geo": "US", "timeRange": "past-12-months",
 "category": 0, "property": "web", "date": "2026-11-01", "formattedTime": "Nov 1, 2026", "value": 60, "hasData": true, "isPartial": true}
```

Dates are `YYYY-MM-DD`. For the past hour, 4 hours, day and 7 days they are UTC timestamps like `2026-11-01T18:08:00Z`.

Interest by region:

```json
{"type": "interestByRegion", "requestId": "comparison-1", "term": "coffee", "geo": "US", "timeRange": "past-12-months",
 "category": 0, "property": "web", "geoCode": "US-CA", "geoName": "California", "value": 65}
```

When several terms are compared, Google gives each region's split between the terms, so a region's values add up to about 100.

Related queries (`kind` is `top` or `rising`; rising values are percent growth, and `Breakout` means more than 5,000%):

```json
{"type": "relatedQuery", "requestId": "comparison-1", "term": "tea", "geo": "US", "timeRange": "past-12-months",
 "category": 0, "property": "web", "kind": "rising", "rank": 1, "query": "tea recipe 2026", "value": 4250,
 "formattedValue": "+4,250%", "link": "https://trends.google.com/trends/explore?q=tea%20recipe%202026&date=today%2012-m"}
```

Related topics:

```json
{"type": "relatedTopic", "requestId": "comparison-1", "term": "coffee", "kind": "top", "rank": 1, "topicId": "/m/041093",
 "topicTitle": "Coffee", "topicType": "Topic", "value": 100, "formattedValue": "100", "link": "https://trends.google.com/trends/explore?q=/m/041093&date=today%2012-m"}
```

The `SUMMARY` record in the run's key-value store has the status (`ok`, `partial`, `no_data`, `rate_limited`, `time_limit`, `failed` or `invalid_input`), requests made, succeeded and failed, every failure with its reason, rows saved and charged per type, whether the spending limit was reached, and notes such as terms with no data.

### Pricing

**$0.30 per 1,000 rows**, charged per row saved. No start fee. Examples from real runs: 2 terms in the US over the past 12 months with every output is about 300 rows, so about $0.09. 5 terms worldwide over 5 years is about 1,900 rows, so about $0.57. 5 terms over 5 years with only interest over time is about 1,300 rows, so about $0.39.

If you set a maximum charge for a run, the Actor stops requesting as soon as it's reached and says so in `SUMMARY`.

### Limits

- **Values are relative, not search counts.** Google Trends gives a 0 to 100 index where 100 is the busiest point (or region) within the comparison. Different comparisons are not on the same scale unless you use an anchor term.
- **Google rate limits.** Google decides how many requests it answers. Busy proxies, very long term lists and short schedules get more 429 answers. Residential proxies help. When Google refuses, you get a clear reason and no charge.
- **Related topics are often empty right now.** Google gives them only for a term searched on its own, and in our November 2026 tests it sent the list back empty even for popular terms. When that happens the SUMMARY says so and nothing is charged.
- **Low-volume terms** can have no data in some places or time ranges. They are listed in the `SUMMARY` notes and cost nothing.
- **Up to 100 terms per run**, 5 per comparison. Custom ranges are whole days from 2004-01-01 to today.
- This Actor reads the public Google Trends website data. It is not affiliated with Google.

### More tools from the same developer

- [News Scraper: GDELT Articles, Full Text & 65 Languages](https://apify.com/private_image_hg9/news-search-gdelt)
- [RSS Feed Reader: Atom & RSS to JSON with Feed Finder](https://apify.com/private_image_hg9/rss-feed-reader-finder)
- [Hacker News Scraper: Search, Stories & Comments](https://apify.com/private_image_hg9/hacker-news-scraper)
- [OpenAlex Papers Search: Scholarly Works, Citations & Abstracts](https://apify.com/private_image_hg9/openalex-papers-search)
- [ClinicalTrials.gov Search: Studies, Phases, Sponsors & Status](https://apify.com/private_image_hg9/clinical-trials-search)
- [Federal Contracts Search: SAM.gov Opportunities & Award History](https://apify.com/private_image_hg9/federal-contracts-search)

# Actor input Schema

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

Words or phrases to look up, e.g. "coffee", "tea". Up to 5 terms are compared with each other in one Google Trends request, exactly like the Compare box on the website. Longer lists are split into groups of 5 (see Anchor term). Up to 100 terms per run.

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

Country or region code as Google Trends uses it: "US", "GB", "DE", a state like "US-CA", or a US metro like "US-NY-501". Leave blank for worldwide.

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

The same presets as the Google Trends website. Choose Custom to enter your own dates below.

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

Used when Time range is Custom. Start and end date separated by a space: "2024-01-01 2024-06-30". Data starts on 2004-01-01.

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

Google Trends category id, e.g. 71 for Food & Drink or 7 for Finance. 0 means all categories.

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

Which Google search to measure.

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

One row per term per time point, with the 0 to 100 value and whether the period is still partial.

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

One row per term per country (worldwide) or subregion (for a country). Regions without data are left out.

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

Searches people also made, with Google's top and rising lists.

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

Topics (people, places, things) people also searched for, with their Knowledge Graph id.

## `anchorTerm` (type: `string`):

Only used with more than 5 terms. Without an anchor, each group of 5 is its own comparison and values are 0 to 100 within that group only. With an anchor, every group is the anchor plus 4 other terms, and each row gets a scaledValue that puts all groups on the first group's scale. Pick a steady, popular term. It is added to your terms if missing.

## `useApifyProxy` (type: `boolean`):

Send requests through Apify Proxy. Each 429 streak switches to a new proxy IP. Turn off only if you run the Actor on your own machine.

## `proxyGroups` (type: `array`):

Apify Proxy groups to use, e.g. RESIDENTIAL. Leave empty for automatic datacenter proxies. Residential proxies get rate limited by Google far less often.

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

How many times one request is retried after a 429, a server error or a timeout. Waits grow from about 2 seconds, with random jitter.

## `requestTimeoutSecs` (type: `integer`):

Give up on one answer from Google after this long, then retry.

## `maxRunSecs` (type: `integer`):

Hard limit for the whole run. No request or retry starts after it, so a run can never loop. Rows already saved are kept.

## Actor input object example

```json
{
  "searchTerms": [
    "coffee",
    "tea"
  ],
  "geo": "US",
  "timeRange": "past-12-months",
  "category": 0,
  "property": "web",
  "interestOverTime": true,
  "interestByRegion": true,
  "relatedQueries": true,
  "relatedTopics": true,
  "useApifyProxy": true,
  "maxRetries": 4,
  "requestTimeoutSecs": 30,
  "maxRunSecs": 600
}
```

# Actor output Schema

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

Every row the run saved, in the default dataset. The type field says which output a row belongs to.

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

Requests made, succeeded and failed with the reason for each failure, rows saved and charged, and notes such as terms with no data.

# 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",
        "tea"
    ],
    "geo": "US"
};

// Run the Actor and wait for it to finish
const run = await client.actor("private_image_hg9/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",
        "tea",
    ],
    "geo": "US",
}

# Run the Actor and wait for it to finish
run = client.actor("private_image_hg9/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",
    "tea"
  ],
  "geo": "US"
}' |
apify call private_image_hg9/google-trends-scraper --silent --output-dataset

```

## MCP server setup

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