# Google Trends Scraper (Reliable, Drop-in) (`fifty50labs/google-trends-scraper-reliable`) Actor

Google Trends interest over time, by region and city, plus related queries. Same input as apify/google-trends-scraper. No browser, hard per-term timeout, failed terms free.

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

## Pricing

$4.00 / 1,000 keyword reports

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 (Reliable, Drop-in)

Get Google Trends data for your keywords: interest over time, interest by region and city, and related queries. The input uses the same field names as `apify/google-trends-scraper`, so you can switch by changing only the Actor ID in your API call, schedule, Zapier/Make step or MCP tool.

### What makes it different

- **No browser.** It calls the JSON endpoints the Google Trends page itself loads, and runs at 256 MB of memory.
- **Hard timeout per term.** Each term has a time limit (`timeoutPerTermSecs`, default 60 s). When it is reached, the Actor saves what it already has and moves to the next term. A run never waits forever on one keyword.
- **Results saved as they arrive.** Each report is written to the dataset as soon as it is done, so an aborted run still keeps the finished terms.
- **Failed terms are free.** You pay only for reports that contain interest-over-time data (`status` = `ok` or `partial`). Failed terms and terms with too little search volume are saved as rows with a reason, at no charge.
- **No start fee.** There is no per-run charge.
- **Bounded retries.** On HTTP 429 or 5xx it waits 2, 4, 8, then 16 seconds, always within the term's time limit, then marks the term `failed` with the reason.
- **No CAPTCHA solving, no proxies.** If Google shows a CAPTCHA page, the term is marked failed. After 3 in a row, the remaining terms are marked "not attempted" so the run ends quickly instead of burning time.

### How to switch from apify/google-trends-scraper

Keep your input JSON. Change the Actor ID:

```text
apify/google-trends-scraper  →  fifty50labs/google-trends-scraper-reliable
```

Supported input fields: `searchTerms`, `isMultiple`, `timeRange`, `customTimeRange`, `geo`, `category`, `startUrls`, `spreadsheetId`, `maxItems`, `maxConcurrency`, `maxRequestRetries`, `pageLoadTimeoutSecs`, `viewedFrom`, `skipDebugScreen`.

Differences you should know about:

| Field | Behaviour here |
|---|---|
| `viewedFrom` | Accepted, no effect (this Actor uses no proxies). |
| `skipDebugScreen` | Accepted, no effect (no browser, so no snapshots). |
| `maxConcurrency` | Capped at 3; 1 (default) is the most reliable with Google's rate limits. |
| `maxRequestRetries` | Capped at 6. |
| `pageLoadTimeoutSecs` | Used as the per-request HTTP timeout, capped at 30 s. |
| `isMultiple` | Also accepts the strings `"true"`/`"false"` in code. |

New optional fields: `timeoutPerTermSecs` (15–300, default 60), `property` (`images`, `news`, `froogle`, `youtube`) and `hl` (label language, default `en-US`).

### Input example

```json
{
  "searchTerms": ["web scraping", "electric cars"],
  "geo": "US",
  "timeRange": "today 3-m"
}
```

Compare up to 5 terms in one chart:

```json
{ "searchTerms": ["iphone, samsung galaxy"], "isMultiple": true }
```

Or paste Google Trends URLs (the `q`, `geo`, `date`, `cat` and `gprop` parameters are read from the URL):

```json
{ "startUrls": [{ "url": "https://trends.google.com/trends/explore?q=coffee&geo=GB&date=today%203-m" }] }
```

### Output

One dataset item per term (or per comparison row). Field names follow `apify/google-trends-scraper`:

| Field | Content |
|---|---|
| `inputUrlOrTerm`, `searchTerm` | What you asked for |
| `interestOverTime_timelineData` | `[{time, formattedTime, formattedAxisTime, value[], hasData[], formattedValue[], isPartial?}]` |
| `interestOverTime_averages` | Averages (filled for comparisons) |
| `interestBy` | Worldwide: interest by country |
| `interestBySubregion`, `interestByCity` | Country geo: interest by region and by city |
| `interestByMetro` | When Google returns metro-level data (e.g. US state URLs) |
| `relatedQueries_top`, `relatedQueries_rising` | `[{query, value, formattedValue, link}]` |
| `relatedTopics_top`, `relatedTopics_rising` | `[{topic: {mid, title, type}, value, formattedValue, link}]` (see limits) |
| `status` | `ok`, `partial`, `no_data` or `failed` |
| `error`, `missingSections` | Why a report is not `ok`, and which sections are missing |
| `geo`, `timeRange`, `durationSecs`, `scrapedAt` | Run details |

In comparisons, each related query also carries the `searchTerm` it belongs to.

### Pricing

Pay per event:

| Event | Price |
|---|---|
| Keyword report (`status` `ok` or `partial`) | $0.004 |
| Failed term, no-data term, run start | $0 |

