# Bulk Google Trends Scraper | Compare, Export & Resume (`cauldo/google-trends-bulk-research`) Actor

Bulk Google Trends research across keywords, countries and dates. Get timeline, regions, related queries and topics. Preserve comparison scope, inspect every request, resume incomplete batches, and download tidy CSV/JSON plus an n8n workflow.

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

## Pricing

$10.00 / 1,000 research request with usable data

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

## Bulk Google Trends Scraper | Compare, Export & Resume

**Run a keyword × country × date research matrix in one Actor. Keep comparison groups together, account for every request, resume incomplete batches, and export tidy trend data.**

Built for SEO research, content planning, ecommerce research, and recurring analyst workflows. Collect interest over time, regional interest, related queries, and related topics without constructing a separate run for every geography and time window.

**$0.01 per usable research request** — $10 per 1,000 request bundles. All selected surfaces and up to five keywords in one comparison group are included. No start fee or per-row fee.

### Why use this Actor?

- **One input for the whole research matrix.** Supply keywords, countries, and time windows. Or use explicit request objects for a mixed research brief.
- **Comparison groups keep their context.** Request several keywords together when you need a relative comparison. Every export carries its request and comparison identity.
- **Know what happened to every request.** The manifest distinguishes usable data, valid no-data, incomplete extraction, and failed requests. A blocked response is not reported as zero interest.
- **Resume the work that needs attention.** Reuse completed requests and retry missing or failed surfaces from a prior run. Download an exact resume input instead of assembling retries by hand.
- **Tidy exports are included.** Separate CSV and JSON files for timeline, regions, related queries, and related topics preserve request context. The default dataset holds a complete bundle per request for API workflows.
- **Predictable billing unit.** One $0.01 `research-request` event covers a request with usable output across its selected surfaces. There is no charge for each daily point or related-query row. Confirmed no-data and wholly failed requests have no research-request charge.

These are concrete workflow features, not a claim that this Actor is faster or more accurate than every alternative. It is particularly useful when your task spans multiple countries or periods and you need to reconcile incomplete batches. It does not provide the Trending Now news feed.

### Try a small research request

Paste this into the Actor input and run it:

```json
{
  "keywords": ["running shoes"],
  "geos": ["US"],
  "timeRanges": ["today 3-m"],
  "surfaces": ["timeline", "regions", "relatedQueries", "relatedTopics"]
}
```

Open the run's **Output** to see request bundles. Open its key-value store to download the manifest and separate research files. Begin with a small input so you can inspect the returned fields and availability for your use case.

### Bulk research across countries and dates

```json
{
  "keywords": ["running shoes", "trail running"],
  "geos": ["US", "GB", "DE"],
  "timeRanges": ["today 3-m", "today 12-m"],
  "surfaces": ["timeline", "relatedQueries"],
  "compareKeywords": false
}
```

This expands to **12 research requests**: 2 keywords × 3 countries × 2 windows. Each keyword is requested independently. Identical canonical requests are collapsed, so duplicate input rows do not create duplicate logical research work.

Use `""` as a geography for worldwide interest. Country codes such as `US`, `GB`, and `DE` are passed as research geography, independently of the proxy's location. Time windows may be relative, such as `today 3-m`, or fixed, such as `2026-01-01 2026-06-30`. Google controls data availability and granularity.

### Compare brands or topics together

```json
{
  "keywords": ["Nike", "Adidas", "New Balance"],
  "geos": ["US", "GB"],
  "timeRanges": ["today 12-m"],
  "surfaces": ["timeline", "regions"],
  "compareKeywords": true
}
```

This creates **two requests**, one group in each country. The Actor preserves keyword order, per-keyword values, source parameters, and `comparisonGroupId`. Compare values within the same fetched response and surface; a matching `comparisonGroupId` identifies the query scope, not a guarantee of calibration across fetch times. The supported group size is capped by the input schema; it is not expanded into independently normalized groups behind your back.

