# Google Trends Scraper: Interest, Regions, Related, Trending Now (`ctriolab/google-trends-scraper`) Actor

Reliable Google Trends API alternative. Compare up to 5 keywords per comparison and many comparisons per run: interest over time, interest by country, region or city, related queries and Trending now by country. Built-in 429 handling.

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

## Pricing

from $1.50 / 1,000 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: Interest, Regions, Related, Trending Now

A **reliable Google Trends API alternative**. Give it keywords, get clean JSON (or flat spreadsheet rows) with:

| Data | Output `type` | What it is |
|---|---|---|
| Interest over time | `interest_over_time` | 0-100 timeline per term, with `isPartial` for the unfinished last period |
| Interest by region | `interest_by_region` | 0-100 per country, region/state, city or US metro (DMA) |
| Related queries | `related_queries` | Top and rising queries per term ("Breakout" included) |
| Related topics (beta) | `related_topics` | Top and rising topics per term (topic name, type and Knowledge Graph ID). Often empty, see Limits |
| Trending now | `trending_now` | What is spiking in Google Search right now, per country: search volume, % increase, start time, category, related searches |

Built for **reliability first**:

- **Rate limit (HTTP 429) handling**: each request retries up to 10 times. Every retry gets a new session (new proxy IP and new Google cookies) and waits with exponential backoff plus jitter.
- **Cookie bootstrap**: every session first visits Google Trends like a browser to get the `NID` cookie before calling the API.
- **Partial results instead of failed runs**: if one comparison fails, the others are still saved, and the run summary tells you exactly what failed.
- **Many comparisons per run**: compare up to 5 terms on the same scale, and add as many comparison lines as you need.

### Input

Each line of **Search terms** is one Google Trends comparison. Put up to 5 terms on a line, separated by commas, to compare them on the same 0-100 scale (exactly like the Compare button on trends.google.com).

#### Example 1: compare three keywords in the US over 12 months (the default)

```json
{
  "searchTerms": ["coffee, tea, matcha"],
  "geo": "US",
  "timeframe": "today 12-m"
}
```

#### Example 2: everything for several keywords, worldwide, by country

```json
{
  "searchTerms": ["chatgpt", "gemini", "claude ai"],
  "geo": "",
  "timeframe": "today 5-y",
  "includeInterestByRegion": true,
  "regionResolution": "COUNTRY",
  "includeRelatedQueries": true,
  "includeRelatedTopics": true
}
```

#### Example 3: YouTube search interest in South Korea, past 7 days, one row per hour for Google Sheets

```json
{
  "searchTerms": ["아이폰, 갤럭시"],
  "geo": "KR",
  "timeframe": "now 7-d",
  "gprop": "youtube",
  "outputFormat": "row-per-point",
  "language": "ko",
  "timezoneOffset": -540
}
```

#### Example 4: custom date range

```json
{ "searchTerms": ["taylor swift"], "geo": "", "timeframe": "custom", "customTimeRange": "2024-01-01 2024-12-31" }
```

#### Example 5: Trending now in several countries (no keywords needed)

```json
{ "searchTerms": [], "trendingNowCountries": ["US", "GB", "KR", "JP", "IN"], "trendingNowHours": "24", "maxTrendingPerCountry": 50 }
```

#### All input fields

