# Google Trends Scraper (`axlymxp/google-trends-scraper`) Actor

Google Trends data as JSON: interest over time, by country, state, metro or city, top and rising related queries, plus Trending Now searches with volume, growth and news. Compare up to 5 terms, paste Trends URLs, run hundreds of keywords. No browser, fast. Pay only for results.

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

## Pricing

from $1.00 / 1,000 dataset items

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

Get **Google Trends data as clean JSON**: interest over time, interest by country / state / metro / city, top and rising
(breakout) related queries, and today's **Trending Now** searches with search volume, growth and news. Paste search terms
or Google Trends URLs, compare up to 5 terms on one scale, and run hundreds of keywords per run.

It reads the same JSON API the Trends website uses, with no browser: a 40-keyword run takes under a minute. When
Google rate-limits an IP, the run switches to a new proxy session and repeats the search, so you get your rows instead
of a failed run.

### What data you get

#### Explore mode: one row per search term

| Field | Example | Notes |
| --- | --- | --- |
| `searchTerm` | `matcha` | keyword or topic id (`/m/02vqfm`) |
| `comparedWith` | `["coffee", "tea"]` | other terms on the same 0-100 scale (compare mode) |
| `geo`, `timeRange`, `timeRangeResolved` | `US`, `today 12-m`, `2025-10-14 2026-10-14` | |
| `category`, `property` | `0`, `web` | web, YouTube, News, Images or Shopping search |
| `hasData` | `true` | false when Google has too little search volume |
| `averageInterest`, `latestInterest`, `peakInterestDate` | `73.3`, `59`, `2026-04-12T00:00:00Z` | computed from the series |
| `interestOverTime[]` | `{date, label, value, isPartial}` | minute, hour, day, week or month points, as Google chooses for the range |
| `interestByRegion[]` | `{geoCode, geoName, value}` or `{coordinates, geoName, value}` | countries, sub-regions, US metros (DMA) or cities |
| `regionLevel` | `CITY` / `default` | `default` when Google has no data at the level you asked for |
| `relatedQueriesTop[]` | `{query, value, link}` | up to 25 |
| `relatedQueriesRising[]` | `{query, growthPercent, formattedValue, link}` | up to 25; `Breakout` = more than +5000% |
| `exploreUrl`, `scrapedAt` | | link to the same view on Google Trends |

#### Trending now mode: one row per trending search

