How to Collect Google Autocomplete Suggestions Using an API

16 min read

Calender 01
How to Collect Google Autocomplete Suggestions Using an API

Typing a seed keyword into Google and writing down the predictions works for five keywords. It stops working at 500, and it gets worse when you need the same list for New York, London and Paris, each in its own language.

Google autocomplete suggestions show how real people phrase their searches, which makes them a good source of keyword ideas. Collecting them by hand is slow, hard to repeat and full of copy-paste errors. An API makes it repeatable: send a list of seed keywords and get back a clean dataset with each suggestion, the seed it came from and the market it belongs to.

This guide covers the whole workflow with working Python code: one request, a bulk run over hundreds of seeds, location-specific collection, data cleanup, and turning the results into a keyword research shortlist.

New to the API? If you want to know how Google’s autocomplete works before writing code, start with How the Google Autocomplete API Works. This guide is the hands-on follow-up.

What Are Google Autocomplete Suggestions?

Google autocomplete suggestions are the predicted searches that appear as someone types in Google. They reflect real searches and change with the user’s language and location. Typing “coffee” can produce different predictions in Texas and in Paris.

Autocomplete shows you what people search for, not how many people search for it. A phrase appears because Google considers it a relevant prediction. It does not come with monthly search volume, and its position in the list is not a ranking metric. Use predictions to find keyword ideas, then check them with a keyword metrics tool.

Why Collect Google Autocomplete Suggestions at Scale?

Collecting predictions for one keyword is research. Collecting them for hundreds is a data workflow that can answer bigger questions:

  • Long-tail discovery. Five hundred seeds can return thousands of candidate phrases, many of them longer, specific variations that are easy to miss with manual research.
  • Question mining. Phrases that start with “how,” “why,” “can” or “is” map directly to FAQs and content briefs.
  • Market comparison. Each location shows how people in that market phrase their searches. This is useful for agencies with clients in several countries.
  • Repeatability. The same script can run next month with the same settings, so you can compare how predictions change.

What You Need Before You Start

  • A SERPHouse API key. Copy it from your dashboard and store it in an environment variable rather than in your code. See Getting Started for authentication details.
  • Python 3.9+ with requests installed (pip install requests pandas; pandas is only used for the cleanup step).
  • A seed-keyword list. A CSV file named seeds.csv with a seed_keyword column and one phrase per row.
  • Target languages and locations. Use codes from the Languages List and exact strings from the Locations List. A location string that doesn’t match the list may fail or return results for the wrong place.
  • Somewhere to store results. A CSV file is enough to start. Larger teams can load the same rows into a database or spreadsheet.

export SERPHOUSE_API_KEY=”your_api_key_here”

How to Collect Google Autocomplete Suggestions Using an API

The SERPHouse Google Autocomplete API returns Google’s predictions for a phrase as structured JSON.

  • Endpoint: POST https://api.serphouse.com/google-autocomplete-api
  • Authentication: Your API key as a Bearer token in the Authorization header
  • Cost: 5 credits per request, and failed requests are not charged
ParameterRequiredDescription
qYesThe seed phrase to get suggestions for
langNoLanguage code, such as en or fr
locNoLocation string from the Locations List, such as Abernathy,Texas,United States
clientNoAutocomplete client: chrome (default), chrome-omni, home_page, safari, firefox or youtube

The parameters go inside a data object in the request body. Suggestions come back under results.results.suggestions, and each one has four fields:

  • value: The suggested search phrase
  • relevance: Google’s relevance score for the prediction
  • type: The suggestion type, such as QUERY
  • link: The Google search URL for that phrase

Full details are in the Google Autocomplete API documentation.

Save the following as serphouse_client.py. It holds the two functions the rest of this guide reuses: one to get suggestions, and one to look up exact location strings.

import os
import requests

API_KEY = os.environ["SERPHOUSE_API_KEY"]
BASE_URL = "https://api.serphouse.com"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}


class RetryableError(Exception):
    """A temporary failure that is worth retrying."""


def get_suggestions(q, lang="en", loc="Abernathy,Texas,United States", client="chrome"):
    """Return Google autocomplete suggestions for one seed phrase."""
    payload = {"data": {"q": q, "lang": lang, "loc": loc, "client": client}}
    response = requests.post(
        f"{BASE_URL}/google-autocomplete-api",
        headers=HEADERS,
        json=payload,
        timeout=30,
    )
    response.raise_for_status()
    data = response.json()

    # A 200 response can still carry {"status": "error", "msg": "Please try again"}
    if data.get("status") != "success":
        raise RetryableError(data.get("msg") or "Autocomplete request failed")

    return data["results"]["results"].get("suggestions", [])


