# Google Trends Scraper & API - Interest, Regions, Trending (`ivan-petrus-g/google-trends-api`) Actor

Reliable Google Trends scraper and API: interest over time, interest by region/city, top related queries, multi-keyword comparison and trending searches for any country. Decoy-filtered rising queries. Auto-retries, 429 handling and proxy rotation built in.

- **URL**: https://apify.com/ivan-petrus-g/google-trends-api.md
- **Developed by:** [Ivan Petrus](https://apify.com/ivan-petrus-g) (community)
- **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 & API: Interest Over Time, Regions, Top Queries & Trending Now

**Google Trends Scraper and unofficial Google Trends API** with data you can rely on: interest over time, interest by region/city, **top related queries**, multi-keyword comparison and live **Trending now** searches for any country. Rising queries are included too, **decoy-filtered** (see below). You can export to JSON, CSV or Excel, or call it from the API, Make, n8n, Zapier or AI agents (MCP).

Built for **reliability**: automatic retries with exponential backoff, HTTP 429 (rate-limit) handling, proxy session rotation, automatic switch to residential proxies when Google blocks, and clear error rows instead of silent gaps. **Failed queries are never charged.**

### Sample output

One keyword result from a real Apify cloud run (Oct 2026), shortened (the full row has 53 weekly points and 72 countries):

```json
{
  "searchTerm": "claude",
  "geo": "Worldwide",
  "timeRange": "today 12-m",
  "interestOverTime": [{"date": "2025-10-05", "values": {"claude": 17}}, {"date": "2025-10-12", "values": {"claude": 18}}, …],
  "interestByRegion": [{"geoCode": "CN", "geoName": "China", "values": {"claude": 100}}, {"geoCode": "SG", "geoName": "Singapore", "values": {"claude": 45}}, …],
  "relatedQueries": {"claude": {"top": [{"query": "claude ai", "value": 100}, {"query": "claude code", "value": 58}, {"query": "anthropic claude", "value": 23}, …]}},
  "status": "ok"
}
```

### What you get

| Data | Status | Details |
|---|---|---|
| 📈 Interest over time | ✅ Reliable | Full timeline (0–100) for each term, plus a **summary per term**: average, peak, peak date, latest value, % change, rising/falling/stable |
| 🌍 Interest by region | ✅ Reliable | Countries (worldwide), or regions/states, cities and US metros (DMA) inside a country. If Google has no city data, it falls back automatically to metros or regions |
| 🔎 Top related queries | ✅ Reliable | The top 25 related queries per term with relative values |
| ⚖️ Comparison | ✅ Reliable | Compare up to 5 terms in one query (same scale), or analyze hundreds of terms separately |
| 🔥 Trending now | ✅ Reliable | Live trending searches for any country: volume, growth %, start time, active/ended, related queries, categories |
| 🔗 Trends URLs | ✅ | Paste any `trends.google.com/trends/explore` URL; its terms, geo, date, category and search type are used as-is |
| 🧪 Rising queries | Filtered, experimental | Rising/"Breakout" queries after our **decoy filter**. Removed entries stay visible in `suspectedDecoys` with the reason |
| 🧩 Related topics | Usually unavailable | Google currently withholds related topics for automated requests. When it does, `relatedTopics` is `null` and `relatedTopicsStatus` says so (off by default) |

Filters: **geo** (country or region, e.g. `US`, `US-CA`, `GB-ENG`), **time range** (past hour to 2004–present, or a custom `YYYY-MM-DD YYYY-MM-DD`), **category**, **search type** (Web, Images, News, YouTube, Google Shopping), language and timezone.

### Use cases

- **SEO and content marketing:** find seasonal peaks, regional demand and the top queries around any keyword.
- **E-commerce and product research:** compare product demand by region and month.
- **Market and investment research:** track interest in brands, tickers, tokens and categories over time, on one comparable scale.
- **Newsrooms and social media:** monitor trending searches by country every hour.
- **AI agents and dashboards:** feed clean JSON into LLM workflows, Google Sheets or BI tools.

### Input examples

**Analyze several keywords separately (batch):**

```json
{ "searchTerms": ["air fryer", "standing desk", "protein powder"], "geo": "US", "timeRange": "today 12-m" }
```

**Compare brands on one scale:**

```json
{ "searchTerms": ["iphone", "samsung galaxy", "google pixel"], "comparisonMode": "compareAll", "geo": "US", "timeRange": "today 5-y" }
```

**Custom dates, city level, YouTube search:**

```json
{ "searchTerms": ["pickleball"], "geo": "US", "customTimeRange": "2024-01-01 2024-12-31", "regionResolution": "CITY", "property": "youtube" }
```

**Trending now in several countries, sports and tech only:**

```json
{ "mode": "trending", "trendingGeos": ["US", "GB", "DE"], "trendingHours": "24", "trendingCategories": ["17", "18"], "trendingMaxItems": 50 }
```

### Output example (real Apify cloud run, Oct 2026, shortened)

```json
{
  "searchTerm": "iphone",
  "geo": "US",
  "timeRange": "today 12-m",
  "googleUserType": "USER_TYPE_SCRAPER",
  "dataQualityWarning": "Google flagged this request as automated (USER_TYPE_SCRAPER). Interest over time, regions and top queries are reliable. Rising queries are decoy-filtered (removed entries are listed in suspectedDecoys) and should be treated as experimental.",
  "interestOverTime": [
    {
      "date": "2025-10-05",
      "timestamp": 1759622400,
      "formattedTime": "Oct 5 – 11, 2025",
      "values": {
        "iphone": 55
      }
    }
  ],
  "interestOverTimeSummary": {
    "iphone": {
      "average": 60.96,
      "max": 100,
      "min": 46,
      "latest": 51,
      "peakDate": "2026-01-18",
      "changePercent": -2.6,
      "direction": "stable"
    }
  },
  "interestByRegion": [
    {
      "geoCode": "US-WY",
      "geoName": "Wyoming",
      "values": {
        "iphone": 100
      }
    },
    {
      "geoCode": "US-LA",
      "geoName": "Louisiana",
      "values": {
        "iphone": 62
      }
    }
  ],
  "relatedQueries": {
    "iphone": {
      "top": [
        {
          "query": "iphone 17",
          "value": 100
        },
        {
          "query": "apple iphone",
          "value": 83
        },
        {
          "query": "apple",
          "value": 79
        }
      ],
      "rising": [
        {
          "query": "iphone 17e",
          "value": 11050,
          "formattedValue": "Breakout"
        },
        {
          "query": "iphone 18 colors",
          "value": 5350,
          "formattedValue": "Breakout"
        },
        {
          "query": "how to stop app tracking on iphone",
          "value": 4300,
          "formattedValue": "+4,300%"
        }
      ],
      "suspectedDecoys": [
        {
          "query": "iphone 6s to buy",
          "formattedValue": "Breakout",
          "reasons": [
            "knownDecoy"
          ]
        },
        {
          "query": "iphone 3gs to buy",
          "formattedValue": "Breakout",
          "reasons": [
            "knownDecoy"
          ]
        }
      ]
    }
  },
  "risingFilter": "strict",
  "relatedTopics": null,
  "relatedTopicsStatus": "unavailable: Google withheld related topics for this request",
  "trendsUrl": "https://trends.google.com/trends/explore?q=iphone&date=today%2012-m&hl=en-US&geo=US",
  "status": "ok"
}
```

**Trending row:** `{ "rank": 1, "term": "brewers vs padres", "geo": "US", "searchVolume": 500000, "searchVolumeFormatted": "500K+", "growthPercent": 1000, "isActive": true, "categories": ["Sports"], "relatedQueries": ["..."] }`

Failed queries appear as `{ "status": "failed", "error": "...", "hint": "..." }` and are **not charged**. A `RUN_SUMMARY` record in the key-value store lists successes, failures, retries and rate-limit counts.

### Pricing (pay per event)

- **$0.01 per run start**
- **$1.50 per 1,000 results.** One result is one keyword (or one comparison of up to 5 keywords) with its timeline, regions and related queries, or one trending search.
- No proxy or compute costs on top. Failed queries are free.
- Example: 100 keywords with all data = $0.15 + $0.01.

Set **Max results** or a maximum cost per run to cap spending. The actor stops gracefully when the limit is reached.

### Reliability notes

- **Proxy:** Apify Proxy is on by default (datacenter first). If Google keeps returning HTTP 429, the run switches to **RESIDENTIAL** automatically (`residentialFallback`).
- **Retries:** each request is retried up to `maxRetries` times with exponential backoff and a new proxy session.
- **Data quality, honestly:** Google marks automated sessions as `USER_TYPE_SCRAPER`. In our cloud tests (Oct 2026) this happened on datacenter IPs, residential IPs and even a real headless Chrome. It doesn't affect timelines, regions, top queries or Trending now; those matched what a browser shows. Rising queries, however, get **decoys mixed in** (e.g. "hotel booking", "coffee grinder", "laptop stand" for "air fryer"), and related topics are withheld. Every keyword result carries `googleUserType` and a `dataQualityWarning`.
- **Decoy filter for rising queries** (`risingFilter`):
  - `strict` (default) moves an entry to `suspectedDecoys` if it is a **known decoy** (built-in list and spam patterns), if it **repeats across unrelated keywords** in the same run, or if it is **unrelated to the keyword** (shares no word with the keyword or its top queries).
  - `balanced` drops only known decoys and repeats; unrelated entries stay in `rising` marked `"unverified": true`. Use it for celebrity or tech keywords, where real rising terms often share no words with the keyword (e.g. "antigravity" for "claude").
  - `off` returns Google's raw list.
  - Add your own blocklist with `extraDecoyTerms`. The run summary reports how many entries were kept and removed.
- **Schedules:** run it daily or hourly with Apify Schedules. Use the `tests/selftest_input.json` input with a run-failure email alert to monitor health.

### Daily alerts to Slack or email

1. Fill in the input and click **Save as a new task** (one task per client or competitor set is a good pattern).
2. In **Schedules**, create a schedule (for example every day at 08:00 in your time zone) and add the task.
3. In the task's **Integrations** tab, add the **Slack** or **Gmail** integration to get a message when a run finishes,
   or a **webhook** on "Run succeeded" that passes the run to Zapier, Make, n8n or your own endpoint. Those tools can read the rows from
   `https://api.apify.com/v2/datasets/{defaultDatasetId}/items` and format them however you like.

Schedule a task weekly (or daily for **Trending now**) and send the results to Slack, Gmail, Google Sheets or a webhook. This Actor has no "only changes" mode: each run returns the full current data, which is what you usually want for a trend report.
Turn on Apify's run-failure notifications too, so you hear about a failed run instead of silence.

### Related actors

Part of a small **competitor-intelligence suite** by the same developer. Same conventions everywhere: pay per event, failed items are never charged, and the monitors return only what changed since the last run.

- [Google Ads Transparency Scraper & New Ads Monitor](https://apify.com/ivan-petrus-g/google-ads-transparency-monitor): competitors' Google Search, Display and YouTube ads, with only-new-ads alerts.
- [LinkedIn Ad Library Scraper & New Ads Monitor](https://apify.com/ivan-petrus-g/linkedin-ad-library-monitor): competitors' LinkedIn ads without login, incl. EU impressions and targeting.
- [Bing Ads Library Scraper - Microsoft Ads Monitor (EU)](https://apify.com/ivan-petrus-g/microsoft-ads-library-monitor): Bing ads from Microsoft's official Ad Library (EU/EEA), with impressions by country.
- [ATS Jobs Scraper & Hiring Monitor](https://apify.com/ivan-petrus-g/company-hiring-monitor): new and closed jobs from Greenhouse, Lever, Ashby, Workday and 6 more job boards, by company domain.
- [App Store & Google Play Scraper](https://apify.com/ivan-petrus-g/app-store-monitor): ratings, installs, versions, chart and keyword ranks of iOS and Android apps, with change rows.

### FAQ

**Is there an official Google Trends API?** Google has no general-public Trends API. This actor uses the same JSON endpoints the Google Trends website uses and returns structured data.

**How many keywords can I run?** Hundreds per run. Keywords are processed in parallel (`maxConcurrency`), each worker on its own proxy session.

**Why do values differ between separate and comparison mode?** Google scales values 0–100 within each query. Use `compareAll` to put terms on the same scale.

**Which category IDs can I use?** Any Google Trends category ID, for example 7 Finance, 18 Shopping, 45 Health, 47 Autos, 71 Food & Drink, 958 Jobs. 0 means all categories.

**Are rising queries accurate?** Treat them as experimental. Google injects unrelated items into rising lists for automated traffic. The decoy filter removes the known ones and anything unrelated to your keyword, and shows what it removed in `suspectedDecoys`. Top queries, timelines and regions are not affected.

**Why are related topics empty?** Google currently withholds them for automated requests, regardless of proxy type. The actor marks this explicitly (`relatedTopicsStatus`) instead of returning empty lists.

**Can I use it from Python, n8n, Make or Zapier?** Yes, through the Apify API, the official integrations, or the Apify MCP server for AI agents.

**Is it legal?** The actor collects publicly available, aggregated data and no personal data. You are responsible for complying with Google's Terms of Service and local law.

*Keywords: google trends api, google trends scraper, google trends data, interest over time, interest by region, top related queries, trending searches, keyword demand, keyword research, search trends, pytrends alternative.*

# Actor input Schema

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

explore = keyword analysis (interest over time, by region, related queries/topics). trending = live 'Trending now' searches for one or more countries.

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

Keywords to analyze. Add as many as you like - they are processed in parallel. See 'Comparison mode' to compare terms against each other.

## `comparisonMode` (type: `string`):

separate = each term is its own query (values 0-100 per term). compareAll = terms are compared together in groups of up to 5 (values relative to each other, like the Compare box on Google Trends). commaSeparated = every line like 'iphone, samsung, pixel' is one comparison.

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

Paste trends.google.com/trends/explore URLs; their q, geo, date, cat and gprop parameters are used as-is.

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

Country code (US, GB, DE, UA...) or region (US-CA, GB-ENG). Empty = Worldwide.

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

Predefined time range. Ignored when 'Custom time range' is filled.

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

Format 'YYYY-MM-DD YYYY-MM-DD', e.g. '2024-01-01 2024-12-31'.

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

Google Trends category id. 0 = all categories. Examples: 7 Finance, 18 Shopping, 45 Health, 66 Pets, 71 Food & Drink, 174 Business, 958 Jobs, 5 Computers & Electronics, 47 Autos.

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

Search type.

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

Timeline + summary stats (average, peak, latest, % change, rising/falling).

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

Countries (worldwide) or regions/cities (inside a country).

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

Granularity of 'Interest by region'. If the chosen level has no data, the actor falls back automatically (City -> Metro/DMA for US -> Google default) and reports the level used in interestByRegionResolution.

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

Also return regions with too little data (value 0).

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

Top and rising related search queries for each term.

## `risingFilter` (type: `string`):

Google mixes fake entries into 'rising' related queries when it flags a session as automated. Flagged entries are moved from 'rising' to 'suspectedDecoys' (with reasons), so nothing is lost. Use 'balanced' for celebrity/tech keywords where real rising terms often share no words with the keyword.

## `extraDecoyTerms` (type: `array`):

Optional: additional rising entries you always want treated as decoys (exact match, case-insensitive).

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

Related topics (Knowledge Graph). Google currently withholds them for automated sessions; when it does, the result has relatedTopics: null and relatedTopicsStatus explains why. Off by default (saves one request per keyword).

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

2-letter country codes for 'Trending now' mode.

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

Time window for trending searches.

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

Only return trends in these categories (empty = all).

## `trendingActiveOnly` (type: `boolean`):

Skip trends that have already ended.

## `trendingMaxItems` (type: `integer`):

Sorted by search volume.

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

Interface language for topic names and formatted dates.

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

Google 'tz' parameter. 0 = UTC. Example: -180 for UTC+3.

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

Stop after this many results (0 = no limit). Useful to cap cost.

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

Parallel workers (each uses its own proxy session).

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

Retries with exponential backoff and proxy rotation on HTTP 429/5xx.

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

Apify Proxy is strongly recommended. Datacenter is used first; see 'Residential fallback'.

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

If Google keeps rate-limiting a datacenter IP, automatically switch to Apify RESIDENTIAL proxies for the rest of the run.

## `legitDataRetries` (type: `integer`):

Google often labels automated sessions as a scraper (USER_TYPE_SCRAPER). With a proxy enabled, the actor can re-fetch through a fresh IP up to this many times. In cloud tests (Oct 2026) fresh datacenter and residential IPs never cleared the flag, so the default is 0 (saves time and proxy cost). Every result reports googleUserType.

## Actor input object example

```json
{
  "mode": "explore",
  "searchTerms": [
    "web scraping",
    "chatgpt"
  ],
  "comparisonMode": "separate",
  "geo": "",
  "timeRange": "today 12-m",
  "category": 0,
  "property": "web",
  "includeInterestOverTime": true,
  "includeInterestByRegion": true,
  "regionResolution": "auto",
  "includeLowVolumeRegions": false,
  "includeRelatedQueries": true,
  "risingFilter": "strict",
  "extraDecoyTerms": [],
  "includeRelatedTopics": false,
  "trendingGeos": [
    "US"
  ],
  "trendingHours": "24",
  "trendingActiveOnly": false,
  "trendingMaxItems": 50,
  "language": "en-US",
  "timezoneOffsetMinutes": 0,
  "maxItems": 0,
  "maxConcurrency": 3,
  "maxRetries": 8,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "residentialFallback": true,
  "legitDataRetries": 0
}
```

# Actor output Schema

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

No description

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

No description

## `runSummary` (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 = {
    "searchTerms": [
        "web scraping",
        "chatgpt"
    ],
    "trendingGeos": [
        "US"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("ivan-petrus-g/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": [
        "web scraping",
        "chatgpt",
    ],
    "trendingGeos": ["US"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("ivan-petrus-g/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": [
    "web scraping",
    "chatgpt"
  ],
  "trendingGeos": [
    "US"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call ivan-petrus-g/google-trends-api --silent --output-dataset

```

## MCP server setup

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