| Field | Example |
| --- | --- |
| `rank`, `searchTerm`, `geo`, `timeWindowHours` | `1`, `roma vs real madrid`, `US`, `24` |
| `searchVolume` | `500000` (Google's bucket: 500K+) |
| `increasePercentage` | `1000` |
| `startedAt`, `endedAt`, `isActive` | ISO times; `endedAt` null while still trending |
| `categories` | `["Sports"]` |
| `trendBreakdown` | the related searches Google groups into this trend |
| `news[]` | `{title, url, source, publishedTimestamp, image}` (optional) |
| `exploreUrl` | |

### Use cases

- **SEO and content teams**: find rising queries before they peak, compare topic demand, plan seasonal content.
- **E-commerce and product research**: check demand curves and seasonality by country or state before launching or stocking a product.
- **Marketing agencies**: monthly trend reports per client keyword; regional interest for geo-targeted campaigns.
- **Newsrooms and social teams**: Trending Now by country with volume, growth and headlines, every hour.
- **Analysts and AI agents**: a time series per keyword as JSON for dashboards, forecasting and LLM pipelines.

### Input

| Parameter | Default | Description |
| --- | --- | --- |
| `mode` | `explore` | `explore` or `trendingNow` |
| `searchTerms` | | keywords or topic ids; one row each |
| `compareTerms` | `false` | compare in groups of up to 5 on one scale |
| `startUrls` | | Google Trends explore URLs (their own q, geo, date, cat, gprop are used) |
| `geo` | worldwide | `US`, `GB`, `US-CA`, `US-NY-501`... |
| `timeRange` | `today 12-m` | past hour ... 2004-present, or `custom` + `customTimeRange` (`2024-01-01 2024-12-31`) |
| `category` | `0` | Google Trends category id |
| `property` | `web` | `web`, `youtube`, `news`, `images`, `shopping` |
| `includeInterestOverTime` / `includeInterestByRegion` / `includeRelatedQueries` | `true` | turn off what you don't need for faster runs |
| `regionResolution` | `auto` | `COUNTRY`, `REGION`, `DMA`, `CITY` |
| `trendingGeos` | `["US"]` | trending now locations |
| `trendingHours` | `24` | 4, 24, 48 or 168 hours |
| `trendingCategories` | all | e.g. `Sports`, `Technology`, `Business and finance` |
| `trendingSort`, `maxTrends`, `onlyActiveTrends`, `includeTrendNews` | | ordering, limit, active only, add headlines |
| `proxyConfiguration` | Apify Residential | used only after Google rate-limits an IP |

#### Example input

Seven phones on YouTube search in the US, compared in groups of 5 + 2:

```json
{
    "mode": "explore",
    "searchTerms": [
        "iphone 17",
        "pixel 10",
        "galaxy s26",
        "oneplus 15",
        "xiaomi 16",
        "nothing phone",
        "motorola edge"
    ],
    "compareTerms": true,
    "geo": "US",
    "timeRange": "today 3-m",
    "property": "youtube",
    "regionResolution": "CITY"
}
```

#### Example output (real run, arrays shortened)

Google has no city data for compared terms on YouTube, so the row falls back to states (`regionLevel: default`).

```json
{
    "type": "explore",
    "searchTerm": "nothing phone",
    "comparedWith": [
        "motorola edge"
    ],
    "geo": "US",
    "timeRange": "today 3-m",
    "timeRangeResolved": "2026-07-14 2026-10-14",
    "category": 0,
    "property": "youtube",
    "hasData": true,
    "averageInterest": 58.26,
    "peakInterestDate": "2026-09-22T00:00:00Z",
    "latestInterest": 67,
    "interestOverTime": [
        {
            "date": "2026-07-14T00:00:00Z",
            "label": "Jul 14, 2026",
            "value": 63,
            "isPartial": false
        },
        {
            "date": "2026-07-15T00:00:00Z",
            "label": "Jul 15, 2026",
            "value": 56,
            "isPartial": false
        }
    ],
    "interestByRegion": [
        {
            "geoCode": "US-DC",
            "coordinates": null,
            "geoName": "District of Columbia",
            "value": 100
        },
        {
            "geoCode": "US-DE",
            "coordinates": null,
            "geoName": "Delaware",
            "value": 100
        }
    ],
    "regionLevel": "default",
    "relatedQueriesTop": [
        {
            "query": "nothing phone pro",
            "value": 100,
            "link": "https://trends.google.com/trends/explore?q=nothing+phone+pro&date=today+3-m&geo=US"
        }
    ],
    "relatedQueriesRising": [
        {
            "query": "nothing phone 4a pro pink",
            "growthPercent": 36900,
            "formattedValue": "Breakout",
            "link": "https://trends.google.com/trends/explore?q=nothing+phone+4a+pro+pink&date=today+3-m&geo=US"
        }
    ],
    "exploreUrl": "https://trends.google.com/trends/explore?q=nothing+phone%2Cmotorola+edge&date=today+3-m&geo=US&gprop=youtube",
    "scrapedAt": "2026-10-14T23:57:02Z"
}
```

### Scheduling and integrations

Schedule the actor (for example hourly Trending Now for 5 countries, or a weekly keyword report) in Apify Console →
Schedules, and send results to Google Sheets, Slack, a webhook, Make, Zapier or n8n. Every run's dataset can be
downloaded as JSON, CSV or Excel or read through the Apify API.

### Use it from AI assistants (MCP)

Through the Apify MCP server (`https://mcp.apify.com`), Claude, ChatGPT and other MCP clients can call this actor as a
tool: "compare search interest for matcha and coffee in the US over 5 years" returns the rows above.

### FAQ

**What do the numbers mean?** Google Trends values are relative (0-100) within the chosen time range and location:
100 is the peak. They are not absolute search counts. Trending Now `searchVolume` is Google's volume bucket (for example 200K+).

**Why compare terms?** Separately, each term has its own 0-100 scale. With `compareTerms` the values are on one shared scale,
like the comparison chart on the website.

**Are related topics included?** No. Google only serves related topics to browser sessions with a reCAPTCHA token.
Related queries (top and rising) are included.

**Why are some terms empty?** `hasData: false` means Google has too little search volume for that term, place and period.
Such rows are cheaper and still show you the term was checked.

**What if Google rate-limits?** The actor retries on a new proxy session and repeats the search (in a 150-keyword test run,
all 10 rate-limit responses were recovered). Searches that still fail are listed in the run's `FAILED_SEARCHES` record and
the rest of the run continues; to retry them, start a new run with just those terms.

**How much data per term?** Interest over time has up to ~270 points (monthly since 2004 for `all`); regions up to 250
countries or 200 cities; related queries up to 25 top + 25 rising.

**Is it legal?** The actor reads public, aggregated, anonymous statistics that Google publishes on trends.google.com.
It collects no personal data. Check that your use complies with Google's terms and your local law.

This actor is not affiliated with or endorsed by Google.

# Actor input Schema

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

Explore returns one row per search term. Trending now returns one row per trending search.

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

Keywords or topic ids (like /m/02vqfm). Each term is one row. Explore mode.

## `compareTerms` (type: `boolean`):

On: terms are compared in groups of up to 5 (values are relative across the group, like the Trends compare view). Off: every term is scraped on its own 0-100 scale.

## `startUrls` (type: `array`):

Paste trends.google.com/trends/explore?... URLs. Their own terms, geo, date, category and property are used.

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

Empty = worldwide. Country code (US, GB, DE), region (US-CA, GB-ENG) or US metro (US-NY-501).

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

Data resolution follows Google: minutes, hours, days, weeks or months.

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

Used when Time range = Custom. Format: 2024-01-01 2024-12-31

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

Google Trends category id, 0 = all categories (for example 71 = Food & Drink, 12 = Business & Industrial, 958 = Shopping).

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

Which Google search to measure, as in the Trends property filter.

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

Time series of search interest (0-100) for each term.

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

Search interest per country, region, metro or city.

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

Geographic level for interest by region.

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

Also return regions where Google has too little data (value 0).

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

Top and rising (breakout) related search queries for each term.

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

How many searches run in parallel.

## `trendingGeos` (type: `array`):

Country (US, GB, IN) or region (US-CA) codes. Trending now mode.

## `trendingHours` (type: `string`):

Time window of the trending list.

## `trendingSort` (type: `string`):

Order of the trending list before Max trending searches is applied.

## `trendingCategories` (type: `array`):

Empty = all categories.

## `onlyActiveTrends` (type: `boolean`):

Skip trends that already ended.

## `maxTrends` (type: `integer`):

Upper limit of trending searches returned per location (you pay per row).

## `includeTrendNews` (type: `boolean`):

Up to 3 headlines with source and link per trend (one extra request per trend).

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

Interface language for labels and Trending now (en-US, de, fr, ja ...).

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

Requests go direct first. When Google rate-limits an IP (HTTP 429) the run switches to a new proxy session. Residential works best; Google throttles shared datacenter IPs.

## Actor input object example

```json
{
  "mode": "explore",
  "searchTerms": [
    "coffee",
    "matcha"
  ],
  "compareTerms": false,
  "startUrls": [
    {
      "url": "https://trends.google.com/trends/explore?q=coffee,tea&geo=US&date=today%205-y"
    }
  ],
  "geo": "",
  "timeRange": "today 12-m",
  "category": 0,
  "property": "web",
  "includeInterestOverTime": true,
  "includeInterestByRegion": true,
  "regionResolution": "auto",
  "includeLowVolumeRegions": false,
  "includeRelatedQueries": true,
  "maxConcurrency": 3,
  "trendingGeos": [
    "US"
  ],
  "trendingHours": "24",
  "trendingSort": "relevance",
  "onlyActiveTrends": false,
  "maxTrends": 100,
  "includeTrendNews": false,
  "language": "en-US",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

No description

# 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": "explore",
    "searchTerms": [
        "coffee",
        "matcha"
    ],
    "trendingGeos": [
        "US"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

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

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

```

## MCP server setup

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