def find_locations(query, engine="google"):
    """Search the Locations List for exact `loc` strings."""
    response = requests.get(
        f"{BASE_URL}/location/search",
        headers=HEADERS,
        params={"q": query, "type": engine},
        timeout=30,
    )
    response.raise_for_status()
    return response.json()["results"]


if __name__ == "__main__":
    for suggestion in get_suggestions("coffee"):
        print(suggestion["relevance"], suggestion["value"])

Run it with python serphouse_client.py. For the seed “coffee” in Abernathy, Texas, the API returns predictions like these:

1250 coffee near me

950 coffee shops near me

601 coffee table

600 coffee shop

560 coffee bean

Two details in this code matter later:

  • A 200 response isn’t always a success. The API can return HTTP 200 with {“status”: “error”, “msg”: “Please try again”}. The function raises a RetryableError for this case so the bulk script can retry it.
  • client=”youtube” returns YouTube search predictions. This is useful if you plan video content.

How to Find the Right Location Strings

Location strings must match the Locations List exactly, so look them up instead of typing them. find_locations() searches the list for you:

from serphouse_client import find_locations

for match in find_locations(“London”)[:10]:

    print(match[“type”], “|”, match[“country_code”], “|”, match[“loc”])

Each result includes a loc value (the exact string to send), a type (such as City, State or Congressional District) and a country_code. Choose the row that matches the market you want and copy its loc value into your list of markets. For language codes, call GET https://api.serphouse.com/language/list/google or check the Languages List.

How to Collect Suggestions for Multiple Keywords in Bulk

The Autocomplete API takes one seed per request, so bulk collection means sending many requests in a controlled way. The script below handles the parts that usually go wrong at scale:

  • Rate limiting. Standard SERPHouse plans allow 60 requests per minute. The script spaces requests out to 50 per minute across 4 parallel workers.
  • Smart retries. It retries rate limits (429), server errors, timeouts and “Please try again” responses with increasing delays. It doesn’t retry 400 (bad parameters), and it stops the whole run on 401 (bad API key) or 402 (out of credits).
  • Resume support. It skips seed-and-market combinations that are already in the output file, so rerunning after a failure doesn’t pay for the same requests twice.
  • Clean output. It writes a CSV header once and stores the seed, location, language and timestamp on every row.

Save it as collect_autocomplete.py in the same folder as serphouse_client.py:

import csv
import os
import threading
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from datetime import datetime, timezone

import requests

from serphouse_client import RetryableError, get_suggestions

SEEDS_FILE = "seeds.csv"
OUTPUT_FILE = "suggestions.csv"
FIELDS = ["seed", "suggestion", "relevance", "type", "loc", "lang", "collected_at"]

# One (loc, lang) pair per market. Copy loc strings exactly from find_locations().
MARKETS = [
    ("Abernathy,Texas,United States", "en"),
    # ("<loc string for London>", "en"),
    # ("<loc string for Paris>", "fr"),
]

MAX_WORKERS = 4             # parallel requests
REQUESTS_PER_MINUTE = 50    # stay under the 60 req/min plan limit
MAX_ATTEMPTS = 4
CREDITS_PER_REQUEST = 5
RETRYABLE_STATUS = {429, 500, 502, 503, 504}


class RateLimiter:
    """Spaces out request start times across all worker threads."""

    def __init__(self, per_minute):
        self.interval = 60.0 / per_minute
        self.lock = threading.Lock()
        self.next_slot = time.monotonic()

    def wait(self):
        with self.lock:
            now = time.monotonic()
            slot = max(now, self.next_slot)
            self.next_slot = slot + self.interval
        time.sleep(max(0.0, slot - now))


limiter = RateLimiter(REQUESTS_PER_MINUTE)


def fetch_with_retry(seed, loc, lang):
    for attempt in range(1, MAX_ATTEMPTS + 1):
        limiter.wait()
        try:
            return get_suggestions(seed, lang=lang, loc=loc)
        except requests.HTTPError as error:
            status = error.response.status_code if error.response is not None else None
            if status not in RETRYABLE_STATUS:
                raise  # 400, 401, 402...: retrying won't help
            last_error = error
        except (RetryableError, requests.Timeout, requests.ConnectionError) as error:
            last_error = error
        if attempt < MAX_ATTEMPTS:
            time.sleep(2 ** attempt)  # 2s, 4s, 8s
    raise last_error


def load_seeds(path):
    with open(path, newline="", encoding="utf-8") as file:
        seeds = (row["seed_keyword"].strip() for row in csv.DictReader(file))
        return list(dict.fromkeys(seed for seed in seeds if seed))


def load_completed(path):
    """(seed, loc, lang) combinations already in the output file."""
    if not os.path.exists(path):
        return set()
    with open(path, newline="", encoding="utf-8") as file:
        return {(row["seed"], row["loc"], row["lang"]) for row in csv.DictReader(file)}