Platform usage is included in the event price; you are not billed for compute separately.

### Limits (read before relying on it)

- **Related topics are often empty.** As of October 2026, Google returns an empty related-topics list to clients that are not a full browser. Related queries, interest over time and interest by region are returned normally. If Google changes this, the fields fill in without any change on your side.
- **Google rate-limits.** There is no official public Google Trends API, and Google throttles automated traffic. Without proxies, very large batches can get HTTP 429 responses. Those terms come back as `failed` (free) with the reason; re-run them later. For large lists, keep `maxConcurrency` at 1.
- **No uptime guarantee.** Google can change these endpoints at any time. The Actor is built to fail fast and visibly (an error row, not a hung run) when that happens.

### Our test runs

Measured on the Apify platform on 12 October 2026, 256 MB memory, no proxy:

| Test | Result |
|---|---|
| 5 terms, US, past 12 months (`web scraping`, `bitcoin`, `electric cars`, `taylor swift`, `chatgpt`) plus one blank row | 5/5 `ok`, blank row skipped, 104 s total |
| Comparison (`iphone, samsung galaxy`), Google Trends URL (`coffee`, GB, 3 months), custom range 2025, and one nonsense term | 2/2 `ok`; nonsense term `no_data` (not charged) |
| Charging check: `solar panels`, `pizza`, a nonsense term, and a US-CA Google Trends URL (`hiking`) | 3 reports charged, nonsense term `no_data` and not charged; US-CA returned `interestByMetro` |
| Forced hang in one section (local test) | Term saved as `partial` with `missingSections` at the 20 s limit |

These are small test runs, not a long-term success rate.

### Is it legal?

The Actor reads public, aggregated, non-personal Google Trends data, the data shown on the Google Trends website. Google's terms discourage automated access, so check that your use fits your own legal requirements.

### Feedback

Found a term that fails or a field that differs from what you expected? Open an issue on the Issues tab with the input you used.

# Actor input Schema

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

Terms to look up, one report per term. Blank rows are skipped. Required unless you use Google Trends URLs or a Google Sheet ID.

## `isMultiple` (type: `boolean`):

If checked, a comma inside one row separates up to 5 terms that are compared in one chart (one report per row).

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

Predefined time range. Empty = past 12 months.

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

Country (ISO code). Empty = worldwide. Region codes such as US-CA work through Google Trends URLs.

## `viewedFrom` (type: `string`):

Accepted for compatibility with apify/google-trends-scraper. This actor uses no proxies, so the field has no effect.

## `skipDebugScreen` (type: `boolean`):

Accepted for compatibility. This actor uses no browser and saves no snapshots.

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

Paste Google Trends explore URLs (trends.google.com/trends/explore?...). The q, geo, date, cat, gprop and hl parameters are read from each URL.

## `spreadsheetId` (type: `string`):

Optional. ID of a public Google Sheet with one column of terms; row 1 is the header and is skipped.

## `category` (type: `string`):

Category filter. Empty = all categories.

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

Maximum number of reports. 0 = no limit.

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

Format YYYY-MM-DD YYYY-MM-DD. Overrides Time range when set.

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

Which Google search to measure. Empty = web search.

## `hl` (type: `string`):

Interface language for labels, e.g. en-US.

## `timeoutPerTermSecs` (type: `integer`):

Hard limit per term. When it is hit, the actor saves whatever sections it already has (status partial) or an error row (status failed) and moves on.

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

Terms processed in parallel (capped at 3 in code). Google rate-limits quickly, so 1 is the most reliable.

## `maxRequestRetries` (type: `integer`):

Retries per request on HTTP 429/5xx (capped at 6), backoff 2, 4, 8, 16 s, always inside the per-term timeout.

## `pageLoadTimeoutSecs` (type: `integer`):

Timeout for one HTTP request (capped at 30 s in code; kept for compatibility).

## Actor input object example

```json
{
  "searchTerms": [
    "web scraping"
  ],
  "isMultiple": false,
  "timeRange": "",
  "geo": "",
  "skipDebugScreen": false,
  "startUrls": [
    {
      "url": "https://trends.google.com/trends/explore?q=web+scraping&geo=US"
    }
  ],
  "category": "",
  "maxItems": 0,
  "customTimeRange": "2024-01-01 2024-12-31",
  "property": "",
  "hl": "en-US",
  "timeoutPerTermSecs": 60,
  "maxConcurrency": 1,
  "maxRequestRetries": 4,
  "pageLoadTimeoutSecs": 20
}
```

# Actor output Schema

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

No description

## `allFields` (type: `string`):

No description

## `summary` (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"
    ],
    "timeRange": ""
};

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

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

```

## MCP server setup

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

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/AtPDYTddI83hjIWuK/builds/PEhHf1OzgRchtFsPE/openapi.json
