# Google Trends API — interest over time, region, related queries (`alxlin/google-trends-api`) Actor

Google Trends data as JSON: interest over time, interest by region, related queries/topics for any keyword, plus trending searches per country. HTTP-only, correct multi-keyword semantics, no infinite retries. Pay per keyword×widget.

- **URL**: https://apify.com/alxlin/google-trends-api.md
- **Developed by:** [Alex Lin](https://apify.com/alxlin) (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 $8.00 / 1,000 keyword × widget 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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

**Google Trends as clean JSON — interest over time, interest by region, related queries/topics, and
trending-now searches for any keyword and country.** HTTP-only (no browser), pay only for data that actually
comes back, and built specifically to fix the reliability problems that plague the existing Google Trends
scrapers on the Store. Point it at one or more keywords, pick which of the four data types you want, and get
structured dataset items back in seconds — ready for the API, a schedule, an integration, or an MCP-connected
agent.

### Sample output

One dataset item per keyword × widget (plus one item per trending search). Interest-over-time for `bitcoin`
(US, last 12 months):

```json
{
  "keyword": "bitcoin",
  "widget": "interest_over_time",
  "geo": "US",
  "timeframe": "today 12-m",
  "category": 0,
  "gprop": "",
  "compare": false,
  "compared_with": null,
  "scale": "own_0_100",
  "average": null,
  "data": [
    { "time": "2025-09-07T00:00:00.000Z", "formatted_time": "Sep 7 – 13, 2025", "value": 22, "is_partial": false },
    { "time": "2025-09-14T00:00:00.000Z", "formatted_time": "Sep 14 – 20, 2025", "value": 25, "is_partial": false }
  ],
  "error": null,
  "fetched_at": "2026-09-13T19:44:29.364Z",
  "source_url": "https://trends.google.com/trends/explore?q=bitcoin&date=today+12-m&geo=US&cat=0&gprop="
}
```

A `trending_now` item (no keyword needed — just pick a country):

```json
{
  "widget": "trending_now",
  "keyword": null,
  "geo": "US",
  "title": "cardinals vs chargers",
  "traffic": "20000+",
  "published_at": "2026-09-13T19:30:00.000Z",
  "news": [
    { "title": "Where to watch Cardinals vs Chargers", "url": "https://sports.yahoo.com/...", "source": "Yahoo Sports" }
  ],
  "fetched_at": "2026-09-13T19:44:23.709Z",
  "source_url": "https://trends.google.com/trending/rss?geo=US"
}
```

Both examples above are real output from a live run of this Actor (see [Why this Actor](#why-this-actor-instead-of-the-official-google-trends-scraper) for the numbers behind that claim). You can download any run's dataset as JSON, CSV, Excel, or HTML from the Storage tab or the API.

### Input

| Field | Type | Default | Notes |
|---|---|---|---|
| `keywords` | array of strings | — | Search terms, e.g. `"bitcoin"`, or a Trends topic id like `/m/05p0rrx`. Required unless you only want `trending_now`. |
| `widgets` | array | `interest_over_time`, `interest_by_region`, `related_queries`, `related_topics` | Which data types to fetch. One dataset item (and one charge) per keyword × widget; `trending_now` charges per trend instead. |
| `geo` | string | `""` (worldwide) | ISO country code (`US`, `GB`, `DE`) or region (`US-CA`). |
| `timeframe` | string | `"today 12-m"` | Trends syntax: `now 1-H`, `now 7-d`, `today 1-m`, `today 5-y`, `all`, or a custom `"2024-01-01 2024-12-31"` range. |
| `category` | integer | `0` | Google Trends category id (0 = all). |
| `gprop` | string | `""` | Search vertical: web, `images`, `news`, `youtube`, `froogle` (Shopping). |
| `compare` | boolean | `false` | See [Compare vs. separate](#compare-vs-separate-the-bug-we-fixed) below — this is the setting the official scraper gets wrong. |
| `resolution` | string | auto | `COUNTRY` / `REGION` / `CITY` / `DMA` for `interest_by_region`. |
| `hl` | string | `"en-US"` | UI language for labels and related-query text. |
| `trending_geo` | string | `"US"` | Country for the `trending_now` widget. |
| `maxAttemptsPerKeyword` | integer | `3` | How many fresh sessions to retry per keyword before giving up on the widgets still missing (partial results are always kept — see [Reliability](#why-this-actor-instead-of-the-official-google-trends-scraper)). |
| `proxyConfiguration` | object | Apify residential proxy | Google throttles by IP. Residential proxy with one session per keyword is the reliable setting; without one, the Actor runs direct with pacing and backoff — slower, and it works less often, but it still works. |

#### Compare vs. separate (the bug we fixed)

Turn **`compare` on** to fetch up to 5 keywords in a single request, sharing one 0–100 scale — exactly like the
"Compare" view on trends.google.com. Numbers become comparable across keywords, and `interest_by_region`
switches to each keyword's *share* of the combined interest (`scale: "share_of_compared_pct"`).

Leave **`compare` off** (default) and every keyword gets its own request, each independently normalised to
its own peak = 100 (`scale: "own_0_100"`). This is the correct default for "how has interest in X changed
over time" — mixing it up with compare mode is exactly the open issue on the official actor titled *"MCP tool
interface isn't passing the isMultiple flag correctly"*. We expose the distinction explicitly in every item's
`scale` and `compare` fields so you never have to guess which mode produced a number.

### Pricing

Pay per event, in USD (Bronze/Silver/Gold plans get automatic discounts):

| Event | Price | When it's charged |
|---|---|---|
| Actor start | $0.005 | Once per run. |
| Keyword × widget result | **$0.01** (primary) | Once per keyword × widget that returned data. Widgets with no data (e.g. an empty `related_topics` list) are not charged. |
| Trending search | $0.001 | Once per trending item returned by `trending_now`. |

Worked examples:

- **1 keyword, all 4 widgets** (interest over time + by region + related queries + related topics):
  4 × $0.01 + $0.005 start ≈ **$0.045**.
- **1 keyword, `interest_over_time` only, plus `trending_now` for a country** (the default input — a
  \~5-second run): 1 × $0.01 + 10 × $0.001 + $0.005 start ≈ **$0.025** for 11 items.
- **5 keywords compared** (`compare: true`, all widgets): `interest_over_time` and `interest_by_region` are
  shared across the 5 keywords (2 charges total), `related_queries` is per-keyword (5 charges); `related_topics`
  isn't offered in compare mode by Google, so it falls back to one extra request per keyword if you ask for it.
  Roughly 5–10 charges depending on which widgets you pick, always cheaper per keyword than fetching each one
  as a separate run.

The minimum spend guard (`minimalMaxTotalChargeUsd`) is $0.05 — well within reach of an agent calling this
tool with a small budget.

### Why this Actor instead of the official Google Trends Scraper

The official `apify/google-trends-scraper` has 12,979 users but a **~28% failure rate over the last 30 days**
and 68 issue reports, with recurring titles like *"Runs with infinite loop and no result"*, *"keep failing"*,
and *"MCP tool interface isn't passing the isMultiple flag correctly"*. This Actor was built specifically to
fix those three problems:

1. **No infinite loops.** Every keyword's fetch is bounded — a fixed number of session attempts
   (`maxAttemptsPerKeyword`), each with its own bounded backoff. If Google keeps throttling a widget, the run
   gives up on *that widget only*, keeps every result it already has, and moves on. A run either finishes or
   fails fast; it never hangs.
2. **Correct multi-keyword semantics.** The `compare` flag (above) is explicit and documented, and every
   output item states which scale it's on. No silent mixing of "own 0–100" and "shared 0–100" values.
   Related-topics data (which Google blanks out entirely for logged-out sessions) is reported as an honest
   empty result with an explanation, not a silent failure.
3. **HTTP-only, cheap, and fast.** No headless browser — a warm session, Google's own internal JSON endpoints,
   and ~800 ms pacing between calls. A typical single-keyword run finishes in seconds, not minutes.

Not affiliated with Google. Google Trends is a Google Inc. trademark; data returned is the same aggregate,
non-personal search-interest data shown publicly at [trends.google.com](https://trends.google.com).

### Use cases

- **SEO & content planning** — find rising queries and topics around a subject before you write about it.
- **Market & brand research** — track interest in a product, competitor, or industry over time and by region.
- **Trading/crypto signal research** — correlate search interest with price action (see the sample output above).
- **News & culture monitoring** — pull the daily `trending_now` feed for any country into a dashboard or bot.
- **Agents & automations** — flat input, small default budget, and typed dataset fields make this a natural
  MCP tool for "what's trending" or "how has interest in X changed" questions.

### How to use

1. Open the Input tab and fill in `keywords` (or skip them and just turn on `trending_now`).
2. Pick which `widgets` you want, a `geo`/`timeframe`, and leave `proxyConfiguration` on Apify's residential
   proxy for the most reliable runs (recommended; the Actor also works without a proxy, just less
   consistently at scale).
3. Click **Start**. Dataset items appear as they're fetched — trending-now items first (fastest), then one
   set per keyword.
4. Export the dataset as JSON/CSV/Excel, or pull it via the API for automations and schedules.

### Output fields

| Field | Description |
|---|---|
| `keyword` | Search term (`null` for `trending_now` items). |
| `widget` | `interest_over_time` | `interest_by_region` | `related_queries` | `related_topics` | `trending_now`. |
| `geo`, `timeframe`, `category`, `gprop` | The request parameters that produced this item. |
| `resolution` | `COUNTRY`/`REGION`/`CITY`/`DMA` (interest by region only). |
| `compare`, `compared_with`, `scale` | See [Compare vs. separate](#compare-vs-separate-the-bug-we-fixed). |
| `data` | The payload: time series points, region rows, or related-query/topic rows — shape depends on `widget`. |
| `title`, `traffic`, `published_at`, `news` | `trending_now` only. |
| `error` | Set (and not charged) when this widget couldn't be fetched, with a human-readable reason. |
| `fetched_at`, `source_url` | When it was fetched, and the matching `trends.google.com` page. |

### Limitations, legal, and support

Google does not offer an official Trends API; this Actor talks to the same internal JSON endpoints the
trends.google.com website uses, the same way the official Apify Trends actor and many open-source tools
(e.g. the archived `pytrends` library) do. `related_topics` is genuinely empty for logged-out sessions — that's
Google's behavior, not a bug here. At high volume, use the built-in residential proxy option for consistent
results; Google throttles aggressively per IP. Data returned is aggregate, non-personal search-interest data,
publicly viewable on trends.google.com for anyone.

Found a bug or want a feature? Use the Issues tab on this Actor's page — we aim to respond within a few days.

# Actor input Schema

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

Search terms, e.g. "bitcoin" or "/m/05p0rrx" (topic id). Each keyword is fetched on its own (own 0–100 scale) unless "Compare keywords" is on. Not needed if you only want trending\_now.

## `widgets` (type: `array`):

Which Google Trends widgets to fetch. One dataset item (and one keyword-widget charge) per keyword × widget; trending\_now is charged per trend item.

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

ISO 3166 country code (US, GB, DE), region (US-CA) or empty for worldwide.

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

Google Trends syntax: 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 "2024-01-01 2024-12-31".

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

Google Trends category id (0 = all categories; e.g. 7 = Finance, 5 = Computers & Electronics). Same numbers as the cat= parameter in Trends URLs.

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

Which Google search vertical to pull Trends data from ('' = regular web search).

## `compare` (type: `boolean`):

ON: up to 5 keywords go into ONE Trends request and share a single 0–100 scale, exactly like the Trends compare view (values across keywords are comparable; region data becomes each keyword's share in %). OFF (default): one request per keyword, each normalised to its own peak = 100 — numbers are NOT comparable across keywords. This is the isMultiple behaviour other actors get wrong.

## `resolution` (type: `string`):

Granularity for interest\_by\_region.

## `hl` (type: `string`):

UI language for labels and related lists, e.g. en-US, de-DE, ja-JP.

## `trending_geo` (type: `string`):

Country code for the trending\_now widget (US, GB, IN, BR, …).

## `maxAttemptsPerKeyword` (type: `integer`):

How many fresh sessions (new proxy IP + cookie) to try per keyword before giving up on the widgets that are still missing. Partial results are always kept.

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

Google throttles by IP (~10–15 API calls per burst). Residential proxies with one session per keyword are the reliable setting. Without any proxy the actor runs direct with pacing and exponential backoff.

## Actor input object example

```json
{
  "keywords": [
    "bitcoin"
  ],
  "widgets": [
    "interest_over_time",
    "trending_now"
  ],
  "geo": "US",
  "timeframe": "today 12-m",
  "category": 0,
  "gprop": "",
  "compare": false,
  "resolution": "",
  "hl": "en-US",
  "trending_geo": "US",
  "maxAttemptsPerKeyword": 3,
  "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 = {
    "keywords": [
        "bitcoin"
    ],
    "widgets": [
        "interest_over_time",
        "trending_now"
    ],
    "geo": "US",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("alxlin/google-trends-api").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"],
    "widgets": [
        "interest_over_time",
        "trending_now",
    ],
    "geo": "US",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("alxlin/google-trends-api").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"
  ],
  "widgets": [
    "interest_over_time",
    "trending_now"
  ],
  "geo": "US",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call alxlin/google-trends-api --silent --output-dataset

```

## MCP server setup

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

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/lXwlKS2lwxu71Vpjt/builds/hheE4a1gofa2AcVBz/openapi.json