def main():
    seeds = load_seeds(SEEDS_FILE)
    completed = load_completed(OUTPUT_FILE)
    jobs = [
        (seed, loc, lang)
        for loc, lang in MARKETS
        for seed in seeds
        if (seed, loc, lang) not in completed
    ]
    print(f"{len(jobs)} requests to send (up to {len(jobs) * CREDITS_PER_REQUEST:,} credits)")

    write_header = not os.path.exists(OUTPUT_FILE)
    failed = []

    with open(OUTPUT_FILE, "a", newline="", encoding="utf-8") as file, \
            ThreadPoolExecutor(max_workers=MAX_WORKERS) as pool:
        writer = csv.DictWriter(file, fieldnames=FIELDS)
        if write_header:
            writer.writeheader()

        futures = {pool.submit(fetch_with_retry, *job): job for job in jobs}
        for future in as_completed(futures):
            seed, loc, lang = futures[future]
            try:
                suggestions = future.result()
            except requests.HTTPError as error:
                if error.response is not None and error.response.status_code in (401, 402):
                    print(f"Stopping: HTTP {error.response.status_code} (check API key or credits)")
                    for pending in futures:
                        pending.cancel()
                    break
                failed.append((seed, loc, lang, str(error)))
                continue
            except Exception as error:
                failed.append((seed, loc, lang, str(error)))
                continue

            collected_at = datetime.now(timezone.utc).isoformat(timespec="seconds")
            for suggestion in suggestions:
                writer.writerow({
                    "seed": seed,
                    "suggestion": suggestion["value"],
                    "relevance": suggestion["relevance"],
                    "type": suggestion.get("type", ""),
                    "loc": loc,
                    "lang": lang,
                    "collected_at": collected_at,
                })
            file.flush()

    for seed, loc, lang, error in failed:
        print(f"FAILED: {seed!r} [{loc}, {lang}]: {error}")
    print(f"Done. {len(failed)} failed. Run the script again to retry them.")


if __name__ == "__main__":
    main()

Before a large run, the script prints how many requests it will send and the maximum credit cost. Test it with 10 seeds and one market, check suggestions.csv, then add the rest.

Note: Seeds that return no suggestions don’t write a row, so a rerun requests them again. That costs 5 credits per empty seed. If your list has many niche seeds, remove the ones that return nothing.

How to Collect Location-Specific Autocomplete Suggestions

Autocomplete predictions change by market, so local and international research needs one run per location and language. With the script above, that means adding one entry to MARKETS for each market:

MARKETS = [
    ("Abernathy,Texas,United States", "en"),
    ("<loc string for London from find_locations>", "en"),
    ("<loc string for Paris from find_locations>", "fr"),
]

Two rules prevent most problems:

  1. Look up every location string. Use find_locations() or the downloadable CSV on the Locations List page, and copy the loc value exactly.
  2. Keep the market on every row. The script stores loc and lang next to each phrase, so “seo services near me” from London never gets mixed up with the same phrase from Texas.

Match the language to the market. Use fr for Paris, not en, unless you specifically want English-language predictions there.

How to Clean and Organize Autocomplete Data

Raw output from many overlapping seeds contains duplicates. “local seo tips” and “Local SEO tips ” are the same phrase, and related seeds often return the same prediction. This pandas script normalizes the text, removes duplicates within each market and flags question phrases:

import pandas as pd

QUESTION_WORDS = {
    "how", "what", "why", "when", "where", "who", "which",
    "can", "is", "are", "does", "do", "should"
}

df = pd.read_csv("suggestions.csv").dropna(subset=["suggestion"])

# 1. Normalize: lowercase, trim, collapse repeated spaces
df["phrase"] = (
    df["suggestion"].str.lower().str.strip().str.replace(r"\s+", " ", regex=True)
)

# 2. Deduplicate within each market, keeping the highest relevance score
df = (
    df.sort_values("relevance", ascending=False)
      .drop_duplicates(subset=["phrase", "loc", "lang"])
      .reset_index(drop=True)
)

# 3. Flag question phrases (English question words)
df["is_question"] = df["phrase"].str.split().str[0].isin(QUESTION_WORDS)

df.to_csv("suggestions_clean.csv", index=False)
print(df.groupby(["loc", "lang"]).size().rename("unique_phrases"))
print(f"{df['is_question'].sum()} question phrases flagged")