**Google Trends scores are relative interest, not absolute search volume.** A value of 100 is a peak within the source's normalization context. A score of 50 in one independent request is not necessarily comparable to 50 in another country, date window, keyword group, or surface. Related “rising” percentages also have a different meaning from timeline interest scores. Keep the source context when analyzing the exports. [Google's explanation](https://support.google.com/trends/answer/4365533?hl=en)

Rows include `normalizationScope`, which identifies the specific fetch and source widget, and `normalizationMethod`, which explains the metric. For a regional comparison, `valueUnit: "percent_of_compared_terms"` identifies each term's share among the compared terms within that region. It is different from a single-keyword map's relative-interest index.

Google sometimes omits related-query or topic widgets from a comparison page. The Actor can fetch those related surfaces through individual-keyword pages. Those rows retain their own `sourceUrl` and separate normalization scope; they are not added to the shared timeline scale.

The Actor does not calibrate arbitrary batches to a common scale. Google Trends uses sampled data, so repeated requests may differ. Topic IDs accepted by Google Trends can be supplied as keywords; a plain keyword string remains a search term and is not automatically resolved into a topic.

### Explicit requests for a mixed research brief

Use `requests` instead of the matrix fields when individual rows need different settings:

```json
{
  "requests": [
    {
      "label": "US footwear comparison, fixed period",
      "keywords": ["Nike", "Adidas"],
      "geo": "US",
      "time": "2026-01-01 2026-06-30",
      "surfaces": ["timeline", "regions"]
    },
    {
      "label": "German running research",
      "keywords": ["Laufschuhe"],
      "geo": "DE",
      "time": "today 3-m",
      "surfaces": ["timeline", "relatedQueries", "relatedTopics"]
    }
  ]
}
```

Multiple keywords inside one explicit request form one comparison group. Do not combine `requests` with top-level `keywords` or `compareKeywords`. A single global geography or time window may provide a default for explicit requests. If a global list has multiple entries, each request must specify that dimension itself. The explicit list never expands a matrix. Check the input schema for category, search property, execution limits, and proxy options.

### What you get

| Output | Contents |
|---|---|
| Default dataset | One result bundle per canonical research request: input context, overall status, and `surfaceResults` containing tidy rows and individual outcomes |
| `MANIFEST.json` | Every canonical request, including any work still pending, with status and provenance |
| `TIMELINE.csv` / `TIMELINE.json` | Interest-over-time rows with keyword, source timestamp and partial-period information |
| `REGIONS.csv` / `REGIONS.json` | Geographic interest with source region names/codes and keyword context |
| `RELATED-QUERIES.csv` / `RELATED-QUERIES.json` | Top/rising related search rows with source values and display values |
| `RELATED-TOPICS.csv` / `RELATED-TOPICS.json` | Top/rising topic rows with source topic identifiers and labels when available |
| `RESUME-INPUT.json` | An input for resuming this research batch |
| `N8N-WORKFLOW.json` / `N8N-SETUP.md` | Importable automation template and setup instructions |
| `OUTPUT` | Run summary, research-file links, and the checkpoint storage ID used for resume |

Each request bundle contains `requestId`, `comparisonGroupId`, `keywords`, `geo`, `time`, `category`, `property`, `status`, and `surfaceResults`. Each surface result records `surface`, `status`, `rows`, `sourceUrl`, `fetchedAt`, and an error where applicable. Tidy rows keep request provenance so multiple runs can be joined without losing their origin.

The manifest and generated exports are the authoritative view of logical requests. For consumers reading raw dataset appends, use `requestId` as the stable key: an interrupted storage response can make an append's acknowledgment uncertain.

#### Example exported row

This excerpt from `TIMELINE.json` was collected on September 22, 2026 for `coffee`, US, `today 3-m`. It shows one observed row, with some fields omitted for readability. Future samples can differ.

```json
{
  "requestId": "trends_48f1c8ccfc7f0730cf65134f",
  "comparisonGroupId": "scope_6c45b22491ace6fc3ef8d8a8",
  "geo": "US",
  "timeRange": "today 3-m",
  "requestStatus": "ok",
  "surfaceStatus": "ok",
  "fetchedAt": "2026-09-22T10:51:39.394Z",
  "keyword": "coffee",
  "interest": 68,
  "date": "2026-06-22T00:00:00.000Z",
  "hasData": true,
  "isPartial": false,
  "normalizationScope": "113c0757-698a-47ee-aca5-12770ba3030c:scope_6c45b22491ace6fc3ef8d8a8:timeline:TIMESERIES",
  "valueUnit": "relative_interest_index"
}
```

The complete request returned 93 timeline rows, 51 regional rows, 50 related-query rows, and a valid no-data outcome for related topics. The request manifest makes that last outcome visible instead of silently omitting the requested surface.

#### Read the status before using the numbers

A request may return useful timeline data while a related-query request fails. That is partial extraction, and the successful data remains available. A valid empty source response is recorded as no-data. A source access failure, an unexpected response, or unavailable widget is reported separately; it is never replaced with invented zeros.

Zero-valued source observations can be valid data. They do not prove no searches occurred. A partial final time interval from Google is also different from a failed extraction surface; preserve both signals when analyzing a time series.

For sparse terms, Google may return regional zero placeholders explicitly marked `hasData: false`. The Actor retains those source rows for transparency, labels the outcome `no_data`, and does not charge for them alone. `rowCount` counts retained rows, so it is not a useful-data or billing count.

An Apify run status of `SUCCEEDED` means the program completed. Consult the manifest for research completeness, especially when a runtime or charge limit stopped new work. A forced kill can leave an in-progress run's final export files unfinished; completed durable request records are retained for resume.

### Resume an interrupted or partial batch

Use the downloaded `RESUME-INPUT.json`, or start with:

```json
{
  "resumeFromRunId": "YOUR_PREVIOUS_RUN_ID"
}
```

The Actor imports the original plan, reuses finished request data, and retries missing or failed surfaces. Confirmed no-data and source-unsupported surfaces are treated as completed outcomes. Resume requires a checkpoint from this Actor under the same Apify account. Wait for a prior run to stop before resuming it.

Each run saves a dedicated checkpoint separately from the files in its default output store. `OUTPUT.checkpointStoreId` identifies it, and the downloaded `RESUME-INPUT.json` selects it through `resumeKeyValueStoreId`. Use that generated input rather than substituting the default output store ID. The input's storage selector grants access to the selected checkpoint while keeping the Actor's normal limited permissions.

The checkpoint must still exist when you resume. It follows Apify storage retention and can expire; resume is not a permanent archive. Save finished exports separately when you need to retain the research itself.

A request already billed in the inherited checkpoint is not charged again for resumed surface work. This depends on the same trusted checkpoint: launching a new independent input or changing the request context is fresh research. Resume is designed to finish an existing batch, not refresh its historical observations. To collect today's version of a relative window, start a new run from the original research input without a resume field.

**Verified in cloud runs:** a four-request batch stopped after one priced event under a $0.01 cap. Its resume kept the first request's 104 saved rows, completed the three deferred requests, and recorded only three new events. Resuming the finished 322-row batch again reused all four requests and recorded zero new events. This checks the resume and billing behavior; it is not a guarantee of future Google availability.

### Pricing and cost control

The launch price is **$0.01 per usable research request**, or **$10 per 1,000 request bundles**. The unit is one canonical keyword/comparison-group + geography + time-window + category + property request with usable output, covering all its selected surfaces. A comparison group may contain up to five distinct keywords. Selecting more daily points does not multiply the event count. The Actor's **Pricing** tab is the source for the current rate.

- A complete request with usable rows: **$0.01**.
- A partial request with usable rows from at least one selected surface: **$0.01**.
- Confirmed no-data or no usable output: **$0**.
- Successfully inherited data on resume: **no repeat request fee**.

The Actor does not define a custom start event. The pay-per-event price includes Apify platform usage and the configured Apify proxy; a custom proxy provider remains subject to your arrangement with that provider. For a matrix of 12 requests, at most 12 request events are needed, regardless of how many timeline or related rows Google returns. `maxRequests` rejects an oversized input before research starts; its default is 100, with a maximum of 500. The run's maximum charge setting and `maxRunSeconds` bound execution. If an execution limit is reached, inspect the manifest and resume input for work that remains.

The 12-request matrix above costs at most **$0.12** in Actor fees. The two-country comparison example costs at most **$0.02**, including all requested surfaces for each country. A request that returns only confirmed no-data reduces that total.

### API and n8n automation

Run the Actor through the Apify API using its handle, `cauldo/google-trends-bulk-research`. Pass the same JSON body shown above. Send your Apify API token in the `Authorization: Bearer …` header. For longer batches, start a run, poll the run ID until it reaches a terminal status, then download its dataset and `OUTPUT` record. [Apify run API](https://docs.apify.com/api/v2/actors-runs-post)

Download `N8N-WORKFLOW.json` and `N8N-SETUP.md` from your run's key-value store or the links in `OUTPUT`. The n8n template starts a bounded research run, waits for completion, validates the run's terminal status, and retrieves its summary and request bundles. Configure an HTTP authentication credential and edit the research input. No account token is embedded in the template.

For scheduled research, save an Apify task or connect a schedule trigger in n8n. Preserve the run and request IDs in your downstream table, and check partial or failed surface outcomes before updating a dashboard.

### Scope and support

This is an independent Actor using Google Trends' public web data. It does not require a Google login or access to Google's limited-access official Trends API. Availability can change with Google's responses, filtering and rate limits. The official API is a separate product with different scaling capabilities. [Google Trends API alpha](https://developers.google.com/search/apis/trends)

**Related-topic availability:** launch checks returned valid empty topic lists for tested popular terms and a valid topic ID. A bounded check of another Google Trends Actor returned empty topic lists too. The `relatedTopics` surface is collected when Google supplies it; `no_data` can reflect current source availability and does not prove that a term has no related topics. Start with a small test if this surface is essential to your workflow.

For an extraction issue, open the Actor's Issues tab with the run ID, affected request ID, expected surface, and a Google Trends source link. Do not include your API token. Reproducible small inputs make problems much easier to investigate.

# Actor input Schema

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

Each term is researched independently by default, across every selected location and date range. Enter plain keywords or Google topic IDs such as /m/02vqfm (Coffee). If omitted, the sample keyword is coffee. Do not supply this field together with advanced requests.

## `compareKeywords` (type: `boolean`):

Group the keyword list into one Google comparison request per location/date range. Maximum five terms. Keep this off for independent keyword research. Groups are never silently split because separate requests do not share a 0–100 scale. Terms in a comparison must be distinct. Omit this field entirely when using advanced requests, which control their own groups.

## `geos` (type: `array`):

Country or subregion codes, such as US, GB, IN, or US-CA. Use an empty string for worldwide: \[""]. Defaults to \["US"] when omitted. Every location combines with every date range and keyword/group.

## `timeRanges` (type: `array`):

Supported ranges: 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, or YYYY-MM-DD YYYY-MM-DD. Fixed dates must be valid, ordered, on/after 2004-01-01, and not in the future (UTC). Defaults to \["today 3-m"].

## `surfaces` (type: `array`):

Select interest-over-time, regional interest, related search queries, and/or related topics. Defaults to timeline, regions, and relatedQueries. Every requested output receives an explicit status, including valid no-data and extraction failures. Related outputs and regional availability vary with the query and time range.

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

Google's numeric category ID. Use 0 for all categories (the default). An invalid or unavailable category can lead to a source error or no data; this actor does not guess a replacement category.

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

Choose the Google search property. Empty string means Web Search, the default. Shopping uses Google's API value froogle.

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

Google response language, such as en-US, de, or zh-TW. Defaults to en-US. This localizes source labels; it does not restrict searches to that language.

## `timezone` (type: `integer`):

Google's minutes-west-of-UTC offset. Defaults to 0 (UTC). For UTC−5 use 300; for UTC+2 use −120. Affects source time buckets, especially hourly data.

## `requests` (type: `array`):

Optional explicit request list; cannot be combined with top-level keywords or compareKeywords. Each item requires one to five distinct keywords and may set label, geo, time, category, property, and surfaces. A single global geo/time is inherited; when a global list has multiple entries, every explicit request must set that dimension. The list never expands a matrix. Other missing values inherit global settings. Equivalent requests are collected once and preserve input indices and labels.

## `maxRequests` (type: `integer`):

Validation guard for predictable batch size. The actor rejects a batch exceeding this limit before extraction; it never silently discards the excess. Identical requests are deduplicated. A keyword comparison counts as one request per location/date range. The un-deduplicated matrix is limited to 500 entries.

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

Stop starting new research requests after this time budget. Unfinished requests are accounted for and saved for resume. In-flight requests may take up to their timeout to finish. Set the Apify run timeout higher than this budget so the actor can save its report.

## `concurrency` (type: `integer`):

Number of research requests processed concurrently. Low concurrency reduces Google rate limiting. Start with the default of 2; raising this does not guarantee faster or more complete results.

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

Additional attempts for retryable extraction failures. Retries are bounded; blocked or incomplete extraction is reported explicitly rather than treated as no data.

## `requestTimeoutSecs` (type: `integer`):

Timeout for an individual Google HTTP request. One research request can make several HTTP requests to retrieve its selected outputs.

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

Residential Apify Proxy is the default because Google frequently rate-limits datacenter/direct requests. Configured Apify proxy and platform usage are included in the published pay-per-event price. If you supply your own proxies, your proxy provider charges under its own terms. You may disable proxy use, but successful Google access is not guaranteed.

## `resumeFromRunId` (type: `string`):

Optional 17-character run ID. Resume saved work from that run using the original research inputs. You must have access to the earlier run and its storage. Use either this field or resumeKeyValueStoreId. Omit new research fields to restore the earlier batch.

## `resumeKeyValueStoreId` (type: `string`):

Optional 17-character key-value store ID containing this actor's RESUME-STATE. Use this alternative when granting access directly to the saved store. Use either this field or resumeFromRunId, and omit new research fields to restore the earlier batch.

## Actor input object example

```json
{
  "keywords": [
    "coffee"
  ],
  "geos": [
    "US"
  ],
  "timeRanges": [
    "today 3-m"
  ],
  "surfaces": [
    "timeline",
    "regions",
    "relatedQueries"
  ],
  "language": "en-US",
  "maxRequests": 100,
  "maxRunSeconds": 600,
  "concurrency": 2,
  "maxRetries": 2,
  "requestTimeoutSecs": 30,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `researchRequests` (type: `string`):

One bundle per canonical request with keywords, geography, time window, request status, and individual surface outcomes. Scores are relative; inspect normalizationScope before comparing values.

## `summary` (type: `string`):

Counts, stop reason, pricing metadata, reuse information, and links to CSV/JSON exports, manifest, resume input and workflow assets.

## `manifest` (type: `string`):

Every canonical request, including no-data, partial, failed, or unprocessed work. Use this to check completeness independently of the Apify run status.

## `timelineCsv` (type: `string`):

Flat interest-over-time rows, keyword and comparison scope, timestamps, partial-period flags and source provenance. No per-time-point charge.

## `regionsCsv` (type: `string`):

Flat region rows with keyword, geography, source metric and normalization context. Regional comparisons can use different units from timeline interest.

## `relatedQueriesCsv` (type: `string`):

Top and rising query rows, source values, display values, breakout flags, request identity and source links.

## `relatedTopicsCsv` (type: `string`):

Top and rising topic rows with Google topic IDs/titles when available, source values and comparison context.

## `resumeInput` (type: `string`):

Start a new run with this input to finish this batch, reusing completed data. Requires this Actor and the same Apify account.

## `n8nWorkflow` (type: `string`):

Inactive importable workflow to start a bounded research run, poll status and download results. Configure an Apify credential after import.

## `n8nGuide` (type: `string`):

Credential setup, workflow behavior, limits and instructions for interpreting partial outcomes.

## `comparisonGuide` (type: `string`):

Dated feature and price comparison, supplemented by one bounded live run per tested competitor. No generalized speed, accuracy or reliability claims.

# 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"
    ],
    "compareKeywords": false,
    "geos": [
        "US"
    ],
    "timeRanges": [
        "today 3-m"
    ],
    "surfaces": [
        "timeline",
        "regions",
        "relatedQueries"
    ],
    "category": 0,
    "property": "",
    "language": "en-US",
    "timezone": 0
};

// Run the Actor and wait for it to finish
const run = await client.actor("cauldo/google-trends-bulk-research").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"],
    "compareKeywords": False,
    "geos": ["US"],
    "timeRanges": ["today 3-m"],
    "surfaces": [
        "timeline",
        "regions",
        "relatedQueries",
    ],
    "category": 0,
    "property": "",
    "language": "en-US",
    "timezone": 0,
}

# Run the Actor and wait for it to finish
run = client.actor("cauldo/google-trends-bulk-research").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"
  ],
  "compareKeywords": false,
  "geos": [
    "US"
  ],
  "timeRanges": [
    "today 3-m"
  ],
  "surfaces": [
    "timeline",
    "regions",
    "relatedQueries"
  ],
  "category": 0,
  "property": "",
  "language": "en-US",
  "timezone": 0
}' |
apify call cauldo/google-trends-bulk-research --silent --output-dataset

```

## MCP server setup

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

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/Fq9oqTiJCdl86SCaI/builds/UgsyO3wANhlEelt7w/openapi.json
