# Google Trends Scraper: Bulk Compare + Insights (`albion_sanctifire/google-trends-bulk`) Actor

Google Trends data for any number of keywords on ONE comparable scale (beats the 5-term limit), with built-in insights: growth %, direction, peak, year-over-year. Interest over time, by region, related queries, and daily trending searches. Fails fast instead of hanging.

- **URL**: https://apify.com/albion_sanctifire/google-trends-bulk.md
- **Developed by:** [Brian](https://apify.com/albion_sanctifire) (community)
- **Categories:** SEO tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.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.

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: Bulk Compare + Trend Insights

Get Google Trends data for **any number of keywords on one comparable scale**, plus **ready-made insights** for every keyword: growth %, rising or falling, peak date, and year-over-year change. You also get interest over time, interest by region, top and rising related queries, and today's trending searches.

### Why this scraper

- **Compare 50 keywords, not 5.** Google Trends compares at most 5 terms at once, so values from separate comparisons can't be compared. This Actor stitches batches together through an anchor keyword, so every keyword lands on **one 0–100 scale**.

- **Small keywords keep their shape.** Next to a big keyword, Google rounds small ones to 0, 1 or 2. The Actor re-measures small keywords next to keywords of similar size and chains the results back, so a niche term shows a real curve instead of a flat line.

- **Answers, not just numbers.** Each keyword comes with `insights`:

  | Field | Meaning |
  |---|---|
  | `recentChangePct` | Last quarter of the period compared with the quarter before |
  | `direction` | `rising`, `falling` or `stable` |
  | `peak` / `peakDate` | Highest point and when it happened |
  | `yearOverYearChangePct` | For ranges of 2 years or more |
  | `slopePerPeriodPct` | Steepness of the trend |

- **Fails fast, never hangs.** Rate limits are absorbed with fresh sessions and backoff, there's a hard cap on attempts, and you set a time budget. A keyword that can't be fetched comes back as a row with an `error`, and you are **not charged** for it.

- **Fast and cheap to run.** Plain HTTP, no headless browser. In Apify cloud tests, 10 keywords finished in under 3 minutes, and 12 keywords on one shared scale in under 1 minute.

### Who uses it for what

- **Product research:** rank 100 product ideas by search interest and see which are still growing.
- **SEO and content planning:** find which topics are rising, and when they peak each year, before you write.
- **Market and brand tracking:** compare your brand with competitors on one scale, week by week.
- **Investing and research:** track interest in companies, products or categories over 5 years.
- **AI agents and automations:** call it from the API, Make, Zapier, n8n, or an MCP client and get clean JSON back.

### Quick start

Compare 3 keywords (Google's own shared scale):

```json
{ "keywords": ["notion", "obsidian", "evernote"], "geo": "US", "timeframe": "today 12-m" }
```

Compare 40 keywords on one scale:

```json
{ "keywords": ["shopify", "woocommerce", "wix", "squarespace", "..."], "geo": "US", "anchorKeyword": "wix" }
```

Each keyword on its own 0–100 scale:

```json
{ "keywords": ["ozempic", "wegovy"], "compareMode": "individual" }
```

Trending searches now:

```json
{ "mode": "trending", "trendingGeos": ["US", "GB", "DE"] }
```

### Output (one row per keyword)

```json
{
  "keyword": "obsidian",
  "geo": "US",
  "timeframe": "today 12-m",
  "scale": "anchored",
  "anchorKeyword": "notion",
  "comparedWith": ["notion", "evernote", "logseq", "..."],
  "insights": { "latest": 50, "average": 68.2, "peak": 100, "peakDate": "2026-01-18", "recentChangePct": -33.3, "direction": "falling", "yearOverYearChangePct": null, "slopePerPeriodPct": -0.71 },
  "interestOverTime": [{ "date": "2025-10-26", "value": 81, "isPartial": false }, "..."],
  "interestByRegion": [{ "geoCode": "US-WA", "geoName": "Washington", "value": 100 }, "..."],
  "relatedQueries": { "top": [{ "query": "obsidian notes", "value": 100, "link": "..." }], "rising": ["..."] },
  "trendsUrl": "https://trends.google.com/trends/explore?q=...",
  "warnings": []
}
```

The **Overview** tab shows a table with keyword, scale, insights, and a link to open the same view in Google Trends.

### Scales

| `scale` | Meaning |
|---|---|
| `shared` | Up to 5 keywords compared in one Google request. Google's own numbers. |
| `anchored` | More than 5 keywords placed on one scale through `anchorKeyword` (default: the first keyword). Values can be fractional. |
| `independent` | Each keyword on its own 0–100 scale. |

**Tip:** pick an anchor of middling popularity. Small keywords are refined automatically either way (`refineSmallKeywords`, on by default).

### Use it from code

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("albion_sanctifire/google-trends-bulk").call(
    run_input={"keywords": ["notion", "obsidian", "evernote"], "geo": "US"})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["keyword"], item["insights"]["direction"], item["insights"]["recentChangePct"])
```

### Not included

Interest by city or metro area, and related topics (see FAQ). Interest by region (state or country level) is included.

### Pricing

Pay per result: **$2 per 1,000 keyword results**, and **$0.50 per 1,000 trending items**, plus Apify's standard $0.00005 per run start. **No compute or proxy charges on top**: the price you see is what you pay. Failed keywords, and keywords Google has no data for, are free.

### FAQ

**Are the numbers search volumes?** No. Google Trends gives relative interest (0–100), not absolute searches. The anchored scale keeps that meaning across many keywords.

**Where are related topics?** As of October 2026, Google returns an empty related-topics list for every keyword, for every scraper. The `relatedTopics` field (Individual mode) fills in automatically if Google brings them back.

**Why do numbers differ slightly from an earlier run?** Google Trends is computed from a random sample of searches, so mid-volume keywords can move a few points between fetches. Very popular keywords are stable.

**Why does the last point say `isPartial: true`?** The current week or day isn't over yet. Insights ignore partial points.

**Is this legal?** The Actor collects public, aggregated, non-personal data, the same data anyone sees on trends.google.com. Check that your use fits your own legal requirements.

**Proxies?** Residential proxies are the default, because Google rate-limits datacenter IPs heavily.

# Actor input Schema

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

Keyword trends, or today's trending searches.

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

Any number of keywords. Up to 5 are compared on Google's own scale; more are put on one shared scale through an anchor keyword.

## `compareMode` (type: `string`):

Auto: one shared scale (anchored when more than 5). Individual: each keyword on its own 0-100 scale.

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

Only for more than 5 keywords: the keyword included in every batch to stitch batches together. Defaults to the first keyword. Pick one of middling popularity for the best precision.

## `refineSmallKeywords` (type: `boolean`):

With more than 5 keywords, re-measure keywords that are tiny next to the anchor beside keywords of similar size, so their curves keep their shape. Costs a few extra requests.

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

Country or region code, e.g. US, GB, US-CA. Empty = worldwide.

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

Period to fetch. Google picks the point spacing: hourly up to 7 days, daily up to 90 days, weekly up to 5 years, monthly beyond.

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

Overrides Time range. Format: YYYY-MM-DD YYYY-MM-DD

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

Google Trends category ID (0 = all categories).

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

Which Google search to measure: web (default), images, news, YouTube or Shopping.

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

Add interest by sub-region (states or provinces, or countries when worldwide).

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

Add the top and rising related search queries for each keyword.

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

Add top and rising related topics (Individual mode). Google currently returns these empty for all keywords; kept so they fill in if Google restores them.

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

For Trending mode: country codes, e.g. US, GB, DE.

## `maxTrendingItems` (type: `integer`):

For Trending mode: how many trending searches to return per country, highest-ranked first.

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

Google rate-limits aggressively; residential proxies give the best success rate.

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

Each attempt uses a fresh session and IP. After this many, the keyword is returned as a free error row instead of retrying forever.

## `maxRunSeconds` (type: `integer`):

Stops starting new requests after this, so runs end cleanly instead of timing out.

## Actor input object example

```json
{
  "mode": "keywords",
  "keywords": [
    "notion",
    "obsidian",
    "evernote"
  ],
  "compareMode": "auto",
  "refineSmallKeywords": true,
  "geo": "",
  "timeframe": "today 12-m",
  "category": 0,
  "property": "",
  "includeRegions": true,
  "includeRelatedQueries": true,
  "includeRelatedTopics": true,
  "trendingGeos": [
    "US"
  ],
  "maxTrendingItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "maxRetries": 6,
  "maxRunSeconds": 3000
}
```

# Actor output Schema

## `overview` (type: `string`):

One row per keyword: scale, insights (growth %, direction, peak, year-over-year), geo, timeframe, any error, and a Google Trends link.

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

Full rows: interest over time, interest by region, related queries and insights for each keyword, or one row per trending search in trending mode.

# 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": [
        "notion",
        "obsidian",
        "evernote"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("albion_sanctifire/google-trends-bulk").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": [
        "notion",
        "obsidian",
        "evernote",
    ] }

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

```

## MCP server setup

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

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/dtQrXrzC9K8e7T0xC/builds/kErcbuTn9IXGoXPVE/openapi.json
