# Google Trends Scraper - Trending Now, Interest & Metrics (`ballast/google-trends-scraper`) Actor

Interest over time, by region, and related queries in one run - most scrapers return one series and charge you three times. Survives Google's rate limits; a throttled dataset is skipped, not fatal. Missing data is null, never zero. Never charges for an empty or failed run.

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

## Pricing

$2.00 / 1,000 result rows

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/platform/actors/running/actors-in-store#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 Scraper - Trending Now, Interest Over Time & Metrics

A Google Trends scraper and API that returns **five datasets in one run**:
daily trending searches, interest over time, interest by region, related
queries, and computed trend metrics.

Most Google Trends scrapers return one series and charge you three times to
assemble a picture. This one assembles it in a single run, and never charges
for an empty or failed run.

```json
{
  "keywords": ["ai agents"],
  "timeframe": "today 12-m",
  "datasets": ["timeseries", "geo", "related_queries", "trending", "metrics"]
}
```

That input returns roughly 170 rows: the weekly series, every region with
data, top and rising related queries, the day's trending searches with their
news coverage, and a computed summary of where the term is heading.

### What you get

#### Trending now (daily trending searches)

The searches spiking today, per country, with Google's traffic estimate and
the news articles driving them. Needs **no keywords** - run it on its own as a
daily trending-topics feed.

| Field | Meaning |
| --- | --- |
| `query` | The trending search term |
| `rank` | Position in today's list |
| `approx_traffic` | Google's own estimate, e.g. `2000+` |
| `approx_traffic_min` | The same figure as an integer you can sort on |
| `news` | Articles driving the spike: title, url, source |
| `picture`, `picture_source` | Lead image and its publisher |
| `published_at` | ISO 8601 timestamp |

#### Interest over time

The weekly or daily series for up to 5 keywords, normalised 0-100.

#### Interest by region

Every country or subregion with data, so you can see where demand sits.

#### Related queries

Top and rising associated searches, with breakouts marked.

#### Trend metrics (computed, no extra requests)

Most scrapers hand you the raw series and stop. This one also computes:

| Field | Meaning |
| --- | --- |
| `direction` | `rising`, `falling` or `flat` |
| `growth_pct` | Second half of the period against the first |
| `peak_value`, `peak_date` | The high point and when it happened |
| `volatility_pct` | Standard deviation as a share of the mean |
| `trend_score` | Composite, 0-100 |

**The score's formula is published, not magic:**

```
growth_component = (clip(growth_pct, -100, 100) + 100) / 2
trend_score      = 0.6 * growth_component + 0.4 * mean
```

When the first half of the period is zero, growth is undefined rather than
infinite, and the score falls back to the level term alone.

### Why this one

**It does not fail when Google throttles.** Google rate-limits Trends
aggressively per IP. The usual failure mode is not an error but a hang: a
scraper waiting on a limit it has no strategy for. This client warms the
session, paces requests, and retries 429s with backoff instead of treating
them as fatal.

**A throttled dataset is skipped, not fatal.** If related queries is refused
after every retry, you still get the series, the regions and the trending
list. Partial success beats a lost run.

**Missing data is `null`, never `0`.** No data is not zero interest, and
charting it as zero invents a collapse that never happened.

**Partial buckets are flagged.** Google's final period is usually incomplete
and reads as a crash. Rows carry `is_partial`, and the computed metrics
exclude those buckets so growth figures are not poisoned by them.

**You are never charged for nothing.** Failed and empty runs cost you zero.
Charging happens only after results are validated.

### Pricing

**$0.002 per result row.** No subscription, no platform fee, no minimum.

| Run | Rows | Cost |
| --- | --- | --- |
| Trending now only | ~10-20 | under $0.05 |
| One keyword, all datasets | ~170 | about $0.34 |
| Five keywords, all datasets | ~400 | about $0.80 |

### Input

| Field | Type | Notes |
| --- | --- | --- |
| `keywords` | array | Up to 5 terms, compared against each other. Not needed for trending-only runs. |
| `datasets` | array | `timeseries`, `geo`, `related_queries`, `related_topics`, `trending`, `metrics` |
| `timeframe` | string | `now 1-H` through `today 5-y`, or `all` |
| `geo` | string | Country code such as `US`, `GB`, `IL`. Empty means worldwide. |
| `trendingGeo` | string | Country for trending searches. Defaults to `geo`, then `US`. |
| `category` | integer | Google Trends category ID. `0` is all categories. |
| `property` | string | Web, images, news, YouTube or shopping |
| `proxyConfiguration` | object | Strongly recommended. Google limits per IP. |

### Reading the numbers correctly

Google normalises every series to 0-100 against its own peak. A value of 50
means half the interest of that term's busiest moment **for that query, over
that period, in that region** - never a search volume, and never comparable
across separate runs. Change the timeframe or the region and the whole series
rescales.

With several keywords in one run, all of them are scaled against the single
most popular term, which is what makes comparison meaningful.

### Common uses

- SEO and content teams tracking whether a topic is rising before committing
- Daily trending-topics feeds for newsrooms and social scheduling
- Market research on regional demand
- Feeding trend context into LLM pipelines and agents
- Monitoring brand or competitor interest over time

### Notes

Related topics is off by default. Google returns an empty list for it when the
session is stamped as an API client, and the widget token is bound to its
request so the flag cannot be edited out. Shipping it on by default would show
an always-empty dataset. Related queries is unaffected.

***

Built by **Ballast** - data tools that stay upright when the source gets hostile.

# Actor input Schema

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

Up to 5 search terms. With more than one, values are relative to the most popular term across the whole period. Not needed if you only want Trending now.

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

Period to analyse.

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

Two-letter country code such as US, GB, IL. Leave empty for worldwide.

## `datasets` (type: `array`):

Which datasets to return. Collecting fewer is faster and cheaper. Trending now needs no keywords and can be run on its own. Trend metrics are computed from interest over time and cost no extra requests. Note: Google returns related topics only intermittently for API clients, so it is off by default; related queries are unaffected.

## `trendingGeo` (type: `string`):

Country for the Trending now feed, such as US, GB, IL. Defaults to the country above, or US when that is empty. Google publishes trending searches per country, so worldwide is not an option here.

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

Google Trends category. 0 means all categories.

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

Restrict to a Google surface. Empty means web search.

## `includeEmptyRegions` (type: `boolean`):

Off by default, so regions Google has no data for are omitted rather than reported as zero.

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

Google rate-limits Trends aggressively per IP. Running through a proxy is what keeps repeated runs reliable, and is strongly recommended.

## Actor input object example

```json
{
  "keywords": [
    "bitcoin"
  ],
  "timeframe": "today 12-m",
  "geo": "",
  "datasets": [
    "timeseries",
    "geo",
    "related_queries",
    "metrics"
  ],
  "trendingGeo": "",
  "category": 0,
  "property": "",
  "includeEmptyRegions": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# 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"
    ]
};

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

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

```

## MCP server setup

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

```

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/ZRkc3UztPcB4Mqacd/builds/6euVRzNG4dF98CYzD/openapi.json
