# Google Trends Scraper ($1.50/1K keywords) (`mathtec/google-trends`) Actor

Google Trends data for any keywords: interest over time, interest by region, related queries and topics, for any country, time range, category and Google property (web, YouTube, news, images, shopping). Compare up to 5 keywords. Failed keywords are free.

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

## Pricing

from $1.00 / 1,000 keyword results

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: interest over time, regions, related queries

Get Google Trends data for any keywords: **interest over time**, **interest by region**, **related queries** and
**related topics**, for any country or region, any time range, any category and any Google property (web search,
YouTube, news, images, Google Shopping). Compare up to 5 keywords on one scale, or fetch each keyword on its own.

- **Input:** keywords, plus optional location, time range, category and property.
- **Output:** one dataset row per keyword (or per comparison) with the series you asked for and a `summary`
  (average, peak and latest value per keyword).
- **Failed keywords are free:** a keyword Google refuses or blocks gives a row with `status: failed` and the reason,
  and is not charged.

### Input

| Field | Default | Notes |
|---|---|---|
| `keywords` | *(required)* | search terms, or Google topic ids such as `/m/05p0rrx` |
| `compareTogether` | `false` | `true`: up to 5 keywords on one 0-100 scale per row (more are split into groups of 5) |
| `geo` | `""` (worldwide) | `GB`, `US`, `DE`, `US-CA`, ... |
| `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`, or `YYYY-MM-DD YYYY-MM-DD` |
| `category` | `0` | Google Trends category id (0 = all) |
| `property` | `""` (web) | `images`, `news`, `youtube`, `froogle` (Shopping) |
| `interestOverTime` | `true` | the 0-100 time series |
| `interestByRegion` | `false` | 0-100 by country or region; `regionResolution` = COUNTRY, REGION, CITY or DMA |
| `relatedQueries` | `false` | top and rising related searches |
| `relatedTopics` | `false` | top and rising related topics (single keywords only) |
| `language`, `timezoneOffsetMinutes` | `en-US`, `0` | formatting of names and dates |

### Output example

```json
{
  "keyword": "bitcoin vs ethereum",
  "keywords": ["bitcoin", "ethereum"],
  "comparison": true,
  "geo": "GB",
  "timeframe": "today 12-m",
  "status": "ok",
  "hasData": true,
  "summary": {"bitcoin": {"average": 37.4, "peak": 100, "peakDate": "2025-11-16T00:00:00Z", "latest": 15, "latestIsPartial": true}},
  "averages": {"bitcoin": 37, "ethereum": 6},
  "interestOverTime": [{"date": "2025-10-19T00:00:00Z", "formattedTime": "Oct 19 – 25, 2025",
                        "values": {"bitcoin": 35, "ethereum": 6}, "isPartial": false}],
  "interestByRegion": [{"geoCode": "GB-ENG", "geoName": "England", "values": {"bitcoin": 86, "ethereum": 14}}],
  "relatedQueries": {"bitcoin": {"top": [{"query": "bitcoin price", "value": 100}], "rising": []}},
  "notes": []
}
```

Values are Google's relative interest (100 = the peak within the row's keywords, location and time range), not search
counts. The last point is often partial (`isPartial: true`) because the period is still running.

### Pricing

One price per keyword result (see the Pricing tab). Failed and rejected keywords, and keywords for which Google has no data (`hasData: false`), are not charged.

### Notes

- Related topics: Google currently returns empty related-topic lists to automated clients for most keywords; when that
  happens the row says so in `notes`. Google does not provide related topics for comparisons at all.
- Run statistics (requests, retries, proxy sessions, timings) are saved in the key-value store as `RUN_STATS`.

### Responsible use

You are responsible for how you use the data, including Google's terms.

# Actor input Schema

## `keywords` (type: `array`):

Search terms (or Google topic ids such as /m/05p0rrx). One row per keyword, or one row per comparison of up to 5 keywords when 'Compare together' is on.

## `compareTogether` (type: `boolean`):

Put up to 5 keywords on one 0-100 scale in a single Google Trends comparison (more than 5 are split into groups of 5; each row lists the keywords it compares).

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

Empty = worldwide. Country or region code as Google Trends uses them: GB, US, DE, US-CA, GB-SCT.

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

One of: 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; or a custom range 'YYYY-MM-DD YYYY-MM-DD' (from 2004).

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

Google Trends category id (0 = all categories).

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

Which Google search the interest comes from.

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

0-100 time series, plus average, peak and latest per keyword.

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

0-100 by country (worldwide) or region (inside a country).

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

Only used with 'Interest by region'.

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

Top and rising related searches per keyword.

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

Top and rising related topics (single keywords only; Google does not return them for comparisons). Google has recently returned these empty for automated clients; the row notes when that happens.

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

Language for region names and formatted dates (hl), e.g. en-US, en-GB, de.

## `timezoneOffsetMinutes` (type: `integer`):

Google's convention: UTC-5 = 300, UTC+1 = -60. 0 = UTC.

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

How requests reach Google. Leave the default unless you know you need another.

## Actor input object example

```json
{
  "keywords": [
    "bitcoin",
    "ethereum"
  ],
  "compareTogether": false,
  "geo": "",
  "timeframe": "today 12-m",
  "category": 0,
  "property": "",
  "interestOverTime": true,
  "interestByRegion": false,
  "regionResolution": "",
  "relatedQueries": false,
  "relatedTopics": false,
  "language": "en-US",
  "timezoneOffsetMinutes": 0,
  "proxyStrategy": "datacenter-then-residential"
}
```

# Actor output Schema

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

Dataset items: keyword, keywords, comparison, geo, timeframe, category, property, status (ok | failed | rejected), hasData, summary, interestOverTime, averages, interestByRegion, relatedQueries, relatedTopics (as requested), notes, fetchedAt; error when not ok.

## `runStats` (type: `string`):

Requests, HTTP 429s, proxy sessions and bytes downloaded, per row timing.

# 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 = {
    "keywords": [
        "bitcoin",
        "ethereum"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("mathtec/google-trends").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 = { "keywords": [
        "bitcoin",
        "ethereum",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("mathtec/google-trends").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 '{
  "keywords": [
    "bitcoin",
    "ethereum"
  ]
}' |
apify call mathtec/google-trends --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mathtec/google-trends"
        }
    }
}
```

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/qw1XxhAiMtrs9Vn0f/builds/cVb62Duwof5WwgPeC/openapi.json
