# Google Autocomplete Scraper: Keyword Suggestions (`cliqtomedia/google-autocomplete-scraper`) Actor

Google Autocomplete suggestions for keyword research: find the phrases and questions people type for your seed keywords, by language and country. Expand with letters, question words or deeper levels and export each suggestion with its query and position.

- **URL**: https://apify.com/cliqtomedia/google-autocomplete-scraper.md
- **Developed by:** [Cliqto Media](https://apify.com/cliqtomedia) (community)
- **Categories:** SEO tools, Marketing
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.03 / 1,000 saved suggestions

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

Find keyword ideas and the questions people type into Google: enter seed keywords and get live Google Autocomplete suggestions for your language and country. Use them to plan articles, product pages and SEO keyword lists. Each saved row shows the suggestion, the Google query that returned it and its position in that response.

No Google account, API key or proxy is needed. A one-keyword run takes a few seconds and costs about $0.002: **$0.001 per start + $0.05 per 1,000 saved suggestions** (lower on higher Apify plans). Google can return an empty list. Requests can also fail or stop at a limit; check `RUN_SUMMARY` to see the reason.

![Google Autocomplete Scraper: seed keywords to live suggestions and JSON or CSV export](https://api.apify.com/v2/key-value-stores/B4JcW3ifWbDj3Swri/records/README-BANNER-20261009.png)

### Table of contents

- [What it does](#what-it-does)
- [How it works](#how-it-works)
- [Quick start](#quick-start)
- [Use cases](#use-cases)
- [Input](#input)
- [Output](#output)
- [Pricing](#pricing)
- [Limits](#limits)
- [API, export and integrations](#api-export-and-integrations)
- [Troubleshooting](#troubleshooting)
- [FAQ](#faq)
- [Related Actors](#related-actors)
- [Support](#support)

### What it does

The Actor sends direct HTTPS requests to Google's public Autocomplete endpoint. No Google login, Google API key, browser or proxy setup is needed. This endpoint is not an official bulk API and may change.

Choose `exact` to send each seed as entered after space cleanup. You can also add letters, numbers or question prefixes. The Actor saves unique suggestions and keeps the first query that returned each one. Set `maxDepth` to 2 or 3 to search the returned suggestions again and collect long-tail phrases. Use `languages` and `countries` to search several locales in one run. Each row also shows how many of your queries returned it (`surfaceCount`).

#### Good fit

- Find phrases to review when you plan an article or product page.
- Compare suggestion lists for the same seed with different language and country preferences.
- Export suggestions with their seed and query for your own search interface research.

> **👉 [Try it now: open the input form](https://console.apify.com/actors/OWdO5gCI8cRbhRWNl/input)**

### How it works

1. You enter seed keywords and choose a language, a country and how to expand each seed (as is, with letters, numbers or question words).
2. The Actor builds a bounded list of queries and asks Google Autocomplete for suggestions for each one. It does not open a browser. With `maxDepth` 2 or 3, each saved suggestion becomes a new query, one level at a time.
3. It removes duplicates and saves each unique suggestion as one Dataset row with its seed, query and position. A `RUN_SUMMARY` record explains empty responses, errors and limits.

> **👉 [Try it now: open the input form](https://console.apify.com/actors/OWdO5gCI8cRbhRWNl/input)**

### Quick start

[![Input form: seed keywords (box 1), language and country (box 2), Google client and expansion mode (box 3)](https://api.apify.com/v2/key-value-stores/B4JcW3ifWbDj3Swri/records/quick-start-form-20261027.png)](https://console.apify.com/actors/OWdO5gCI8cRbhRWNl/input)

1. Open the **Input** tab. Keep the prefilled seed `coffee` or add your own `keywords` (box 1 in the picture).
2. Keep `language: "en"` and `country: "us"`, or add up to 5 values to `languages` and `countries` to compare markets (box 2).
3. Keep `client: "chrome"` and `expansionModes: ["exact"]` (box 3). Keep the prefill `maxResults: 100` for the demo. Set a maximum cost per run in Apify if you need a platform charge cap.
4. Click **Start**.
5. Open **Output → Suggestions** or the default Dataset. Check `suggestion`, `seed`, `generatedQuery` and `expansionMode`, then `googleRank`, `surfaceCount` (Found by queries), `relevance` and `suggestType` (box 5). Open **Run summary** for empty responses, errors and limits.

   [![Output table: suggestions for coffee with Google rank, Found by queries, Google relevance and Type](https://api.apify.com/v2/key-value-stores/B4JcW3ifWbDj3Swri/records/quick-start-table-20261027.png)](https://api.apify.com/v2/key-value-stores/B4JcW3ifWbDj3Swri/records/quick-start-table-20261027.png)

The form prefill is a demo. The runtime `maxResults` default is 500. An API input `{}` has no demo seed and fails validation. Console may restore your previously saved input; check it before starting.

> **👉 [Try it now: open the input form](https://console.apify.com/actors/OWdO5gCI8cRbhRWNl/input)**

### Use cases

| Job | Settings | Fields to use | Next step |
| --- | --- | --- | --- |
| Keyword research for SEO | `keywords`, `expansionModes: ["exact", "alphabet"]` | `suggestion`, `googleRank`, `surfaceCount`, `relevance` | Sort by `surfaceCount` to see the phrases Google offers most often, then check volume in your SEO tool. |
| Find questions for blog posts and FAQs | `expansionModes: ["exact", "questions"]` | `suggestion`, `generatedQuery`, `expansionToken` | Turn the questions into article headings or FAQ entries. |
| Long-tail keyword ideas | `maxDepth: 2` or `3` | `suggestion`, `depth`, `parentSuggestion` | Group phrases by the suggestion they grew from. |
| Compare searches by country and language | `languages: ["en", "de"]`, `countries: ["us", "de"]` in one run | `seed`, `language`, `country`, `googleRank`, `fetchedAt` | Compare locales side by side; differences are not search-volume measurements. |
| Track how suggestions for your brand change | Schedule the same `keywords` | `suggestion`, `googleRank`, `fetchedAt` | Compare exports from different dates. |

> **👉 [Try it now: open the input form](https://console.apify.com/actors/OWdO5gCI8cRbhRWNl/input)**

### Input

#### All input fields

There are no nested input objects. All fields except `keywords` are optional.

| Field | Type | Runtime default | New form prefill | Allowed values and effect |
| --- | --- | --- | --- | --- |
| `keywords` | array of strings; required | None | `["coffee"]` | 1–100 seeds, each up to 120 Unicode characters. Trim spaces and join repeated whitespace. Keep punctuation and Unicode. |
| `language` | string | `"en"` | `"en"` | Lowercase language code such as `en`, `fr`, `ru`, `ja`, `pt-br`. Two or three letters with an optional 2–8 character subtag. Sent as `hl`. |
| `country` | string | `"us"` | `"us"` | Two-letter code such as `us`, `gb`, `fr`, `ru`, `jp`. Lowercased and sent as `gl`. |
| `languages` | array of strings | None | None | Optional, up to 5 language codes. When set, it replaces `language`. Each seed is searched for every `languages` × `countries` pair. |
| `countries` | array of strings | None | None | Optional, up to 5 two-letter codes. When set, it replaces `country`. Sent as `gl`; it does not change IP location. |
| `client` | string | `"chrome"` | `"chrome"` | `chrome` or `firefox`. Lists and metadata can differ. No browser is launched. |
| `expansionModes` | array of strings | `["exact"]` | `["exact"]` | At least one of `exact`, `alphabet`, `numbers`, `questions`. Repeated modes are used once. |
| `questionPrefixes` | array of strings | `["how", "what", "where", "why", "when", "which"]` | None | 1–20 nonempty prefixes, each up to 40 characters. Trimmed and lowercased. Used by `questions`. Validation still applies when that mode is off. |
| `maxGeneratedQueries` | integer | 50 | 50 | 1–500 planned Google queries. Retries are extra HTTP attempts. |
| `maxDepth` | integer | 1 | 1 | 1–3. `1`: suggestions for your queries only. `2`: also search each saved suggestion. `3`: one more level. All levels share `maxGeneratedQueries` and `maxResults`. |
| `maxResults` | integer | 500 | 100 | 1–5,000 saved unique rows. Stops additional row writes at the cap. |
| `maxRowsPerSeed` | integer | 0 | None | 0–5,000. Stop saving new rows for one seed after this many, counted over all its languages and countries, in query order (not the strongest first); other seeds continue. `0` = no per-seed limit. Reported once per seed in `outcomes`; it does not change the run status. |
| `maxSuggestionsPerQuery` | integer | 0 | None | 0–15. Keep only the first N suggestions of each Google response. `0` keeps all (Google sends up to about 10–15). |
| `maxConcurrency` | integer | 4 | 4 | 1–8 simultaneous requests. Does not change row order. |
| `requestTimeoutMillis` | integer | 8,000 | None | 1,000–30,000 ms per request attempt, also bounded by the remaining source deadline. |
| `maxRetries` | integer | 1 | None | 0–2 retries for network, timeout and transient server errors. Blocks, redirects, rate limits and invalid payloads are not retried. |
| `maxResponseBytes` | integer | 65,536 | None | 1,024–262,144 bytes per response. An oversized response is a technical failure. |
| `maxRunTimeSeconds` | integer | 240 | None | 5–300 seconds for source work. A shorter platform deadline also applies, with time reserved for saving output. A larger platform timeout does not extend this input limit. |
| `includeRawMetadata` | boolean | `true` | None | Keep Google metadata when available. `false` saves `{}` in `metadata`. |
| `maxChargeUsd` | number | None | None | Form range: 0.00005–1.50 USD. Optional estimate cap for saved suggestion events. It does not cap platform usage or source requests. |

For older API callers, `seedKeywords` remains an alias when `keywords` is absent. Runtime also accepts a comma- or newline-separated string for either seed field. The form uses an array. API numeric settings also accept numeric strings. Unknown extra keys have no runtime effect; the form schema disallows them.

Missing seeds, an empty array, a batch over 100 entries, non-string seeds or invalid settings produce a failed summary before any Google request. Empty-after-trimming or overlong seeds are recorded individually as `invalid_input`. Valid seeds in that batch can still run; invalid-only batches save no suggestion rows. Blank language/country/client values use their defaults. Optional numeric `null` values use their defaults.

#### Interacting settings

| Setting | Behavior |
| --- | --- |
| Expansion | `exact`: the seed; `alphabet`: seed + space + `a`–`z`; `numbers`: seed + space + `0`–`9`; `questions`: prefix + space + seed. Queries over 150 characters are skipped and reported. |
| Query cap | Seeds take turns: the first query of every seed, then the second of every seed, and so on; within a seed, modes follow the selected order. Each query is planned for every language and country pair before the next query. Keep at most `maxGeneratedQueries`, so a small cap still reaches every seed. A query-plan limit gives `stopped`, even if all retained requests succeed. |
| Depth | Level 0 is your planned queries. Each new suggestion saved at one level is sent as an exact query at the next level, in save order. A query already sent for the same seed is not sent again. Deeper levels use what is left of `maxGeneratedQueries`, shared between seeds in turn (one query per seed per round), so every seed gets deeper queries before the budget runs out. Within one seed, deeper queries follow save order, so with several locales and a small budget the first locale can get more of them; when it runs out, the summary is `stopped`. A row or charge cap ends recursion. A suggestion longer than 150 characters is not sent as a next-level query; it is skipped, reported in `outcomes` and does not change the run status. |
| Row / charge cap | Requests are fetched before rows are saved. A low `maxResults` or `maxChargeUsd` does not reduce that query plan. Keep the query cap small too. |
| Several languages / countries | Every pair is a separate set of requests, so 2 languages × 2 countries uses 4 times the queries of one locale. All pairs share `maxGeneratedQueries`. Rows are kept per locale. |
| Duplicate seeds or expansion paths | Dedupe suggestions within the same normalized seed, language, country, client and surface. Keep the first query's provenance; later queries that return the same suggestion add to `surfacedByQueries`, `surfaceCount` and `bestGoogleRank` of that row at no extra charge. Repeats are still counted after `maxResults` or `maxChargeUsd` stops saving new rows. The same suggestion under another seed can be a separate row. |
| Request completion | Save rows in query-plan order, then Google response order. Concurrent completion order does not change grouping. |

#### Example: three seed keywords

This input produced the output example below in a live Cloud run:

```json
{
  "keywords": ["coffee", "café & bakery", "кофе"],
  "language": "en",
  "country": "us",
  "client": "firefox",
  "expansionModes": ["exact"],
  "maxResults": 30,
  "maxConcurrency": 2,
  "maxRetries": 1
}
```

The observed run saved 30 rows. That count is an example, not a promise for another run. Each row's `seed` and `generatedQuery` identify its input.

#### Example: bounded question expansion

```json
{
  "keywords": ["coffee"],
  "expansionModes": ["exact", "questions"],
  "questionPrefixes": ["how", "what"],
  "maxGeneratedQueries": 3,
  "maxResults": 100
}
```

This plans `coffee`, `how coffee` and `what coffee`. It does not expand their results again. More queries can add source work and saved-row charges.

> **👉 [Try it now: open the input form](https://console.apify.com/actors/OWdO5gCI8cRbhRWNl/input)**

### Output

#### Dataset fields

Each row is a saved useful suggestion. Error and empty outcomes are in `RUN_SUMMARY`, not extra Dataset rows. The runtime emits all fields below.

| Field | Type | Meaning / empty values |
| --- | --- | --- |
| `id` | string | Synthetic `sug_` ID from normalized suggestion and first saved query/context. Google supplies no suggestion ID. Stable for the same text and path; a different first path can change it. |
| `suggestion` | string | Google suggestion text after JSON decoding. No HTML extraction, translation or scoring is applied. |
| `normalizedSuggestion` | string | Trimmed text with joined whitespace and lowercase letters, used for dedupe. |
| `seed` | string | Accepted seed after whitespace cleanup. |
| `normalizedSeed` | string | Seed used for planning; same whitespace cleanup, not lowercased. |
| `generatedQuery` | string | Exact query sent to Google. |
| `expansionMode` | string | `exact`, `alphabet`, `numbers` or `questions`. |
| `expansionToken` | string or null | Added letter, number or question prefix. `null` for exact. |
| `depth` | integer | `0` for your planned queries, `1`–`2` for recursive levels (`maxDepth` 2–3). |
| `parentSuggestion` | string or null | Suggestion that was searched to get this row; equals `generatedQuery` on recursive levels. `null` at depth 0. |
| `language` | string | Requested `hl`; not detected result language. |
| `country` | string | Requested `gl`; not a measured user or IP location. |
| `client` | string | `chrome` or `firefox`. |
| `surface` | string | Always `web`. |
| `googleRank` | integer | One-based position in this query's suggestion response. It is not a website search ranking. Dedupe can leave gaps. |
| `bestGoogleRank` | integer | Best (lowest) position of this suggestion across all queries that returned it. |
| `surfaceCount` | integer | Number of different queries of this seed and locale whose response contained this suggestion. Higher means Google offers it more often; it is not search volume. |
| `surfacedByQueries` | array of strings | Those queries, first one first, up to 20. |
| `relevance` | number or null | Google relevance score from the chrome response (`suggestrelevance`). Undocumented, compare only within one response. `null` for firefox. |
| `suggestType` | string or null | Google suggestion type such as `QUERY` (`suggesttype`). `null` for firefox. |
| `sourceUrl` | string | Fixed Google HTTPS origin and parameters. `q` is `<redacted>`; use `generatedQuery` for your query provenance. |
| `sourceRequestId` | string | Synthetic `req_` ID for seed index, query and context. Moving a seed in the input can change it. |
| `fetchedAt` | ISO UTC string | Time the row was assembled after source work; not the time a suggestion was first created by Google. |
| `metadata` | object | Per-suggestion `google:` metadata with the prefix removed. Keys/values can change; missing values can be `null`. `{}` when unavailable or disabled. Relevance/type/subtype values are undocumented, not search volume. |
| `duplicateOf` | string or null | `null` in current output. Duplicate rows are skipped. |

#### Output surfaces and run summary

| Surface | What it contains |
| --- | --- |
| Default Dataset | Full suggestion rows. The **Suggestions** view shows selected columns. Use the full Dataset API/export for all fields. |
| Output → `suggestions` | A generated link to the Dataset Suggestions view. |
| Output → `runSummary` | A generated link to the KVS `RUN_SUMMARY` JSON record. |
| KVS `INPUT` | The input saved for the run. |
| KVS `RUN_SUMMARY` | Final input, status, limits, counters, timing, event estimate and non-row outcomes. |

The output schema generates the two links. The Actor does not write a separate `OUTPUT` record. An absent `OUTPUT` record is expected.

`RUN_SUMMARY` has these fields:

| Field / group | Contents |
| --- | --- |
| `schemaVersion`, `status`, `verdict` | Version `1`, status `succeeded` / `partial` / `stopped` / `failed`, and a short explanation. |
| `startedAt`, `finishedAt`, `durationMs`, `input` | ISO UTC times, milliseconds and normalized input fields listed above. |
| `limits` | Booleans: `maxGeneratedQueriesReached`, `maxResultsReached`, `maxChargeReached`, `maxRunTimeReached`. Query-length skips share the generated-query limit flag. |
| `counts` | `receivedSeeds`, `validSeeds`, `invalidInputs`, `generatedQueriesPlanned`, `generatedQueriesSkipped`, `attemptedRequests`, `savedSuggestions`, `duplicatesSkipped`, `emptyResponses`, `technicalFailures`, `retries`, `bytesDownloaded`. Logical requests and retries are separate; bytes include retry response bodies. |
| `performance` | `timeToFirstUsefulRowMs` is time to the first assembled row after fetching the plan, not first persisted output. Source latency: `p50SourceLatencyMs`, `p95SourceLatencyMs`; `usefulSuggestionsPerMinute` uses core duration. Values can be `null` when no row/request exists. |
| `pricing` | Suggestion-event fields: `eventName`, `pricePerSuggestionUsd`, `chargeableEvents`, row-only `estimatedChargeUsd`, `maxChargeUsd` (number or null), `chargingApplied` (boolean). When the standard start event is active, `platformStart` reports its automatic estimate and `estimatedTotalChargeUsd` includes start plus rows. These are estimates, not a customer invoice. |
| `source` | `host`, `transport`, `client`, `language` and `country` (first values), `languages`, `countries` (all values), `parserVersion`. |
| `outcomes` | Non-row outcomes with `kind`, `message`, and optional `seed`, `generatedQuery`, `sourceRequestId`, `count`, `statusCode`. Optional fields can be absent. Your queries are kept here for your own run analysis. |
| `warnings` | Completeness, affiliation and charging notices. |

#### Output example

This is one full row from a Cloud run with `languages: ["en", "de"]`, `countries: ["us", "de"]` and `expansionModes: ["exact", "alphabet"]`. Two queries returned it, so `surfaceCount` is 2. Suggestions and their positions may change.

```json
{
  "id": "sug_4e317e5fb04b2cef1e19ba897d3de863",
  "suggestion": "running shoes adidas",
  "normalizedSuggestion": "running shoes adidas",
  "seed": "running shoes",
  "normalizedSeed": "running shoes",
  "generatedQuery": "running shoes",
  "expansionMode": "exact",
  "expansionToken": null,
  "depth": 0,
  "parentSuggestion": null,
  "language": "en",
  "country": "de",
  "client": "chrome",
  "surface": "web",
  "googleRank": 5,
  "bestGoogleRank": 1,
  "surfaceCount": 2,
  "surfacedByQueries": [
    "running shoes",
    "running shoes a"
  ],
  "relevance": 560,
  "suggestType": "QUERY",
  "sourceUrl": "https://suggestqueries.google.com/complete/search?client=chrome&q=%3Credacted%3E&hl=en&gl=de",
  "sourceRequestId": "req_5c14dece7a859a6ce3c3bcc866cd6c03",
  "fetchedAt": "2026-10-27T04:37:02.674Z",
  "metadata": {
    "clientdata": {
      "bpc": false,
      "tlw": false
    },
    "suggestrelevance": 560,
    "suggestsubtypes": [
      512
    ],
    "suggesttype": "QUERY",
    "verbatimrelevance": 1300
  },
  "duplicateOf": null
}
```

#### Empty, partial and failed output

- `succeeded`: all retained planned requests completed. An empty Dataset with `emptyResponses > 0` can be a valid result.
- `partial`: some seeds or source requests failed. Useful rows from other queries remain available.
- `stopped`: a query, length, row, charge or time limit prevented further work or writes. Already fetched requests remain in the counters.
- `failed`: invalid-only input, resource error, technical failure or internal error prevented useful output. Check `outcomes`.

The Apify run status and `RUN_SUMMARY.status` are separate. A completed process can be `SUCCEEDED` while the summary reports `failed` or `stopped`. Check the Dataset **and** the summary.

> **👉 [Try it now: open the input form](https://console.apify.com/actors/OWdO5gCI8cRbhRWNl/input)**

### Pricing

The price is **$0.001 per Actor start + $0.00005 per saved unique suggestion**: **$0.05 per 1,000 rows**. Higher Apify plans pay less per row:

| Apify plan | Price per saved suggestion | Per 1,000 rows |
| --- | ---: | ---: |
| Free | $0.00005 | $0.050 |
| Bronze | $0.000045 | $0.045 |
| Silver | $0.00004 | $0.040 |
| Gold and higher | $0.000035 | $0.035 |

Apify charges the standard start event automatically. The start fee scales with run memory: one start event per GB, minimum one. With the default 256 MB, and anywhere in this Actor's 256–1,024 MB range, that is one start event ($0.001). Empty and invalid-only runs still have the start charge. Duplicates, invalid seeds, empty lists and failed requests have no suggestion-event charge. Partial runs pay the start charge plus only the rows saved before completion or a cap. You do not pay platform usage separately.

Cost examples at the Free plan price:

| Scenario | Saved suggestion events | Actor event charge |
| --- | ---: | ---: |
| Three-seed exact run with 30 rows | 30 | $0.00250 |
| Example one-seed run with 15 saved rows | 15 | $0.00175 |
| Valid empty or invalid-only run | 0 | $0.00100 |
| Partial/limited run with 2 saved rows | 2 | $0.00110 |
| 1,000 saved rows in one run | 1,000 | $0.05100 |
| Maximum 5,000 saved rows in one run | 5,000 | $0.25100 |
| `coffee` with `maxDepth: 3` and 500 queries (about 2,800 rows) | 2,783 | $0.14015 |

These amounts include one start and the saved suggestion events. Check Console's cost details for the applied price and plan rules.

For a cap on total Actor charges, use Apify's maximum cost per run (`maxTotalChargeUsd` in API calls); the minimum is $0.00105 for one start and one suggestion. `maxChargeUsd` is a separate estimate for suggestion events only, excluding the start; it uses the per-row price of your Apify plan. `RUN_SUMMARY.pricing.estimatedChargeUsd` preserves that row-only meaning; when the start event is active, `platformStart` and `estimatedTotalChargeUsd` show the additional start estimate and total. These estimates are not a customer invoice. Neither limit guarantees every planned query will run or every returned suggestion will be saved.

> **👉 [Try it now: open the input form](https://console.apify.com/actors/OWdO5gCI8cRbhRWNl/input)**

### Limits

- Returns Google Search suggestions only. No search results, website rankings, search volume, CPC, Google Ads data or AI-generated keywords. No YouTube, Amazon, Places or Maps. Recursion goes at most 3 levels deep.
- Suggestions change with time, location, language and Google's filters. Country and language are request preferences: they do not set the request's IP location or guarantee a language for every result. [Google explains how Autocomplete works](https://support.google.com/websearch/answer/7368877?hl=en).
- No complete keyword list and no SEO ranking prediction. The Google endpoint is public but not an official bulk API and may change.
- Hard limits: 100 seeds, 120 characters per seed, 150 per generated query, 500 planned queries, 5,000 saved rows, concurrency 8, two retries and 262,144 bytes per response.
- Default memory is 256 MB; 256–1,024 MB is supported. A larger platform timeout keeps the internal source limit unchanged.
- No output-text filter and no stateful unchanged/delta mode.

> **👉 [Try it now: open the input form](https://console.apify.com/actors/OWdO5gCI8cRbhRWNl/input)**

### API, export and integrations

- **API:** use the Actor's **API** tab to start a run with the same input fields and read its default Dataset after it finishes. Keep your Apify API token in a private credential store, not in shared links or input examples.
- **Export:** JSON or CSV from Console. Use `suggestion`, `seed` and `generatedQuery` as the next step's text fields. Keep `id`, locale and `fetchedAt` when comparing snapshots.
- **Scheduling:** Apify can schedule runs. Each run creates a fresh snapshot; this Actor does not keep a change baseline, so repeated runs can return and charge the same current suggestions. No schedule is enabled by using this Actor.

#### Use with AI agents (MCP)

- MCP server with only this Actor: `https://mcp.apify.com?tools=cliqtomedia/google-autocomplete-scraper`.
- Smallest useful input: `{"keywords": ["coffee"], "language": "en", "country": "us"}`.
- For long-tail phrases add `"maxDepth": 2` (or 3) and raise `maxGeneratedQueries` and `maxResults`; one seed at depth 3 can return about 2,800 rows.
- Several locales in one run: `"languages": ["en", "de"], "countries": ["us", "de"]`. Keep a keyword list short with `maxRowsPerSeed`.
- Key output fields: `suggestion` (the suggested phrase), `seed` (your keyword), `generatedQuery` (the exact query sent), `googleRank` (position in that response), `surfaceCount` (how many queries returned it), `depth`, `parentSuggestion` and `RUN_SUMMARY.status` (`succeeded`, `partial`, `stopped` or `failed`).
- A one-keyword exact run usually finishes in a few seconds with about 15 rows and costs about $0.002. Respect the hard limits above; keep `maxGeneratedQueries` small when you need few requests.

> **👉 [Try it now: open the input form](https://console.apify.com/actors/OWdO5gCI8cRbhRWNl/input)**

### Troubleshooting

| Symptom | What to check | Safe next action |
| --- | --- | --- |
| Empty Dataset | `status`, `emptyResponses`, `technicalFailures`, `outcomes` | Try a clear public seed only when the summary confirms a valid empty response. |
| `invalid_input` | Seed count/length and allowed settings | Correct the input; do not add a login or token. |
| `blocked_or_consent`, `rate_limited` | Access denial, HTML or redirects | Stop repeated runs. Retry later with a small query plan and lower concurrency. |
| `malformed_response` | Unexpected JSON, suggestion types or a different echoed query | Share the run ID with support. Do not treat it as an empty suggestion list. |
| `retry_exhausted` | Timeout/network/server failure after bounded attempts | Use fewer queries or lower concurrency; check the summary before retrying. |
| `response_too_large` | Response size exceeded `maxResponseBytes` | Check for source drift; increase the byte cap only within the documented range. |
| `stopped` with useful rows | `limits` and `outcomes` | Export the rows already saved. Increase only the specific limit you need. |
| `resource_error` | Memory outside 256–1,024 MB | Choose supported memory. This is separate from invalid input. |
| Different suggestions on repeat | Time, locale, client and query paths | Compare snapshots, not a promised permanent keyword set. |

> **👉 [Try it now: open the input form](https://console.apify.com/actors/OWdO5gCI8cRbhRWNl/input)**

### FAQ

#### Do I need a Google account or Google API key?

No. An Apify account is needed to run the Actor. No Google credentials are used.

#### Are these search volumes or Google Search rankings?

No. `googleRank` is a position inside an Autocomplete response. Metadata does not provide verified search volume, CPC or competition.

#### Can I use non-English keywords?

Yes. Unicode is kept, including Cyrillic and accented text. Set the requested language and country. Google can still return suggestions in another language.

#### Are country results exact local results?

No. `country` and `countries` send `gl`; they do not change IP location, so two countries can return the same list. Results can also depend on Google's current behavior.

#### Will a repeat run have the same IDs and order?

The same saved text and first query/context have the same synthetic ID. Query-plan grouping is deterministic. Google's suggestion text and order can change, and a different first expansion path can change an ID.

#### Why did a low row limit still make several requests?

The Actor fetches its bounded query plan before saving rows. Lower `maxGeneratedQueries` when you also need fewer source requests.

#### Do empty runs cost nothing?

No. The $0.001 start event still applies. There is no suggestion event when no useful row is saved. Check the actual cost breakdown in Console.

#### Can it expand suggestions recursively?

Yes. Set `maxDepth` to 2 or 3. Each saved suggestion is searched again, and new rows show `depth` and `parentSuggestion`. Raise `maxGeneratedQueries` and `maxResults` for deeper runs: every level shares those limits.

#### Can it monitor changes?

It can export repeated snapshots, but it has no built-in delta state or unchanged-result filter. Compare exported snapshots in your own workflow.

> **👉 [Try it now: open the input form](https://console.apify.com/actors/OWdO5gCI8cRbhRWNl/input)**

### Related Actors

- [Google Search Results Scraper](https://apify.com/cliqtomedia/google-search-scraper) — check which pages rank in Google for the suggestions you found.
- [Google Trends Scraper](https://apify.com/cliqtomedia/google-trends-scraper) — compare interest over time and by region for your best phrases.
- [DuckDuckGo & Bing Search Scraper](https://apify.com/cliqtomedia/duckduckgo-bing-search) — see results for the same phrases outside Google.
- [Google Ads Transparency Scraper](https://apify.com/cliqtomedia/google-ads-transparency-scraper) — see which advertisers run ads on topics from your keyword list.

> **👉 [Try it now: open the input form](https://console.apify.com/actors/OWdO5gCI8cRbhRWNl/input)**

### Support

Open an issue in this Actor's Apify **Issues** tab. Include the run ID, selected mode, non-sensitive input settings and the relevant `RUN_SUMMARY` outcome. Remove private keywords if needed. Never share API tokens, cookies, account or billing details.

This project is not affiliated with, endorsed by, or sponsored by Google. The Google name identifies the source.

> **👉 [Try it now: open the input form](https://console.apify.com/actors/OWdO5gCI8cRbhRWNl/input)**

# Changelog

This Actor's version history is a separate document: https://apify.com/cliqtomedia/google-autocomplete-scraper/changelog.md

# Actor input Schema

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

Add 1-100 seed keywords, each up to 120 characters. Spaces are trimmed and repeated spaces are joined. Unicode is kept. Duplicate seeds do not create duplicate saved rows.

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

Language preference sent as Google hl, such as en, fr, ru or pt-br. This is a preference, not a guarantee that every suggestion uses that language.

## `country` (type: `string`):

Two-letter country preference sent as Google gl, such as us, gb, fr or ru. This does not set the request IP location.

## `languages` (type: `array`):

Optional. Up to 5 language codes such as en, de or fr. When set, it replaces Language and every keyword is searched in each language and country pair. Each pair uses requests from Maximum Google requests.

## `countries` (type: `array`):

Optional. Up to 5 two-letter country codes such as us, gb or de. When set, it replaces Country. Country is sent as Google gl; it does not change the request IP location, so results can match across countries.

## `client` (type: `string`):

Choose chrome or firefox. They can return different suggestions and metadata. No browser is launched.

## `expansionModes` (type: `array`):

Choose one or more modes. exact sends the seed. alphabet adds a-z; numbers adds 0-9; questions adds your prefixes before the seed. With maxDepth 1, results are not expanded again.

## `questionPrefixes` (type: `array`):

Used for questions mode. Add 1-20 prefixes of up to 40 characters. Combined queries over 150 characters are skipped and reported.

## `maxGeneratedQueries` (type: `integer`):

Maximum planned Google queries, 1-500. Retries are counted separately. A small result limit does not reduce the query plan.

## `maxDepth` (type: `integer`):

1 = only suggestions for your keywords. 2 = also search each saved suggestion and save its suggestions. 3 = one more level. Deeper levels share the Maximum Google requests and Maximum saved suggestions limits.

## `maxResults` (type: `integer`):

Maximum saved unique suggestions, 1-5000. Runtime default is 500; the new form prefill is 100. No result count is guaranteed.

## `maxRowsPerSeed` (type: `integer`):

Optional. Stop saving new suggestions for one seed keyword after this many rows, 0-5000. 0 means no per-keyword limit. Other keywords continue.

## `maxSuggestionsPerQuery` (type: `integer`):

Optional. Keep only the first N suggestions of each Google response, 0-15. 0 keeps all of them (usually up to 10-15).

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

Maximum simultaneous Google requests, 1-8. Lower it if requests fail. Saved rows keep query plan order.

## `requestTimeoutMillis` (type: `integer`):

Timeout for one Google request in milliseconds.

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

Retries for transient network or server errors. Blocks and bad requests are not retried.

## `maxResponseBytes` (type: `integer`):

Stops parsing if one Google response is larger than this byte limit.

## `maxRunTimeSeconds` (type: `integer`):

Internal source-work limit, 5-300 seconds. Default is 240. A shorter platform timeout also limits source work and reserves time to save results.

## `includeRawMetadata` (type: `boolean`):

Keep metadata returned by Google for each suggestion. Missing metadata is an empty object. Values are undocumented and are not search volume.

## `maxChargeUsd` (type: `number`):

Optional estimated suggestion-event cap in USD. It limits saved rows, not source requests or total platform usage. Also set a maximum cost per run in Apify.

## Actor input object example

```json
{
  "keywords": [
    "coffee"
  ],
  "language": "en",
  "country": "us",
  "client": "chrome",
  "expansionModes": [
    "exact"
  ],
  "questionPrefixes": [
    "how",
    "what",
    "where",
    "why",
    "when",
    "which"
  ],
  "maxGeneratedQueries": 50,
  "maxDepth": 1,
  "maxResults": 100,
  "maxRowsPerSeed": 0,
  "maxSuggestionsPerQuery": 0,
  "maxConcurrency": 4,
  "requestTimeoutMillis": 8000,
  "maxRetries": 1,
  "maxResponseBytes": 65536,
  "maxRunTimeSeconds": 240,
  "includeRawMetadata": true
}
```

# Actor output Schema

## `suggestions` (type: `string`):

Dataset table with one saved row per unique useful suggestion.

## `runSummary` (type: `string`):

JSON report with input, request, result, stop, warning and cost accounting.

# 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"
    ],
    "language": "en",
    "country": "us",
    "client": "chrome",
    "expansionModes": [
        "exact"
    ],
    "maxGeneratedQueries": 50,
    "maxDepth": 1,
    "maxResults": 100,
    "maxConcurrency": 4
};

// Run the Actor and wait for it to finish
const run = await client.actor("cliqtomedia/google-autocomplete-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": ["coffee"],
    "language": "en",
    "country": "us",
    "client": "chrome",
    "expansionModes": ["exact"],
    "maxGeneratedQueries": 50,
    "maxDepth": 1,
    "maxResults": 100,
    "maxConcurrency": 4,
}

# Run the Actor and wait for it to finish
run = client.actor("cliqtomedia/google-autocomplete-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": [
    "coffee"
  ],
  "language": "en",
  "country": "us",
  "client": "chrome",
  "expansionModes": [
    "exact"
  ],
  "maxGeneratedQueries": 50,
  "maxDepth": 1,
  "maxResults": 100,
  "maxConcurrency": 4
}' |
apify call cliqtomedia/google-autocomplete-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cliqtomedia/google-autocomplete-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/OWdO5gCI8cRbhRWNl/builds/n7A9KRbcKgY4wl2kc/openapi.json
