# Google Trends Scraper: Interest, Regions, Related Queries (`smallhourstools/google-trends-polite`) Actor

Unofficial Google Trends reader for weekly term lists: interest over time, by region, related queries. No proxies, respects robots.txt. Failed terms are free.

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

## Pricing

from $0.01 / 1,000 term reads

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: Interest, Regions, Related Queries

Reads Google Trends for a list of search terms and gives you, for each term:

- **Interest over time**, as a series of dated points.
- **Interest by region**, by country or by subregion.
- **Related queries**, both top and rising.

Up to 25 terms per run. Time ranges go from the past 7 days to 2004 to present. You can narrow by
country or subregion, category and language.

It is slow on purpose. Read "How it handles Google's limits" below before you schedule it.

### Who it is for

People who track the same list of terms on a schedule, not people who need thousands of terms in an
hour. Some uses:

- Compare seasonal demand: when "sunscreen", "umbrella" or "flu symptoms" start rising each year.
- Watch a category: run your product terms every Monday and see which ones move.
- Feed a spreadsheet or a workflow: send each run to Google Sheets, n8n, Make or a webhook and chart
  it there.

If you need bulk extraction at high speed, this is the wrong tool. It will not get faster by design.

### Input

| Field | What it does | Default |
|---|---|---|
| `searchTerms` | The terms to read, one result per term. Up to 25 per run; extra terms are skipped. | required |
| `geo` | Country or subregion code: `US`, `GB`, `BR`, `US-CA`. Empty means worldwide. | worldwide |
| `timeRange` | `now 7-d`, `today 1-m`, `today 3-m`, `today 12-m`, `today 5-y` or `all` (2004 to present). | `today 12-m` |
| `category` | Google Trends category ID. `0` means all categories. | `0` |
| `includeRegions` | Add interest by region. | `true` |
| `includeRelated` | Add top and rising related queries. | `true` |
| `language` | Language for labels, like `en-US` or `es-419`. | `en-US` |

Example:

```json
{
  "searchTerms": ["cold brew", "iced tea"],
  "geo": "US",
  "timeRange": "today 12-m",
  "category": 0,
  "includeRegions": true,
  "includeRelated": true,
  "language": "en-US"
}
```

Duplicate terms are read once.

### Output

One dataset item per term. Example, trimmed to a few points per list:

```json
{
  "searchTerm": "cold brew",
  "geo": "US",
  "timeRange": "today 12-m",
  "category": 0,
  "interestOverTime": [
    { "date": "2026-06-14", "label": "Jun 14 - 20, 2026", "value": 100, "partial": false },
    { "date": "2026-06-21", "label": "Jun 21 - 27, 2026", "value": 97, "partial": false },
    { "date": "2026-10-18", "label": "Oct 18 - 24, 2026", "value": 58, "partial": true }
  ],
  "interestByRegion": [
    { "region": "Hawaii", "code": "US-HI", "value": 100 },
    { "region": "California", "code": "US-CA", "value": 86 }
  ],
  "relatedQueries": {
    "top": [
      { "query": "cold brew coffee", "value": "100" },
      { "query": "cold brew recipe", "value": "41" }
    ],
    "rising": [
      { "query": "cold brew concentrate ratio", "value": "+180%" },
      { "query": "protein cold brew", "value": "Breakout" }
    ]
  },
  "source": "Google Trends (unofficial reader). Values are relative, 0 to 100, not search counts.",
  "readAt": "2026-10-20T15:02:11.000Z"
}
```

Notes on the fields:

- The time step depends on the range and is set by Google: for example, daily points for 30 or 90
  days and weekly points for 12 months.
- `partial: true` marks the current period, which Google is still filling in.
- `relatedQueries.rising` values are Google's own labels: a percentage, or "Breakout" for a very
  large jump.

If a term fails, its item carries only `searchTerm` and `error`, so you can see what was missed.

### Price

**For the launch weeks, each term read successfully costs a symbolic US$0.00001** (pay per event,
event name `term-result`). That is a launch price, not the regular one.

**After the launch the price is US$0.003 per term read successfully** (US$3 per 1,000 terms). Apify
notifies every user 14 days before any price increase, so the change reaches you before it applies.

A realistic case: a list of 20 terms read every week is about 86 results a month, or **about US$0.26 a
month** at the price after the launch.

A term that fails is not charged. Apify's own platform usage for the run is billed by Apify as usual.

### How it handles Google's limits

When Google answers "too many requests" (HTTP 429), the reader waits and tries again, with a longer
wait each time. It does not switch IPs to get around the limit. After a few refusals on the same
term, it gives up on that term and moves on. After three terms in a row fail, it stops the run
instead of pushing harder.

That is why it takes **about a minute per term**, sometimes more. A run of 25 terms can take close
to half an hour. For a job that runs once a week while you sleep, that is a fair trade: you get the
data Google is willing to give, at the pace Google asks for, and you are not paying for retries that
were never going to work.

What it does not do:

- No residential proxies, no IP rotation to multiply volume.
- No CAPTCHA solving, by itself or through any service.
- No Google accounts and no login.
- No fake browser fingerprints. It identifies itself with its own User-Agent that names the tool and
  a contact address.
- It respects Google Trends' `robots.txt` and only calls the paths it allows.

If Google puts a CAPTCHA or a hard block in front of Trends, the run fails with a clear message
instead of trying to force its way through.

**Tested from Apify on 20 October 2026:** the terms it read came back complete. We have not measured
a success rate over time or at volume, so we do not quote one.

### Notices

- **This is an unofficial tool.** It is not affiliated with, endorsed by or connected to Google.
- **Data source: Google Trends.** Please cite it that way wherever you use the data. You are
  responsible for how you use it.
- **Values are relative indexes from 0 to 100, not search counts.** 100 is the peak for that term,
  place and period; 50 is half of that peak. Two runs with different settings are not on the same
  scale.
- **Volume cap: 25 terms per run.** That limit is deliberate.
- **It can break if Google changes Trends.** If that happens we fix it or say so on this page.
- **If Google opens its official Trends API to the public, this tool moves to it.** If Google or
  Apify asks us to take it down, we take it down the same day.
- The data contains no personal information: only the aggregate indexes Trends shows to anyone.

### Who is behind it

Small Hours is run by **Arlex Peralta**, who answers for this tool. The work (building it, testing it
and writing this page) is done by AI agents he directs. If you write to us, an AI agent may answer
first, and it will say so.

Questions, bugs or requests: **smallhours.tools@gmail.com**, or open an issue on this page.

# Actor input Schema

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

One result per term. Up to 25 per run.

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

ISO code like US, GB, BR or US-CA. Empty means worldwide.

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

How far back the data goes.

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

Google Trends category. 0 means all categories.

## `includeRegions` (type: `boolean`):

Adds interest by country or subregion.

## `includeRelated` (type: `boolean`):

Adds the top and rising related queries.

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

Language for labels, like en-US or es-419.

## Actor input object example

```json
{
  "searchTerms": [
    "coffee"
  ],
  "geo": "",
  "timeRange": "today 12-m",
  "category": 0,
  "includeRegions": true,
  "includeRelated": true,
  "language": "en-US"
}
```

# 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 = {
    "searchTerms": [
        "coffee"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("smallhourstools/google-trends-polite").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": ["coffee"] }

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

```

## MCP server setup

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

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/mclJbGZqAJXYWqUu5/builds/RoUnj2BQUYqgCe7Pb/openapi.json