What each step does:

  • Normalize. Lowercases, trims and collapses repeated spaces so near-identical phrases match.
  • Deduplicate within each market. A phrase counts as a duplicate only when the text, location and language all match. The copy with the highest relevance score is kept.
  • Flag questions. Phrases that start with a question word are ready-made FAQ and how-to topics. The word list is English, so add equivalents (for example, “comment” and “pourquoi” for French) for other languages.
  • Keep the source metadata. The seed column shows which seeds produce the most useful ideas, which helps you choose seeds for the next round.

Decide on your matching rule before you deduplicate and write it down. Some teams also merge singular and plural forms. That’s fine, as long as you apply the same rule on every run.

How to Use Autocomplete Suggestions for Keyword Research

Here is how a content team researching local SEO might turn Google autocomplete suggestions into a content plan:

  1. Start with business-relevant seeds, such as “local seo,” “google business profile,” “local keyword research,” “local rank tracking” and “local seo report.”
  2. Collect predictions for each target market with the bulk script.
  3. Clean the results with the cleanup script.
  4. Group phrases by topic and intent. Sort them into themes such as Google Business Profile, local rankings, local keyword research and reporting. Question phrases in the Google Business Profile theme can become an FAQ or how-to guide. Phrases like “local seo report template” suggest a downloadable resource. Read through anything that doesn’t fit a theme, because new themes often show up there.
  5. Check demand and competition before prioritizing. Autocomplete tells you a phrase exists. Search volume, keyword difficulty and the current SERP tell you whether it’s worth targeting. Run your shortlist through a keyword metrics tool, and check the live results for each candidate with the Google SERP API before you assign it to a writer.

Best Practices for Large-Scale Collection

  • Budget credits before you run. Each request costs 5 credits. For example, 500 seeds × 4 markets = 2,000 requests = 10,000 credits, which is about $0.62 on the Regular plan. The free plan’s 4,000 credits cover 800 autocomplete requests. See pricing for current rates.
  • Stay under your rate limit. Standard plans allow 60 requests per minute. Keep some headroom (the script uses 50), and contact SERPHouse if you need a higher limit on a custom plan.
  • Retry only errors that can recover. Rate limits, server errors, timeouts and “Please try again” responses deserve a retry with backoff. Bad parameters, bad keys and empty credit balances don’t.
  • Cache results. Predictions for the same seed and market change slowly. Reuse recent results instead of collecting them again for every report.
  • Log everything. Keep the list of failed seeds and the run totals. A log tells you whether a gap in the data is a real absence or a failed request.
  • Start small. Test 10 seeds in one market, check the output, then scale up.

Common Mistakes to Avoid

  • Treating predictions as search volume. A high relevance score or the top spot in the list does not mean high monthly searches. Always check demand separately.
  • Mixing markets. Without location and language on each row, US and UK phrases blend into one list, and the localized research becomes useless.
  • Typing location strings by hand. A string that doesn’t exactly match the Locations List can fail or return results for the wrong place. Look it up.
  • Treating every HTTP 200 as a success. Check the status field. A 200 response can still say “Please try again.”
  • Skipping deduplication. Overlapping seeds produce many repeats. Without a matching rule, the shortlist looks bigger than it is.
  • Sending requests without cost or rate control. Unlimited parallel requests plus reruns without resume support is the fastest way to waste credits and hit 429 errors.

Start Collecting Autocomplete Data

Collecting Google autocomplete suggestions at scale takes three pieces: one reliable request function, a bulk runner that respects rate limits and can resume, and a cleanup step that keeps each market separate. With the scripts in this guide, a list of 500 seeds becomes a clean, deduplicated keyword dataset for every market you target, and you can rerun it next month with the same settings.

Try the Google Autocomplete API free. The free plan includes 4,000 credits, which is 800 autocomplete requests, and you aren’t charged for failed requests.

FAQ

Can I collect Google autocomplete suggestions in bulk?

Yes. Send one API request per seed keyword and combine the results into one dataset. The bulk script in this guide handles rate limits, retries and resuming. How much you can collect depends on your plan’s credits and its 60 requests-per-minute limit.

Does Google Autocomplete provide search volume?

No. Predictions show phrases people search for, not how often they search for them. The relevance score is Google’s prediction ranking, not a volume metric. Use a separate keyword metrics source to estimate demand.

Can I collect location-specific suggestions?

Yes. The SERPHouse Autocomplete API accepts loc and lang parameters, and results can differ between markets. Use exact values from the Locations List and Languages List.

How much does autocomplete collection cost with SERPHouse?

Each autocomplete request costs 5 credits, and failed requests are free. Multiply your number of seeds by your number of markets, then by 5, to estimate total credits. On the Regular plan that works out to about $0.31 per 1,000 requests. See the pricing page for current plan details.

Can I get YouTube autocomplete suggestions?

Yes. Set client to youtube to get YouTube search predictions instead of Google web predictions. This is useful when you plan video content.

top 100 serp
Latest Posts