| Field | Default | Notes |
|---|---|---|
| `searchTerms` | `["coffee, tea"]` | One comparison per line, up to 5 comma-separated terms per line. |
| `geo` | `US` | Country (`US`, `GB`, `KR`, `JP`, `DE` ...) or subregion (`US-CA`, `GB-ENG`). Empty = worldwide. |
| `timeframe` | `today 12-m` | `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` (2004 to now), `custom`. |
| `customTimeRange` | | With `custom`: `YYYY-MM-DD YYYY-MM-DD` or hourly `YYYY-MM-DDTHH YYYY-MM-DDTHH`. |
| `category` | `0` | Google Trends category ID (0 = all). |
| `gprop` | `web` | `web`, `images`, `news`, `youtube`, `froogle` (Google Shopping). |
| `includeInterestOverTime` | `true` | |
| `includeInterestByRegion` | `false` | |
| `regionResolution` | `auto` | `COUNTRY`, `REGION`, `CITY`, `DMA`. Auto: worldwide gives countries, a country gives regions, a region gives cities. |
| `includeLowVolumeRegions` | `false` | |
| `includeRelatedQueries` / `includeRelatedTopics` | `false` | Top and rising lists per term. |
| `trendingNowCountries` | `[]` | Country codes for Trending now. |
| `trendingNowHours` | `"24"` | `"4"`, `"24"`, `"48"` or `"168"`. |
| `maxTrendingPerCountry` | `0` | 0 = all. |
| `outputFormat` | `item-per-term` | See below. |
| `language` | `en-US` | Language for dates, topic names and Trending now. |
| `timezoneOffset` | `0` | Minutes behind UTC (Google's `tz`). 0 = UTC, 300 = New York, -540 = Seoul. |
| `maxRetries` | `10` | Retries per request on 429 or network errors. |
| `proxyConfiguration` | Apify Proxy (datacenter) | Residential proxy also works but is rarely needed. |

### Output

Every item repeats the input it came from (`comparison`, `terms`, `geo`, `timeframe`, `category`, `gprop`), so you can mix many comparisons in one dataset and still filter easily.

#### `outputFormat: "item-per-term"` (default, compact)

One item per term and data type. Timelines and region lists are arrays.

```json
{
  "type": "interest_over_time",
  "term": "coffee",
  "comparison": "coffee vs tea vs matcha",
  "terms": ["coffee", "tea", "matcha"],
  "geo": "US",
  "timeframe": "today 12-m",
  "category": 0,
  "gprop": "web",
  "resolvedTimeRange": "2025-10-02 2026-10-02",
  "resolution": "WEEK",
  "average": 76,
  "peakValue": 100,
  "latestValue": 70,
  "timeline": [
    { "date": "2026-09-20", "timestamp": 1789862400, "formattedTime": "Sep 20 – 26, 2026", "value": 76, "isPartial": false },
    { "date": "2026-09-27", "timestamp": 1790467200, "formattedTime": "Sep 27 – Oct 3, 2026", "value": 70, "isPartial": true }
  ],
  "scrapedAt": "2026-10-02T11:58:23.507Z"
}
```

```json
{
  "type": "related_queries",
  "term": "coffee",
  "comparison": "coffee vs tea vs matcha",
  "geo": "US",
  "timeframe": "today 12-m",
  "top": [ { "rank": 1, "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": [ { "rank": 1, "query": "sports scores today", "value": 5350, "formattedValue": "Breakout", "link": "..." } ]
}
```

```json
{
  "type": "interest_by_region",
  "term": "coffee",
  "geo": "US",
  "resolution": "REGION",
  "regions": [ { "geoCode": "US-WY", "geoName": "Wyoming", "value": 100, "hasData": true } ]
}
```

```json
{
  "type": "trending_now",
  "geo": "KR",
  "hours": 24,
  "rank": 1,
  "title": "한국 대 베네수엘라",
  "searchVolume": 200000,
  "increasePercentage": 1000,
  "startedAt": "2026-10-02T10:00:00.000Z",
  "endedAt": null,
  "active": true,
  "categories": ["Sports"],
  "relatedQueries": ["한국 대 베네수엘라", "베네수엘라 축구 국가대표팀", "..."],
  "exploreUrl": "https://trends.google.com/trends/explore?q=...&geo=KR&date=now%201-d",
  "source": "trending-now"
}
```

#### `outputFormat: "row-per-point"` (flat, for Google Sheets and Excel)

- Interest over time: one row per date per comparison, with one column per term in `values` (`values.coffee`, `values.tea` in CSV).
- Interest by region: one row per region per comparison, with one column per term.
- Related queries and topics: one row per query or topic, with `list` = `top` or `rising` and `rank`.

```json
{ "type": "interest_over_time", "comparison": "coffee vs tea", "geo": "US", "timeframe": "today 12-m", "date": "2026-09-20", "isPartial": false, "values": { "coffee": 73, "tea": 32 } }
```

Row-per-point produces many more results (for example 52 weekly rows instead of 2 items for a 2-term, 12-month comparison), so it costs more. Use it when you want the data straight in a spreadsheet.

A run summary (items, errors and HTTP statistics per comparison) is saved to the key-value store as `RUN_SUMMARY`.

### Pricing

Pay per result: you pay only for items saved to the dataset. No monthly fee, and Apify platform usage and proxy are included.

Typical costs with the default `item-per-term` format:

| Job | Results |
|---|---|
| 1 comparison of 2 terms, interest over time | 2 |
| Same + interest by region + related queries | 6 |
| Trending now, 1 country, all trends (24 h) | 50 to 500 |

### Limits and notes

- Values are relative (0-100) within each comparison, exactly as on Google Trends. Terms on different lines are not on the same scale.
- Google Trends allows at most 5 terms per comparison. All terms in a comparison use the same location and time range.
- Google rate-limits automated traffic. The actor handles this with session rotation and backoff, so runs with many comparisons take longer (about 1 to 3 seconds per request, plus waiting time when Google slows us down).
- Related topics (beta): Google currently hides related topics from most automated clients (the API answers with an empty list). The actor retries once with a fresh session; if Google still returns nothing, no item is saved, so you are not charged, and the run summary notes it. Related queries are not affected.
- Very small search volumes return all zeros (Google's own behaviour).
- Trending now uses the same data as trends.google.com/trending. If that endpoint is unavailable the actor falls back to the public Trending now RSS feed (fewer fields, about 10 to 25 trends).
- The data is aggregated and anonymous. No personal data is collected.

### Use cases

- **SEO and content planning**: find rising queries and seasonal peaks before you write.
- **Market and product research**: compare brands, products or features over time and by country.
- **E-commerce**: spot seasonality and trending products (use `gprop: froogle` for Google Shopping).
- **AI agents and MCP clients**: one call returns structured trend data with the input echoed in every item.
- **Newsrooms and social media teams**: schedule Trending now every hour for the countries you cover.

### Support

Missing a field or a Google Trends feature? Open an issue on the Issues tab.

# Actor input Schema

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

Each line is one Google Trends comparison. Put up to 5 terms on a line separated by commas to compare them on the same 0-100 scale, e.g. "coffee, tea, matcha". Use one term per line to get each term on its own scale.

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

Country or subregion code as used by Google Trends: US, GB, DE, KR, JP, US-CA, GB-ENG ... Leave empty for worldwide.

## `timeframe` (type: `string`):

Google picks the data resolution from the range: minutes or hours for short ranges, days up to 9 months, weeks up to 5 years, months beyond.

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

Used only when Time range is Custom. Format "YYYY-MM-DD YYYY-MM-DD", e.g. "2024-01-01 2024-12-31". Hourly: "2024-01-01T10 2024-01-07T22" (max 7 days).

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

0 = all categories. Examples: 7 Finance, 12 Business & Industrial, 18 Shopping, 44 Beauty & Fitness, 45 Health, 71 Food & Drink, 958 Jobs, 5 Computers & Electronics.

## `gprop` (type: `string`):

Which Google property to measure.

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

Timeline of relative interest (0-100) for each term.

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

Relative interest per country, region or city for each term.

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

Level of detail for Interest by region.

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

Same as the checkbox on the Google Trends website.

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

Queries people also searched for, per term.

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

Topics people also searched for, per term. Beta: Google currently hides related topics from most automated clients, so this list is often empty. Empty results are not saved and not charged.

## `trendingNowCountries` (type: `array`):

Country codes for the Google Trends 'Trending now' list (what is spiking in search right now), e.g. US, GB, KR, JP, IN. Can be used with or without search terms.

## `trendingNowHours` (type: `string`):

Trends that started within this window.

## `maxTrendingPerCountry` (type: `integer`):

0 means all (usually 50 to 500 depending on country and window).

## `outputFormat` (type: `string`):

item-per-term returns one result per term and data type. row-per-point returns one flat row per date, region or related query, which is easier in Google Sheets or Excel but produces more results.

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

Language for formatted dates, topic names and Trending now, e.g. en-US, de, ko, ja.

## `timezoneOffset` (type: `integer`):

Same as Google's tz parameter: minutes behind UTC. 0 = UTC, 300 = New York (EST), -540 = Seoul.

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

On rate limits (HTTP 429) the actor rotates the session and proxy IP and waits with exponential backoff.

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

Google Trends rate-limits datacenter IPs. The default works for most runs.

## Actor input object example

```json
{
  "searchTerms": [
    "coffee, tea"
  ],
  "geo": "US",
  "timeframe": "today 12-m",
  "category": 0,
  "gprop": "web",
  "includeInterestOverTime": true,
  "includeInterestByRegion": false,
  "regionResolution": "auto",
  "includeLowVolumeRegions": false,
  "includeRelatedQueries": false,
  "includeRelatedTopics": false,
  "trendingNowCountries": [],
  "trendingNowHours": "24",
  "maxTrendingPerCountry": 0,
  "outputFormat": "item-per-term",
  "language": "en-US",
  "timezoneOffset": 0,
  "maxRetries": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

All saved Google Trends results (interest over time, by region, related queries and topics, trending now).

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

Items, errors and HTTP statistics per comparison and trending country.

# 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",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("ctriolab/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",
    "proxyConfiguration": { "useApifyProxy": True },
}

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

```

## MCP server setup

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