# Google Trends Scraper — No Browser, Full 12-Month Range (`craftbox/google-trends-fast`) Actor

Interest over time, by region, plus related queries and topics — pulled straight from the Trends API. Seconds per keyword instead of minutes.

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

## Pricing

$30.00 / 1,000 keyword processeds

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?

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 — No Browser, Full 12-Month Range

Pull Google Trends data through the same API the Trends interface uses — **no headless
browser**. Seconds per keyword instead of minutes, at a fraction of the compute cost.

### What you get per keyword

- **Interest over time** — the full series for your window, plus a computed summary
  (average, peak, latest, direction)
- **Interest by region** — subregion or country breakdown, empty regions removed
- **Related queries** — top and rising search terms
- Optional: related topics (see *Limitations*)

### Measured against the incumbent

Same keyword, same day, both on Apify:

| | This Actor | Google Trends Scraper (apify) |
|---|---|---|
| Time per keyword | **~25–31 s** | **over 300 s** — the run exceeded the API limit |
| Compute cost per keyword | **$0.0056** | **over $0.0968** |
| `today 12-m` range | **supported** | **not accepted** |
| Approach | Trends widget API | headless browser |

That is roughly **17× cheaper on compute** and **an order of magnitude faster**.

#### The 12-month gap is real

The incumbent's allowed time ranges jump straight from `today 3-m` to `today 5-y`.
The most common analysis window — the past 12 months — simply is not available there.
Here it is the default.

### Example output

```json
{
  "keyword": "python",
  "geo": "US",
  "timeRange": "today 12-m",
  "status": "ok",
  "summary": { "dataPoints": 53, "average": 71.2, "peak": 100, "latest": 66, "trend": "falling" },
  "interestOverTime": [
    { "date": "Jul 27 – Aug 2, 2025", "timestamp": "1753574400", "value": 61, "isPartial": false }
  ],
  "interestByRegion": [
    { "location": "California", "code": "US-CA", "value": 100 }
  ],
  "relatedQueries": {
    "top":    [ { "query": "what is python", "value": 100, "formattedValue": "100" } ],
    "rising": [ { "query": "python install", "value": 250, "formattedValue": "+250%" } ]
  }
}
```

One record per keyword. Failed keywords are returned with `status: "failed"` and a
reason — never as an empty record dressed up as success.

### Pricing

**$0.03 per keyword** processed. You are charged only for keywords returned with
`status: "ok"`.

A keyword here means the **complete pull**: time series, regional breakdown and related
queries in one record. Compute on top is roughly **$0.006** per keyword, because this
Actor makes plain HTTP calls instead of driving a browser.

Total: about **$0.036 per keyword**. The incumbent is free to install, but its compute
alone exceeded **$0.097** for a single keyword in our measurement.

### Caching — faster repeats, and a safety net

Results are cached for **24 hours by default**. This is not a shortcut: Trends returns
**weekly** data points for the common windows, so a series fetched yesterday is the same
series today.

What it buys you:

| | Fresh fetch | Served from cache |
|---|---|---|
| Time | ~24 s | **~5 s** |
| Compute cost | $0.0054 | **$0.0010** (81% less) |

Cached records are always labelled with `fromCache: true`, `cachedAt` and
`cacheAgeSeconds` — you can always tell replayed data from fresh data.

**Stale fallback.** If a live fetch fails — Google throttling, or a proxy outage — the
Actor returns the last cached copy rather than an error, marked `staleFallback: true`
with its age in the `warning` field. A week-old series with its age stated is more useful
than a failed run. Set **Cache lifetime** to `0` if you always need a live fetch.

### How to use

1. Put your terms into **Keywords** — one record comes back per term.
2. Pick a **Location** (`US`, `PL`, `GB`, `US-CA`, or empty for worldwide).
3. Pick a **Time range** — `today 12-m` by default.
4. Leave **Proxy** on. Google Trends throttles single IP addresses quickly.

