# Google Trends Scraper – Reliable Interest Over Time API (`brightleaf_data/google-trends-scraper`) Actor

Reliable Google Trends API: interest over time, related queries and interest by region for many keywords, countries and search types (web, YouTube, news, images, shopping). Compare up to 5 terms. Pay only for successful results.

- **URL**: https://apify.com/brightleaf\_data/google-trends-scraper.md
- **Developed by:** [Brightleaf Data](https://apify.com/brightleaf_data) (community)
- **Stats:** 2 total users, 1 monthly users, 80.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.50 / 1,000 successful search terms

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 – Reliable Interest Over Time API

**Works reliably, and you pay only for successful results.** Get Google Trends **interest over time**, **related queries (top + rising)** and **interest by region** for hundreds of keywords in one run, across any country and across Web, YouTube, News, Images and Shopping search.

- ✅ **Built for reliability.** Datacenter proxies first, with automatic **residential fallback** when Google rate-limits. Every retry uses a fresh session and IP, with exponential backoff.
- 💸 **Pay only for results.** Failed terms are returned with a clear reason and are **never charged**.
- ⚡ **Lightweight and fast.** No browser, just 256 MB of memory and about 3 seconds per term.
- 🧾 **Clean output.** One row per term, with clear field names and a `status` field. Ready for spreadsheets, BI tools and automations.
- 🔀 **Compare mode.** Compare up to 5 terms on the same 0–100 scale, just like on trends.google.com.

### What can you use it for?

| Use case | How |
|---|---|
| 🔎 **SEO and keyword research** | Check whether a keyword is growing or dying before you target it, and mine **rising related queries** for new long-tail ideas. |
| 🗓️ **Content planning** | Find seasonal peaks (e.g. "sunscreen", "diwali gifts") and publish ahead of the demand curve. |
| 📊 **Market research** | Compare brands, products or categories (`nike, adidas, puma`) across countries and on YouTube or Shopping search. |
| 📈 **Trend monitoring** | Schedule daily or weekly runs and send the results to Sheets, Slack or your database to catch breakout topics early. |

### How to use it

1. Enter your **search terms**, one per line. Add `| COUNTRY` to set a country for one term, e.g. `cricket | IN`.
2. Optionally set the default **location**, **time range**, **search type** and **category**.
3. Choose what to fetch: interest over time (on by default), related queries (on by default) and interest by region.
4. Click **Start**, then download the results as JSON, CSV, Excel or HTML, or fetch them through the API.

### Input examples

**Keyword research across countries**

```json
{
    "searchTerms": ["coffee", "cricket | IN", "premier league | GB", "tesla | US"],
    "timeRange": "today 12-m",
    "includeRelatedQueries": true
}
```

**Compare brands on YouTube over 5 years, with regional breakdown**

```json
{
    "searchTerms": ["nike, adidas, puma | US", "iphone, samsung, pixel"],
    "isMultiple": true,
    "timeRange": "today 5-y",
    "property": "youtube",
    "includeInterestByRegion": true
}
```

**Exact date range in one category (Food & Drink)**

```json
{
    "searchTerms": ["matcha", "cold brew"],
    "geo": "GB",
    "customTimeRange": "2024-01-01 2024-12-31",
    "category": 71
}
```

The input field names (`searchTerms`, `isMultiple`, `timeRange`, `customTimeRange`, `geo`, `category`, `maxItems`) match the most popular Google Trends Actor, so you can switch by pasting your existing input.

### Output

Each search term (or comparison group) produces **one dataset item**:

| Field | Description |
|---|---|
| `searchTerm` / `searchTerms` | The term, or the list of compared terms |
| `geo`, `timeRange`, `category`, `property` | What was requested (`geo: ""` means worldwide) |
| `status` | `success`, `failed` or `skipped` (max charge limit reached) |
| `errorReason` | Why a term failed, e.g. `Rate-limited by Google (HTTP 429) after 5 attempt(s)` |
| `interestOverTime` | `[{date, timestamp, formattedTime, value, isPartial}]`. In compare mode, `values` is keyed by term |
| `relatedQueriesTop` / `relatedQueriesRising` | `[{query, value, formattedValue, link}]`. In compare mode, `relatedQueriesByTerm` |
| `interestByRegion` | `[{geoCode, geoName, value}]` (when enabled) |
| `scrapedAt` | ISO timestamp |
| `meta` | Attempts, proxy used, whether residential fallback was needed, duration |
| `input` | The exact input line, for easy joining |

**Sample** (term `coffee`, US, past 12 months):

| date | value |
|---|---|
| 2025-09-21 | 62 |
| 2025-09-28 | 63 |
| … | … |

```json
{
    "searchTerm": "coffee",
    "searchTerms": ["coffee"],
    "isCompare": false,
    "geo": "US",
    "timeRange": "today 12-m",
    "category": 0,
    "property": "web",
    "status": "success",
    "errorReason": null,
    "interestOverTime": [
        { "date": "2025-09-21", "timestamp": 1758412800, "formattedTime": "Sep 21 – 27, 2025", "value": 62, "isPartial": false }
    ],
    "relatedQueriesTop": [
        { "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" }
    ],
    "relatedQueriesRising": [
        { "query": "how to remove coffee stain from carpet", "value": 5150, "formattedValue": "Breakout", "link": "https://trends.google.com/trends/explore?q=how+to+remove+coffee+stain+from+carpet&date=today+12-m&geo=US" }
    ],
    "scrapedAt": "2026-09-27T09:00:00+00:00",
    "meta": { "attempts": 1, "proxy": "datacenter", "usedResidentialFallback": false, "durationSecs": 2.4, "retriedErrors": [] },
    "input": { "searchTermsEntry": "coffee | US", "index": 0 }
}
```

A run summary (successes, failures, residential fallbacks, error counts, duration) is saved as `SUMMARY` in the run's key-value store.

### Integrations

Works with **n8n, Make, Zapier**, Google Sheets, Slack, Airbyte, webhooks and anything that can call the [Apify API](https://docs.apify.com/api/v2). Use the **Run Actor** module or node, then read the dataset items. Because every item has a `status` field, you can filter out failures in one step.

### FAQ

**Do I need my own proxies?**
No. Proxies are included. The default **Auto** strategy uses fast datacenter IPs and automatically retries rate-limited terms through residential IPs. You can force *Datacenter only* or *Residential only* in the input.

**What does it cost?**
This Actor uses pay-per-event pricing with two charges (current prices are on the *Pricing* tab):

| Event | When it is charged | Price |
|---|---|---|
| **Actor start** | Once when a run starts (per GB of memory; the default 256 MB counts as one) | $0.005 |
| **Term result** | Once per **successful** search term or comparison group | $0.0015 ($1.50 per 1,000) |

Example: 1,000 terms in one run cost $0.005 + $1.50 = **$1.505**. Platform and proxy costs are included, with no usage fees on top. Failed terms are returned with a reason and **are not charged**. If you set a maximum cost for a run, the Actor takes the start fee into account and stops cleanly before going over it. Remaining terms are listed as `skipped` and are not charged.

**What is compare mode?**
Enable **Compare terms** and put up to 5 comma-separated terms on one line (`coffee, tea, matcha | US`). They are fetched in a single Google Trends comparison, so the values share one 0–100 scale. Each line counts as one result.

**Are there limits?**
Google allows at most 5 terms per comparison. Values are relative (0–100), as on trends.google.com, and very low-volume terms may return no data. Concurrency is capped at 5 to stay under Google's rate limits. The default of 2 is the tested sweet spot. For very large batches (thousands of terms), split them across a few runs or schedule them.

**Why are "rising" values sometimes "Breakout"?**
Google labels queries that grew by more than 5,000% as *Breakout*. The numeric `value` is still included.

**Can I get related topics?**
Not currently. Google no longer serves related-topics data through its public Trends endpoints (it returns empty lists), so we don't charge you for a field that would always be empty.

**Is scraping Google Trends legal?**
This Actor collects publicly available, aggregated and anonymized statistics. It does not collect personal data. Check your own use case against applicable laws and Google's terms.

# Actor input Schema

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

Keywords to look up, one per line. Each term becomes one result.<br><br>Optional <b>per-term location</b>: add <code>| COUNTRY</code>, e.g. <code>cricket | IN</code> or <code>tesco | GB</code>. Terms without it use the default location below.<br><br>With <b>Compare terms</b> enabled, write up to 5 terms separated by commas on one line, e.g. <code>coffee, tea, matcha | US</code>.

## `isMultiple` (type: `boolean`):

When enabled, commas in a search-terms line separate up to 5 terms that are compared against each other on the same 0-100 scale (like adding terms on trends.google.com). The whole line returns one result. When disabled, commas are part of the search term.

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

Two-letter country code (e.g. <code>US</code>, <code>IN</code>, <code>GB</code>, <code>DE</code>) or a region like <code>US-CA</code>. Leave empty for <b>Worldwide</b>. Individual terms can override this with <code>| COUNTRY</code>.

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

Period to fetch. Data resolution depends on the range (e.g. weekly points for 12 months, daily for 90 days, hourly for 7 days).

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

Optional exact period in the format <code>YYYY-MM-DD YYYY-MM-DD</code>, e.g. <code>2024-01-01 2024-12-31</code>. Overrides <b>Time range</b>.

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

Which Google property to measure interest on — same as the 'Web search / YouTube search / ...' switch on trends.google.com.

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

Optional Google Trends category to narrow the topic (0 = all categories). Examples: 3 = Arts & Entertainment, 7 = Finance, 45 = Health, 71 = Food & Drink, 958 = Jobs & Education. Find more IDs in the <code>cat=</code> part of a trends.google.com URL.

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

Time series of search interest on a 0-100 scale.

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

Top and rising related searches for each term (up to 25 each). In compare mode, returned per term.

## `includeInterestByRegion` (type: `boolean`):

Interest per country (worldwide) or per state/region (when a country is set).

## `proxyStrategy` (type: `string`):

<b>Auto (recommended)</b>: fast, low-cost datacenter proxies first; if Google rate-limits a term, it is retried automatically via residential proxies. <b>Datacenter only</b> / <b>Residential only</b> force one pool. Proxy costs are included in the price.

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

How many terms are fetched in parallel (1-5). Higher is faster; 2 is the tested sweet spot for reliability.

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

Retries after the first attempt when Google rate-limits or blocks a request. Each retry uses a new session and IP with exponential backoff.

## `termTimeoutSecs` (type: `integer`):

Hard time limit for one term including retries. When it is hit, the term is returned with status "failed" and a reason (and is not charged).

## `maxItems` (type: `integer`):

Process at most this many search-term lines (0 = no limit). Useful for test runs.

## Actor input object example

```json
{
  "searchTerms": [
    "coffee",
    "bitcoin | US",
    "cricket | IN",
    "premier league | GB"
  ],
  "isMultiple": false,
  "geo": "",
  "timeRange": "",
  "property": "web",
  "category": 0,
  "includeInterestOverTime": true,
  "includeRelatedQueries": true,
  "includeInterestByRegion": false,
  "proxyStrategy": "auto",
  "maxConcurrency": 2,
  "maxRequestRetries": 4,
  "termTimeoutSecs": 150,
  "maxItems": 0
}
```

# Actor output Schema

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

One item per search term or comparison group: interest over time, related queries, interest by region, status and error reason.

## `failed` (type: `string`):

Every term with its status (success / failed / skipped), error reason and retry details (attempts, proxy used, residential fallback). Filter status != success to see failures; failed and skipped terms are never charged.

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

SUMMARY record: success/failure counts, duration, proxy fallback and circuit-breaker stats, error counts.

# 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",
        "bitcoin | US",
        "cricket | IN",
        "premier league | GB"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("brightleaf_data/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",
        "bitcoin | US",
        "cricket | IN",
        "premier league | GB",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("brightleaf_data/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",
    "bitcoin | US",
    "cricket | IN",
    "premier league | GB"
  ]
}' |
apify call brightleaf_data/google-trends-scraper --silent --output-dataset

```

## MCP server setup

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