# Google Trends API: Bulk Trends, Trending Now & Change Monitor (`shan-abbas/google-trends-api`) Actor

Reliable Google Trends scraper: interest over time, by region, related queries & topics, 100+ keywords on one scale (anchor-normalized), Trending Now, and change-only monitoring. Agent/MCP-friendly output.

- **URL**: https://apify.com/shan-abbas/google-trends-api.md
- **Developed by:** [Shan Abbas](https://apify.com/shan-abbas) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 keyword reports

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 API — Bulk Google Trends Scraper, Trending Now & Change Monitoring

**Scrape Google Trends reliably at scale**: interest over time, interest by region, related queries (top + rising + Breakout), related topics, **100+ keywords on one comparable 0–100 scale**, daily **Trending Now** searches, and **change-only monitoring** for schedules and webhooks. No browser, no login, no Google API key. Works as a **pytrends alternative** (pytrends was archived in April 2025) and is ready for **AI agents, MCP, n8n, Make and Zapier**.

### Why this Google Trends scraper?

- **Built for reliability.** It uses a pool of cookie-warmed sessions, rate limiting per session, exponential backoff that retires bad sessions, and **automatic RESIDENTIAL proxy fallback** used only for keywords that keep getting rate-limited. When a keyword fails, it gets a clear error item instead of crashing or hanging the run. Runs never "succeed" with an empty dataset: if every keyword fails, the run fails with an actionable message.
- **You only pay for results.** Error and no-data items are free.
- **Compare 100+ keywords on one scale.** Google caps a comparison at 5 terms and rescales every request separately. Our `compareMany` mode chains 5-term batches through a shared **anchor keyword** and rescales everything onto one 0–100 scale. You get one ranked list.
- **Monitoring mode (`changedOnly`).** It stores a snapshot in a named key-value store and returns only keywords whose interest moved more than X% since the last run, or that gained new **Breakout** queries. Pair it with a daily schedule and a webhook.
- **Output that suits agents.** `outputFormat: "agentSummary"` gives you one sentence plus key numbers per keyword (avg, latest, peak, trend direction, top regions, rising queries). It is small and cheap in tokens.
- **Trending Now** for any number of countries, with approximate traffic, images and linked news articles.

### What data can I get from Google Trends?

| Mode | Output per keyword |
|---|---|
| `interestOverTime` | timeline `[{date, value 0-100, isPartial}]`, plus average, latest complete value, peak, peak date, trend direction and % change of the recent period vs the average |
| `interestByRegion` | sub-regions (states/provinces, or countries if worldwide) sorted by interest |
| `relatedQueries` | top and rising queries with an `isBreakout` flag and explore links |
| `relatedTopics` | top and rising topics (entity id, title, type) |
| `compareMany` | the same stats on a **shared scale**, plus `rank`, `scaleFactor` and `lowPrecision` flag |
| `trendingNow` | title, approxTraffic (also as a number), pubDate, picture, news\[] |
| `changedOnly` | a full report, but only for keywords that changed, plus `change.reasons` |

The four keyword modes are merged into **one report per keyword**, so you pay one `keyword-report` event per keyword.

### Input example

```json
{
  "searchTerms": ["electric bike", "e-scooter", "https://trends.google.com/trends/explore?q=cargo%20bike&geo=GB"],
  "modes": ["interestOverTime", "interestByRegion", "relatedQueries"],
  "geo": "US",
  "timeRange": "today 12-m",
  "category": 0,
  "property": "web",
  "language": "en-US",
  "outputFormat": "agentSummary",
  "proxyConfiguration": { "useApifyProxy": true }
}
```

- `timeRange`: `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 `2024-01-01 2024-06-30`.
- `property`: `web`, `news`, `images`, `youtube` or `froogle` (Google Shopping).
- **compareMany:** `{"modes":["compareMany"], "searchTerms":[...150 terms...], "anchorKeyword":"yoga"}`. Pick an anchor of middling popularity. Results from batches where the anchor is near 0 are flagged `lowPrecision`.
- **Monitoring:** `{"modes":["changedOnly"], "snapshotStoreName":"my-trends", "snapshotKey":"ebikes-us", "changeThresholdPct":20}` on a daily schedule.
- **Trending Now:** `{"modes":["trendingNow"], "trendingGeos":["US","GB","PK"]}`.

### Output example (`agentSummary`)

```json
{
  "keyword": "coffee", "geo": "US", "timeRange": "today 12-m", "status": "ok",
  "summary": "\"coffee\" (US, today 12-m): avg interest 76.94/100, latest 71, peak 100 on 2026-04-12, trend flat (-4.9% recent vs avg). Top regions: Hawaii 100, ... Rising queries: ...",
  "averageValue": 76.94, "latestValue": 71, "peakValue": 100, "trendDirection": "flat",
  "topRegions": ["Hawaii", "..."], "risingQueries": ["..."], "breakoutQueries": ["..."],
  "exploreUrl": "https://trends.google.com/trends/explore?q=coffee&geo=US&date=today+12-m"
}
```

A failed keyword produces `{"keyword": "...", "status": "error", "errorType": "RateLimitError", "errorMessage": "..."}`. Each run also writes `RUN_SUMMARY` to the default key-value store with the success rate, average time and bytes per keyword, and HTTP status counts.

### Pricing (pay per event)

| Event | Price |
|---|---|
| `keyword-report` (one successful keyword report or compareMany keyword) | **$2.50 / 1,000** |
| `trending-item` (one Trending Now search) | $0.50 / 1,000 |
| Error / no-data items | free |

Set `maxItems` or the platform's "max total charge" to cap spending. The Actor stops cleanly when the limit is reached.

### Tips for reliability and cost

- Keep `maxConcurrency` at 3–5 when using datacenter proxy. Each session uses its own IP and cookie.
- Residential fallback is on by default. Each keyword uses about 25–40 KB (12-month range), so residential traffic stays cheap.
- Google Trends values are relative (0–100), not absolute search volumes.

### Use with AI agents / MCP

Call it from the Apify MCP server or the API with `outputFormat: "agentSummary"` and a small `maxItems`. The input fields have descriptions written for LLM tool use.

### FAQ

**Is it legal to scrape Google Trends?** Google Trends shows aggregated, anonymized data with no personal data. You are responsible for following Google's terms and the laws that apply to you.
**Why do my numbers differ from the website?** Google samples its data. Values can shift by a few points between requests, and the last point is often partial (`isPartial: true`).
**Related topics are empty?** Google currently returns empty related-topic lists to many API-style clients. The field is still present, so it won't break your pipeline.

# Actor input Schema

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

Keywords to analyze (or full trends.google.com/trends/explore URLs, whose geo/date/cat/gprop override the defaults below). Up to 5,000. Not needed for trendingNow-only runs.

## `modes` (type: `array`):

What to collect. interestOverTime / interestByRegion / relatedQueries / relatedTopics are merged into ONE report per keyword. compareMany = all keywords on one 0-100 scale via anchor chaining. trendingNow = daily trending searches (RSS) for trendingGeos. changedOnly = emit only keywords whose trend changed since the last run's snapshot.

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

ISO country or sub-region code, e.g. US, GB, PK, US-CA. Empty = worldwide.

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

Preset or custom range "YYYY-MM-DD YYYY-MM-DD" (custom only via JSON/API).

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

Google Trends category id (0 = all categories; e.g. 71 = Food & Drink, 7 = Finance).

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

Which Google search property to measure.

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

Interface language for names of regions/topics, e.g. en-US, de, fr-FR.

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

agentSummary is ideal for AI agents / MCP: small, flat, token-cheap.

## `anchorKeyword` (type: `string`):

Keyword included in every 5-term batch to chain scales. Choose a stable, mid-popularity term. Default: first search term.

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

Country codes for trendingNow mode. Default: geo or US.

## `snapshotStoreName` (type: `string`):

Named key-value store that keeps the previous run's values. Named stores persist between runs.

## `snapshotKey` (type: `string`):

Use different keys for different monitoring jobs sharing a store.

## `changeThresholdPct` (type: `integer`):

Emit a keyword when its latest or average interest moved at least this much vs the snapshot, or a new Breakout related query appeared.

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

Stop after this many dataset items (0 = no limit). Caps cost.

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

Parallel sessions. Each session has its own cookie + proxy IP.

## `requestDelayMs` (type: `integer`):

Per-session politeness delay (jittered).

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

Each retry uses a fresh session (new cookie + IP) with exponential backoff. After half the retries, the residential fallback is used.

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

Apify Proxy recommended for bulk runs. Datacenter groups are tried first.

## `residentialFallback` (type: `boolean`):

If a keyword keeps getting rate-limited, retry it through Apify RESIDENTIAL proxy (billed per GB, ~35 KB/keyword).

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

Google's tz param (minutes behind UTC; 0 = UTC). Affects hourly/daily bucket boundaries.

## Actor input object example

```json
{
  "searchTerms": [
    "electric bike",
    "e-scooter"
  ],
  "modes": [
    "interestOverTime",
    "relatedQueries"
  ],
  "geo": "",
  "timeRange": "today 12-m",
  "category": 0,
  "property": "web",
  "language": "en-US",
  "outputFormat": "full",
  "trendingGeos": [
    "US"
  ],
  "snapshotStoreName": "google-trends-snapshots",
  "snapshotKey": "default",
  "changeThresholdPct": 20,
  "maxItems": 0,
  "maxConcurrency": 3,
  "requestDelayMs": 800,
  "maxRequestRetries": 6,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "residentialFallback": true,
  "timezoneOffset": 0
}
```

# Actor output Schema

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

Default dataset: interest over time, regions, related queries/topics, compareMany rankings, or Trending Now rows.

## `errors` (type: `string`):

Dataset view filtered to error items only.

## `trending` (type: `string`):

Dataset view for trendingNow mode rows.

## `runSummary` (type: `string`):

Success rate, timing, bytes, HTTP status counts, and pay-per-event charges for the run.

# 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": [
        "electric bike",
        "e-scooter"
    ],
    "modes": [
        "interestOverTime",
        "relatedQueries"
    ],
    "trendingGeos": [
        "US"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("shan-abbas/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 = {
    "searchTerms": [
        "electric bike",
        "e-scooter",
    ],
    "modes": [
        "interestOverTime",
        "relatedQueries",
    ],
    "trendingGeos": ["US"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("shan-abbas/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 '{
  "searchTerms": [
    "electric bike",
    "e-scooter"
  ],
  "modes": [
    "interestOverTime",
    "relatedQueries"
  ],
  "trendingGeos": [
    "US"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call shan-abbas/google-trends-api --silent --output-dataset

```

## MCP server setup

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