# Google Autocomplete Keyword Expander – A-Z & Questions (`raspberry_rondel/google-autocomplete-keywords`) Actor

Expand seed keywords with Google Autocomplete suggestions: a-z, 0-9, question words, prepositions and custom modifiers, chosen language/country (hl/gl), optional recursion. One row per keyword or per suggestion, plus CSV. US$0.002 per keyword with results, no start fee. Unofficial; no proxy needed.

- **URL**: https://apify.com/raspberry_rondel/google-autocomplete-keywords.md
- **Developed by:** [星賢 陳](https://apify.com/raspberry_rondel) (community)
- **Categories:** SEO tools, Marketing, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 keyword expandeds

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 Autocomplete Keyword Expander – A-Z, Questions, Language & Country Options

Give it seed keywords. It returns the suggestions Google Autocomplete shows for each seed, plus for the seed with a–z, 0–9, question words, prepositions or your own modifiers added. Use it for long-tail keyword research, content ideas and "people also ask"-style question lists. Language (`hl`) and country (`gl`) are configurable; no proxy and no Google account are needed.

> **Unofficial. Not affiliated with, endorsed by or sponsored by Google.** "Google" is used only to describe the data source. The Actor reads Google's public, undocumented autocomplete endpoint (`suggestqueries.google.com`), which Google can change or limit without notice.

### What you get

- One dataset row per expanded keyword (default): `suggestions` (array of strings), `suggestionCount`, and `details` (each suggestion with the `mode`, `modifier`, exact `query` sent and `rank` 1–10).
- `OUTPUT.csv` in the key-value store: flat, one row per suggestion: `seed, keyword, depth, mode, modifier, query, suggestion, rank, lang, country, status, error`.
- `RUN_SUMMARY`: requests, 429s, keywords with data / empty / failed, charged events.
- Set `outputLayout: "flat"` if you want one dataset row per suggestion instead.

Suggestions are deduplicated per seed (or per run with `dedupAcrossSeeds`). Optional recursion (`maxDepth` 1–2, hard cap 2) expands the top suggestions of each keyword again; `maxKeywords` (max 1000) caps the total. By default it is 100, or the number of seeds if there are more, so every seed is expanded. If you set a lower limit, the seeds beyond it get a free row with status `skipped-max-keywords`.

### Example output (real run, 2026-10-17, seed "air fryer", hl=en, gl=us)

Dataset row (arrays shortened here; the real row had 375 suggestions):

```json
{
  "seed": "air fryer", "keyword": "air fryer", "depth": 0, "status": "ok", "suggestionCount": 375,
  "suggestions": ["air fryer", "air fryer baked potato", "air fryer chicken breast", "air fryer salmon", "air fryer chicken wings", "…"],
  "details": [{ "suggestion": "air fryer baked potato", "mode": "base", "modifier": null, "query": "air fryer", "rank": 2 }, "…"],
  "lang": "en", "country": "us", "error": null
}
```

`OUTPUT.csv` rows from the same run:

```
seed,keyword,depth,mode,modifier,query,suggestion,rank,lang,country,status,error
air fryer,air fryer,0,base,,air fryer,air fryer baked potato,2,en,us,ok,
air fryer,air fryer,0,questions,why,why air fryer,why air fryer is better than oven,2,en,us,ok,
air fryer,air fryer,0,questions,why,why air fryer,why air fryer smell like plastic,3,en,us,ok,
air fryer,air fryer,0,alphabet,b,air fryer b,air fryer broccoli,4,en,us,ok,
```

### Expansion modes

| Input | Queries per keyword | Example query |
|---|---|---|
| `includeBase` (default on) | 1 | `air fryer` |
| `alphabet` (default on) | 26 | `air fryer b` |
| `questions` (default on) | 12: how, what, why, when, where, which, who, can, is, are, does, will | `why air fryer` |
| `numbers` | 10 | `air fryer 2` |
| `prepositions` | 12: for, with, without, to, near, vs, like, versus, and, or, is, can | `air fryer vs` |
| `customModifiers` + `customPosition` | 1 per modifier per position | `best air fryer` |

Google returns up to 10 suggestions per query. They may not contain the exact modifier: for example, `how standing desk` returned "what standing desk to buy".

### Measured performance (internal tests, 2026-10-17; not a guarantee)

50-seed run on Apify (internal test, 2026-10-17, build 0.2.8 with the `RondelBot/1.0` User-Agent, default modes = 39 queries per seed, 256 MB): **50/50 seeds returned suggestions, 1,950 requests, 0 throttled (0 × HTTP 429)**, 17,467 suggestions (232–381 per seed, average 349), 878 s (about 18 s per seed; requests are sent one at a time with a 400 ms pause). At that pace, the maximum of 1,000 keywords per run should fit in the default 6-hour run timeout (an estimate; not tested).

Same 20 seeds, run on Apify at the same time with the `RondelBot/1.0` User-Agent and with a standard Firefox User-Agent (internal test, 2026-10-17, build 0.2.7, default modes): both runs **20/20 seeds with suggestions, 780 requests, 0 failed requests**. The `RondelBot/1.0` User-Agent returned 6,581 suggestions and the Firefox one 6,884 (about 4% fewer with `RondelBot/1.0`).

Not tested with the current version: runs larger than 50 seeds, sustained scheduled use, or more than two parallel runs. Google may throttle heavier use. The Actor then retries 408/429/5xx errors with exponential backoff and honours `Retry-After`.

### Pricing

Pay per event: **US$0.002 per keyword expanded** (a seed or a recursive child keyword that returned at least one suggestion). No start fee.

- Free: keywords where every query failed, keywords with no suggestions, and keywords skipped because your run hit its maximum charge or `maxKeywords`.
- **Charging depends on whether suggestions came back, not on their quality.** A keyword that gets any suggestions from Google is charged, even if the suggestions are not useful to you. A keyword with no suggestions gets status `empty` and is free (internal test, 2026-10-18, build 0.2.11: 4 random letter strings such as "qzxjv wplkq zzvx" each returned no suggestions in 2 runs and were not charged). Results for random strings can change over time.
- With recursion, every expanded child keyword is a separate event. Example: `maxDepth: 1, recursionTopN: 5` turns 1 seed into up to 6 events.
- Cap your spend with the run's maximum total charge; the remaining keywords are skipped and not charged. Charges are recorded per keyword, so a platform restart does not charge the same keyword twice.

### Input example

```json
{
  "seeds": ["air fryer", "standing desk"],
  "alphabet": true,
  "questions": true,
  "prepositions": false,
  "customModifiers": ["best", "cheap"],
  "customPosition": "prefix",
  "hl": "en",
  "gl": "us",
  "maxDepth": 0,
  "outputLayout": "keyword"
}
```

### Google Autocomplete API with Python, JavaScript and curl

Replace `<YOUR_APIFY_TOKEN>` with your token from Apify Console → Settings → API & Integrations.

**curl** (waits for the run and returns the dataset items):

```bash
curl -X POST "https://api.apify.com/v2/acts/raspberry_rondel~google-autocomplete-keywords/run-sync-get-dataset-items" \
  -H "Authorization: Bearer <YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"seeds": ["air fryer"], "alphabet": false, "questions": true}'
```

**Python** (`pip install "apify-client>=3"`):

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("raspberry_rondel/google-autocomplete-keywords").call(
    run_input={"seeds": ["air fryer"], "alphabet": False, "questions": True}
)
for row in client.dataset(run.default_dataset_id).iterate_items():
    print(row["keyword"], row["status"], row["suggestionCount"], row["suggestions"][:5])
```

**JavaScript / Node.js** (`npm install apify-client`):

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('raspberry_rondel/google-autocomplete-keywords').call({
    seeds: ['air fryer'],
    alphabet: false,
    questions: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const row of items) console.log(row.keyword, row.status, row.suggestionCount, row.suggestions.slice(0, 5));
```

### Related: Google Trends

Need to know how interest in these keywords changes over time? Try our [Google Trends Bulk Compare Actor](https://apify.com/raspberry_rondel/actor-google-trends): many keywords on one 0–100 scale, as flat rows and CSV.

### FAQ

**Is this search volume?** No. Autocomplete shows what Google suggests, not how often a term is searched.

**Are the results the same as in my browser?** Not always. Browser suggestions can be personalised (signed-in history, location, device). This Actor sends anonymous requests with your `hl`/`gl` from Apify's servers, and Google changes suggestions over time.

**Which languages and countries work?** The Actor checks the `hl`/`gl` codes before it sends a request. Codes that are not valid language or two-letter country codes (for example `hl: "xx-INVALID"` or `gl: "zz"`) are rejected: the run fails with an error message, nothing is fetched and nothing is charged. Valid codes are passed to Google as entered (surrounding spaces removed, the country code in lower case). This check confirms the code is a real language or country code, not that Google has suggestions for it. We checked only Japanese (`hl=ja`, `gl=jp`), which returned correct UTF-8 text. Other languages were not tested individually. The CSV is UTF-8 with a BOM so Excel opens it correctly.

**Why does one keyword have fewer than 39 × 10 suggestions?** Duplicates are removed, and many queries return fewer than 10 suggestions.

**What happens on errors?** Each failed query is retried with backoff. If some queries for a keyword fail, it is marked `partial` (charged, because it has data). If all fail, it gets an `error` row and is not charged.

**Does it collect personal data?** It is not designed to. It only sends your seed keywords and stores Google's public suggestion strings. Suggestions can occasionally contain the names of well-known people, as they appear in Google's suggestions.

**Do I need a proxy?** No. None is used.

**Is it allowed to use this endpoint?** The endpoint is public and needs no login or API key, and `suggestqueries.google.com` publishes no robots.txt. It is still an undocumented endpoint, not an official Google API, and Google's [Terms of Service](https://policies.google.com/terms) apply to how you use the results. Do not use the suggestions to manipulate search results or to generate spam content. The Actor sends requests at a modest pace (one at a time, with a short pause after each), and each request identifies the Actor in the User-Agent (`RondelBot/1.0`). You are responsible for making sure your use fits Google's terms and the laws that apply to you. This is general information, not legal advice.

# Actor input Schema

## `seeds` (type: `array`):

Keywords to expand. Blank entries and duplicates are dropped (seeds are lower-cased).

## `includeBase` (type: `boolean`):

Query the seed itself (Google's top suggestions for the seed).

## `alphabet` (type: `boolean`):

'seed a' … 'seed z' (26 queries per keyword).

## `numbers` (type: `boolean`):

'seed 0' … 'seed 9' (10 queries per keyword).

## `questions` (type: `boolean`):

how, what, why, when, where, which, who, can, is, are, does, will + seed (12 queries).

## `prepositions` (type: `boolean`):

seed + for, with, without, to, near, vs, like, versus, and, or, is, can (12 queries).

## `customModifiers` (type: `array`):

Your own words, e.g. 'best', 'cheap', '2026'. One query each per position.

## `customPosition` (type: `string`):

Put custom modifiers after the keyword, before it, or both.

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

Interface language code, e.g. en, de, ja, zh-TW. Checked before any request: an unknown code stops the run with a clear message, nothing charged.

## `gl` (type: `string`):

Two-letter country code, e.g. us, gb, de, jp, tw. Empty = not set. Checked before any request: an unknown code stops the run with a clear message, nothing charged.

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

0 = expand seeds only. 1–2 = also expand the top suggestions of each keyword with the same modes. Hard cap 2.

## `recursionTopN` (type: `integer`):

How many of a keyword's plain-query suggestions are expanded at the next depth.

## `maxKeywords` (type: `integer`):

Hard limit on seeds + recursive keywords expanded (each one is a billable event if it returns suggestions). Leave empty for the default: 100, or the number of seeds if you enter more than 100. Seeds beyond the limit get a free row with status skipped-max-keywords.

## `dedupAcrossSeeds` (type: `boolean`):

Off: each suggestion appears once per seed. On: once per run.

## `outputLayout` (type: `string`):

Apify bills dataset writes per item, so 'keyword' is much cheaper to run. OUTPUT.csv in the key-value store is always flat (one row per suggestion).

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

Which public suggest format to request. Both returned the same lists in our tests.

## `delayBetweenRequestsMs` (type: `integer`):

Polite pause after every successful request.

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

For 408/429/5xx/network errors only. Exponential backoff, honours Retry-After.

## `baseDelayMs` (type: `integer`):

Doubles on each retry, plus jitter.

## `maxDelayMs` (type: `integer`):

Upper limit on any single wait.

## Actor input object example

```json
{
  "seeds": [
    "coffee grinder"
  ],
  "includeBase": true,
  "alphabet": true,
  "numbers": false,
  "questions": true,
  "prepositions": false,
  "customPosition": "suffix",
  "hl": "en",
  "gl": "us",
  "maxDepth": 0,
  "recursionTopN": 5,
  "dedupAcrossSeeds": false,
  "outputLayout": "keyword",
  "client": "firefox",
  "delayBetweenRequestsMs": 400,
  "maxRetries": 4,
  "baseDelayMs": 3000,
  "maxDelayMs": 60000
}
```

# Actor output Schema

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

No description

## `errors` (type: `string`):

No description

## `datasetConsole` (type: `string`):

No description

## `csv` (type: `string`):

No description

## `runSummary` (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 = {
    "seeds": [
        "coffee grinder"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("raspberry_rondel/google-autocomplete-keywords").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 = { "seeds": ["coffee grinder"] }

# Run the Actor and wait for it to finish
run = client.actor("raspberry_rondel/google-autocomplete-keywords").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 '{
  "seeds": [
    "coffee grinder"
  ]
}' |
apify call raspberry_rondel/google-autocomplete-keywords --silent --output-dataset

```

## MCP server setup

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

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/2FUCJlvQgmyJJbpGp/builds/Z6GGx0NIHbnXhGPiL/openapi.json