#### From code

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("craftbox/google-trends-fast").call(run_input={
    "keywords": ["retrieval augmented generation", "vector database"],
    "geo": "US",
    "timeRange": "today 12-m",
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["keyword"], item["summary"])
```

### Limitations — read this before you run

Stated plainly, so there are no surprises:

1. **Google Trends throttles hard.** A handful of requests from one address is enough to
   start getting rejected. This Actor uses Apify Proxy by default and rotates the address
   per keyword. Keep it enabled.
2. **Related topics are off by default.** Google serves related topics and related queries
   from the *same* endpoint and usually throttles the second call, returning an empty
   payload with HTTP 200. If you enable topics, raise **Same-endpoint delay**. Either way,
   an empty result is reported in `warnings` — never silently as zero.
3. **Values are relative, not absolute.** Google Trends returns 0–100 popularity indices,
   not search volumes. That is how the source works.
4. **Throughput is bounded by politeness.** Expect roughly 25–30 s per keyword. Speed
   comes from avoiding a browser, not from hammering the source.

### Politeness and compliance

This Actor calls the same public endpoints the Trends web interface calls, at a
deliberately limited rate. It does not log in, does not bypass any protection mechanism,
and returns no personal data.

### FAQ

**Why is it so much faster than the alternative?**
No headless browser. The Trends interface fetches its data from a JSON API; this Actor
calls that API directly, so there is no page to render.

**Can I compare several keywords on one chart?**
Not yet — each keyword is fetched independently and returns its own record. Google's
own comparison mode normalises values across terms, which is a different calculation
and is on the roadmap.

**Which time ranges work?**
`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`.

**What if a keyword returns nothing?**
Terms with too little search volume have no Trends data at all. You get
`status: "failed"` with the reason, and you are not charged for it.

**Can I narrow it to a category?**
Yes — set the numeric Google Trends category ID. `0` means all categories.

# Actor input Schema

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

Search terms to analyse. Each becomes one dataset record.

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

Country or region code, e.g. US, PL, GB, US-CA. Leave empty for worldwide.

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

Analysis window. Unlike some alternatives, the 12-month range is supported.

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

Google Trends category. 0 means all categories.

## `includeTimeseries` (type: `boolean`):

Popularity across the selected window.

## `includeGeo` (type: `boolean`):

Breakdown by subregion or country.

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

Top and rising related search terms.

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

Top and rising related topics. Google serves this from the same endpoint as related queries and often throttles the second request, returning empty data. If you enable it, raise 'Same-endpoint delay'. Empty results are reported in the 'warnings' field, never as silent zeros.

## `perHostDelay` (type: `integer`):

Google Trends throttles aggressively. Lower this only when using proxies.

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

Strongly recommended. Google Trends rate-limits single IP addresses quickly.

## `sameEndpointDelay` (type: `integer`):

Extra pause before reusing an endpoint. Related queries and related topics share one endpoint; raise this if you need both.

## `attemptsPerKeyword` (type: `integer`):

If a keyword fails, retry it with a fresh proxy address. Protects against individual blocked addresses and short proxy outages.

## `cacheTtlHours` (type: `integer`):

Reuse a recent result instead of fetching again. Trends series are weekly-resolution, so a day-old answer is the same data — and it returns instantly. Cached records are labelled with 'fromCache' and 'cachedAt'. Set 0 to always fetch live.

## Actor input object example

```json
{
  "keywords": [
    "coffee"
  ],
  "geo": "US",
  "timeRange": "today 12-m",
  "category": 0,
  "includeTimeseries": true,
  "includeGeo": true,
  "includeRelatedQueries": true,
  "includeRelatedTopics": false,
  "perHostDelay": 2,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "sameEndpointDelay": 6,
  "attemptsPerKeyword": 2,
  "cacheTtlHours": 24
}
```

# 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": [
        "coffee"
    ],
    "geo": "US",
    "timeRange": "today 12-m",
    "includeRelatedTopics": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("craftbox/google-trends-fast").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": ["coffee"],
    "geo": "US",
    "timeRange": "today 12-m",
    "includeRelatedTopics": False,
}

# Run the Actor and wait for it to finish
run = client.actor("craftbox/google-trends-fast").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": [
    "coffee"
  ],
  "geo": "US",
  "timeRange": "today 12-m",
  "includeRelatedTopics": false
}' |
apify call craftbox/google-trends-fast --silent --output-dataset

```

## MCP server setup

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

```

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/oZdRjf8r9fImw0klL/builds/bxqeyxzvJbs65lPhs/openapi.json
