Google Search Autocomplete Scraper by Buyer Intent Filter
Pricing
from $4.99 / 1,000 results
Google Search Autocomplete Scraper by Buyer Intent Filter
Automate the collection of Google autocomplete results for large keyword sets. Build rich keyword datasets with related terms, variations, and search trends. Supports SEO planning, market discovery, and competitive analysis workflows.
Pricing
from $4.99 / 1,000 results
Rating
0.0
(0)
Developer
API Empire
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
0
Monthly active users
4 days ago
Last modified
Categories
Share
Google Autocomplete Scraper — Suggestions, Intent Tags and Counts
Google Autocomplete Scraper pulls live search suggestions from Google's public suggest endpoint and returns three things per seed keyword: the raw autocomplete completions, a search-intent label for every completion, and a per-seed intent scorecard that counts transactional, commercial, informational and navigational keywords. Every run returns typed, normalized JSON — no HTML, no CSS selectors, no parsing step. Turn on one boolean and the same run collapses to a buyer-intent-only keyword list ready for PPC, affiliate and e-commerce campaigns.
What is the Google Autocomplete Buyer-Intent Scraper?
This is a Google autocomplete scraper with a built-in buyer-intent classifier. It queries https://suggestqueries.google.com/complete/search with client=firefox, an hl language code and a gl country code, reads the completion array Google returns, then runs each completion through a deterministic keyword-matching classifier before writing a dataset row. No Google account, no login, no cookies and no API key are involved anywhere in the source — the suggest endpoint is public, and the Actor sends nothing but the query string.
It is a keyword research tool first and an intent segmentation tool second, which is what separates it from a plain suggestion dumper. The classification is a keyword heuristic, not AI and not machine learning: there is no model, no embedding and no external inference call in the code. Every label is reproducible from a fixed list of 95 trigger words you can read below.
- Scrape Google autocomplete completions — the same predictions the search box shows, per seed keyword, per market.
- Tag every completion with a search-intent type —
transactional,commercial,informationalornavigational, plus the exact word that triggered the label. - Score each seed keyword — per-seed counts of every intent bucket and a
hasBuyerIntentflag, so you can rank seeds by commercial demand. - Filter down to buyer-intent keywords only — drop research and brand-navigation noise in the same run.
- Export as JSON, CSV, Excel, XML or HTML from the Apify dataset — proxy escalation, retries and language/country code mapping are handled for you.
What data does the Google Autocomplete Scraper collect?
Each dataset row covers a single expanded query and carries four distinct data types: the autocomplete completions themselves, per-completion intent labels, a per-seed intent scorecard, and the extracted buyer-intent keyword set. All field names below are copied from the row-building block in src/main.py.
| Data Type | Key Fields | JSON Field Names |
|---|---|---|
| Autocomplete completions | The completions Google returned for this query, both as numbered columns and as a clean array, plus how many survived filtering | query, suggestion_01 … suggestion_NN, suggestions, suggestionCount |
| Per-completion intent labels | One intent bucket and one matched trigger word per completion, index-aligned with suggestions | intentTypes, matchedIntentWords |
| Per-seed intent scorecard | How many completions fell into each of the four intent buckets for this seed | transactionalCount, commercialCount, informationalCount, navigationalCount |
| Buyer-intent keyword set | The transactional + commercial subset, its size, and a boolean flag for fast filtering | buyerIntentCount, hasBuyerIntent, buyerIntentSuggestions |
| Run configuration echo | Which filter mode produced this row, so downstream jobs can tell filtered rows from complete ones | buyerIntentOnly |
The numbered suggestion_XX columns are dynamic. The row-builder writes one key per kept completion using a two-digit zero-padded index (suggestion_01, suggestion_02, …), so a seed that returns four completions produces exactly four such keys and nothing more. There is no fixed-width padding and no null filler columns.
Need more keyword and SERP data?
If you are building a full keyword pipeline, API Empire publishes several Actors that pair naturally with this one. The YouTube Search Scraper with Keyword Rank Tracking covers the same seed list on YouTube's index so you can see which money keywords also carry video demand, and the Google News Scraper (Real URL & Source Metadata) shows which of your commercial terms are currently attracting press coverage. For off-page context on the terms you decide to target, the Ahrefs Scraper by Market Category and the Moz Backlink Profile Analyzer cover the authority side. For demand-side research, the Reddit Posts Scraper with Buyer Question Detection applies a similar intent lens to forum threads instead of search suggestions.
Why not build a Google autocomplete scraper yourself?
Google publishes no official, documented public API for the autocomplete suggestion endpoint — the suggestqueries.google.com/complete/search URL this Actor calls is an internal endpoint used by browsers, not a supported product with a versioned contract. The Google Ads API's keyword planning services are a different dataset entirely: they cover planner estimates, not the live search-box predictions, and they require an approved developer token and a linked Ads account. So the realistic comparison is not "official API vs Actor" — it is "your own scraper vs this one."
Three things make the DIY version more expensive than it looks:
Blocking is the default outcome at volume. A bare requests.get loop against the suggest endpoint from a cloud IP will start collecting 403, 429 and 503 responses, and — more annoyingly — empty or non-JSON bodies that look like success to naive code. This Actor treats all four cases as a block, including a body that parses as JSON but does not match the [query, [completions], …] shape Google actually returns. That last check is what most home-grown scrapers skip, and skipping it silently poisons the output with empty rows.
Proxy escalation has to be stateful. The Actor starts with no proxy, escalates to Apify Proxy's GOOGLE_SERP datacenter group on the first block, then to residential, and stays on residential rather than flapping between tiers. On residential it retries a failed query up to three times with increasing backoff before giving up. That is a small state machine you would otherwise write, test and maintain.
The locale mapping is boilerplate you do not want to own. The Actor ships a 77-entry language table mapping human-readable names to ISO 639-1 hl codes and a 205-entry country table mapping names to gl codes, so nobody has to remember that Hebrew is iw on Google or that Chinese is zh-CN. Add the intent word lists, the word-boundary regex compilation, and the parallel-array output contract, and the "quick script" becomes a maintained component.
Build it yourself if you need one seed keyword once. Use this Actor when the keyword list is recurring, multi-market, or feeding something downstream that expects a stable schema.
Why do developers and teams scrape Google autocomplete?
Autocomplete is the cheapest available signal of what people actually type, refreshed continuously by Google and free of the aggregation lag that affects planner tools. The intent layer is what turns that raw signal into something you can act on without hand-sorting.
For PPC managers and paid search teams
Autocomplete is a negative-keyword mine as much as a keyword mine. Run your ad group's seed terms with buyerIntentOnly off and tagIntent on, then split the dataset on intentTypes: everything labelled informational or navigational is a candidate negative keyword, and everything labelled transactional is a candidate exact-match addition. Because matchedIntentWords records the specific trigger that fired, you can justify each classification in a review — "this went to negatives because it matched how to, not because a model guessed." Seeds where hasBuyerIntent is false are usually not worth an ad group at all.
For affiliate and review-site publishers
Commercial-investigation keywords are the entire business model of a review site, and they are exactly what the commercial bucket isolates: best, top, review, vs, versus, compare, alternative, worth it, pros and cons. Feed a product category's seed list, sort the dataset by commercialCount descending, and the top rows are the comparison articles worth writing. Pair that with transactionalCount on the same row to find categories where readers are both comparing and ready to buy — those are the seeds where a comparison post converts rather than just ranking.
For e-commerce and marketplace sellers
Run the same product seeds across several values of country and compare buyerIntentCount per market. A seed returning near me, for sale, in stock and free shipping completions in one market but only how to completions in another tells you where demand is transactional and where it is still educational. Add region-specific money words through customIntentWords — financing, lease, installment — and they fold into the transactional bucket, so local payment language is not misfiled as informational.
For developers building data products
The output contract is flat enough to load directly. query is the join key, suggestions is an array, and intentTypes and matchedIntentWords are index-aligned to it, so a single zip reconstructs (completion, intent, trigger) triples with no parsing. Schedule the Actor on Apify, point a webhook at your warehouse loader, and you have a keyword-intent feed on your own cadence. Because every classification is a keyword match rather than a model output, labels do not drift between runs — the same completion always produces the same label for the same word list.
How to scrape Google autocomplete by buyer intent (step by step)
The Actor runs on the Apify platform. You start it from the Apify Console UI or by calling the Apify API with your Apify API token — there is no separate signup, no vendor-specific API key and no self-hosted mode.
- Open the Actor's page on the Apify Store and click Try for free (or Start if it is already in your account). Everything below happens on the Apify platform.
- Fill in
queries— the only required input. One seed keyword per line in the 🌱 Seed keywords field. The schema prefillsbluetooth speaker,running shoesandcrm software, so you can run it untouched to see the output shape. - Choose your market and intent settings. Pick
language(77 options, defaultEnglish) andcountry(69 options in the dropdown, defaultUnited States). LeavetagIntenton to get labels and counts. TurnbuyerIntentOnlyon only when you want the informational and navigational completions dropped from the row entirely. - Decide on expansion before you press Start.
usePrefixanduseSuffixare both off by default. Each one multiplies the request count — and therefore the billed row count — by 26 per seed. Turning both on takes one seed to 53 queries. - Start the run and export. Results land in the run's default dataset. Download as JSON, CSV, Excel, XML or HTML from the Storage tab, or read the dataset programmatically with the Apify API client.
What to do when Google changes its suggest response
The Actor is maintained, and the output contract is the part designed to stay still: query, the numbered suggestion_XX keys, suggestions, intentTypes, matchedIntentWords and the count fields keep their names and types across updates. If Google alters the suggest response shape or tightens its blocking, the fix happens inside the fetch and block-detection layer, not in your integration.
⬇️ Input
The Actor accepts nine parameters. queries is the only required one; everything else has a documented default in .actor/actor.json. The table below reproduces the schema exactly — same names, same types, same defaults, nothing added and nothing omitted.
| Parameter | Required | Type | Description | Example Value |
|---|---|---|---|---|
queries | Yes | array of string (stringList editor) | Seed terms to mine, one per line. Each seed is fetched from Google's autocomplete endpoint and every returned completion is classified. Prefilled with ["bluetooth speaker", "running shoes", "crm software"]. No default beyond that prefill. A run with an empty list logs No queries provided and stops without pushing any rows. A bare string is accepted through the API and wrapped into a single-item list. | ["bluetooth speaker", "crm software"] |
buyerIntentOnly | No | boolean | Default false. When true, completions classified informational or navigational are dropped from the row before the suggestion_XX keys are written, leaving only transactional + commercial money keywords. When false, every completion is returned and tagged. | true |
tagIntent | No | boolean | Default true. Adds the per-completion label arrays (intentTypes, matchedIntentWords), the suggestions array, the per-seed counts (suggestionCount, transactionalCount, commercialCount, informationalCount, navigationalCount, buyerIntentCount), hasBuyerIntent, buyerIntentSuggestions and the buyerIntentOnly echo. Set to false for a bare keyword list of query + suggestion_XX only. | true |
customIntentWords | No | array of string (stringList editor) | No default — empty unless you fill it. Additional trigger words appended to the transactional bucket only, on top of the 41 built-in transactional words. Each entry is lowercased and trimmed; blank entries are dropped and entries already in the built-in transactional list are skipped. A bare string is accepted and wrapped into a single-item list. | ["financing", "lease", "installment"] |
language | No | string (enum, 77 values) | Default "English". The hl language Google returns completions in. Enum: English, Spanish, French, German, Italian, Portuguese, Russian, Japanese, Korean, Chinese, Arabic, Hindi, Bengali, Turkish, Vietnamese, Polish, Dutch, Swedish, Danish, Norwegian, Finnish, Czech, Hungarian, Romanian, Greek, Hebrew, Thai, Indonesian, Malay, Filipino, Ukrainian, Bulgarian, Croatian, Slovenian, Slovak, Lithuanian, Latvian, Estonian, Icelandic, Irish, Welsh, Basque, Catalan, Galician, Afrikaans, Swahili, Zulu, Xhosa, Amharic, Somali, Yoruba, Hausa, Igbo, Persian, Urdu, Tamil, Telugu, Kannada, Malayalam, Marathi, Gujarati, Punjabi, Nepali, Sinhala, Burmese, Khmer, Lao, Mongolian, Tibetan, Georgian, Armenian, Azerbaijani, Kazakh, Uzbek, Turkmen, Kyrgyz, Tajik. Every enum value has a code in the internal table; any value outside it silently falls back to en. | "German" |
country | No | string (enum, 69 values) | Default "United States". The gl country used for location-specific completions — different markets surface different buyer terms. Enum: United States, United Kingdom, Canada, Australia, Germany, France, Spain, Italy, Brazil, Mexico, Argentina, Chile, Colombia, Peru, Russia, Ukraine, Poland, Netherlands, Belgium, Switzerland, Austria, Sweden, Norway, Denmark, Finland, Portugal, Ireland, Czech Republic, Hungary, Slovakia, Slovenia, Croatia, Greece, Bulgaria, Romania, Turkey, China, Japan, South Korea, India, Pakistan, Bangladesh, Indonesia, Malaysia, Thailand, Philippines, Vietnam, Singapore, New Zealand, South Africa, Egypt, Nigeria, Kenya, Morocco, Tunisia, Algeria, Saudi Arabia, United Arab Emirates, Israel, Jordan, Lebanon, Iran, Iraq, Kuwait, Qatar, Oman, Bahrain, Yemen, Syria. The internal name-to-code table covers 205 territories, so names outside the dropdown still resolve when passed through the API; unrecognised names silently fall back to us. | "Germany" |
usePrefix | No | boolean | Default false. Prepends each letter a–z before the seed (a bluetooth speaker, b bluetooth speaker, …) in addition to the bare seed. Multiplies the request count by 26 per seed. Shown under the ⚙️ Advanced expansion & proxy section of the input form. | false |
useSuffix | No | boolean | Default false. Appends each letter a–z after the seed (bluetooth speaker a, bluetooth speaker b, …) in addition to the bare seed. Multiplies the request count by 26 per seed. Both flags together yield 53 queries per seed. | true |
proxyConfiguration | No | object (proxy editor) | No default value; the field is prefilled with {"useApifyProxy": true}. Standard Apify proxy object. Read the note below — this input is only consulted after the Actor has escalated to its residential tier. | {"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]} |
How proxyConfiguration is actually used. The Actor's proxy manager starts at tier none and ignores your proxy object entirely on the first requests. On the first detected block it escalates to tier datacenter, which is hardcoded to Apify Proxy's GOOGLE_SERP group and also ignores your object. Only when it escalates a second time, to tier residential, is your proxyConfiguration read — and even then only if it contains a truthy useApifyProxy; otherwise the Actor substitutes {"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}. In practice, setting a custom proxy group has no effect on an unblocked run and cannot be used to force proxying from the first request.
Example JSON input
{"queries": ["bluetooth speaker", "running shoes", "crm software"],"buyerIntentOnly": false,"tagIntent": true,"customIntentWords": ["financing", "lease", "installment"],"language": "English","country": "United States","usePrefix": false,"useSuffix": false,"proxyConfiguration": {"useApifyProxy": true}}
The most common input mistake is enabling usePrefix and useSuffix on a long seed list without doing the arithmetic. Twenty seeds with both flags on is 20 × 53 = 1,060 queries and 1,060 charged rows, processed one after another. Start with expansion off, confirm the intent labels look right for your niche, then expand.
The second most common mistake is turning tagIntent off and then wondering why the dataset table looks empty. The default dataset view is built around suggestionCount, buyerIntentCount, hasBuyerIntent, transactionalCount and commercialCount — all of which only exist when tagIntent is true.
⬆️ Output
Every run writes one dataset row per expanded query. The output is typed, normalized JSON with stable key names — strings for the completions, integers for the counts, a boolean for hasBuyerIntent, and arrays for suggestions, intentTypes, matchedIntentWords and buyerIntentSuggestions. From the Apify dataset you can export the same rows as JSON, JSON Lines, CSV, Excel, XML, HTML or RSS.
The row shape changes in two documented ways depending on your input, so all three variants are shown below rather than merged into one misleading example.
Scraped completions with full intent tagging (default)
This is what you get with the defaults — tagIntent: true, buyerIntentOnly: false. Every completion Google returned is present, and every one carries a label.
{"query": "bluetooth speaker","suggestion_01": "bluetooth speaker with lights","suggestion_02": "bluetooth speaker jbl","suggestion_03": "bluetooth speaker best buy","suggestion_04": "bluetooth speaker price","suggestion_05": "bluetooth speaker reviews","suggestion_06": "bluetooth speaker near me","suggestion_07": "how to connect bluetooth speaker","suggestion_08": "bluetooth speaker waterproof","suggestion_09": "best bluetooth speaker 2026","suggestion_10": "bluetooth speaker app","suggestions": ["bluetooth speaker with lights", "bluetooth speaker jbl","bluetooth speaker best buy", "bluetooth speaker price","bluetooth speaker reviews", "bluetooth speaker near me","how to connect bluetooth speaker", "bluetooth speaker waterproof","best bluetooth speaker 2026", "bluetooth speaker app"],"suggestionCount": 10,"intentTypes": ["informational", "informational", "transactional", "transactional","commercial", "transactional", "informational", "informational","commercial", "navigational"],"matchedIntentWords": [null, null, "buy", "price", "reviews","near me", "how to", null, "best", "app"],"transactionalCount": 3,"commercialCount": 2,"informationalCount": 4,"navigationalCount": 1,"buyerIntentCount": 5,"hasBuyerIntent": true,"buyerIntentSuggestions": ["bluetooth speaker best buy", "bluetooth speaker price","bluetooth speaker reviews", "bluetooth speaker near me","best bluetooth speaker 2026"],"buyerIntentOnly": false}
intentTypes and matchedIntentWords are index-aligned with suggestions, so suggestions[i], intentTypes[i] and matchedIntentWords[i] always describe the same completion. matchedIntentWords[i] is null when no trigger word matched — that completion was assigned informational as the fallback label, not because a research word was found. Note bluetooth speaker best buy: it matched buy from the transactional bucket, which is scanned before the commercial bucket that contains best.
Scraped buyer-intent keywords only
With buyerIntentOnly: true, the filter runs before the row is built. The suggestion_XX keys are renumbered over the surviving completions, and every count is computed over the filtered set — which is why informationalCount and navigationalCount are always 0 here, and suggestionCount always equals buyerIntentCount.
{"query": "bluetooth speaker","suggestion_01": "bluetooth speaker best buy","suggestion_02": "bluetooth speaker price","suggestion_03": "bluetooth speaker reviews","suggestion_04": "bluetooth speaker near me","suggestion_05": "best bluetooth speaker 2026","suggestions": ["bluetooth speaker best buy", "bluetooth speaker price","bluetooth speaker reviews", "bluetooth speaker near me","best bluetooth speaker 2026"],"suggestionCount": 5,"intentTypes": ["transactional", "transactional", "commercial", "transactional", "commercial"],"matchedIntentWords": ["buy", "price", "reviews", "near me", "best"],"transactionalCount": 3,"commercialCount": 2,"informationalCount": 0,"navigationalCount": 0,"buyerIntentCount": 5,"hasBuyerIntent": true,"buyerIntentSuggestions": ["bluetooth speaker best buy", "bluetooth speaker price","bluetooth speaker reviews", "bluetooth speaker near me","best bluetooth speaker 2026"],"buyerIntentOnly": true}
If a seed produces no buyer-intent completions at all, the row still exists — it contains query, no suggestion_XX keys, suggestions: [], suggestionCount: 0, buyerIntentCount: 0 and hasBuyerIntent: false. Filter those out downstream with hasBuyerIntent == true.
Scraped completions without tagging
With tagIntent: false, the classifier still runs internally (it has to, for buyerIntentOnly to work) but nothing about it is written. The row collapses to the base autocomplete contract — query plus numbered completions, and nothing else:
{"query": "crm software","suggestion_01": "crm software free","suggestion_02": "crm software for small business","suggestion_03": "crm software pricing","suggestion_04": "crm software comparison","suggestion_05": "crm software examples","suggestion_06": "crm software list","suggestion_07": "crm software demo","suggestion_08": "crm software companies"}
This is the mode to use when you are feeding a tool that only wants a flat keyword list, or when you want output that is shape-compatible with a plain Google autocomplete scraper.
🛒 How the buyer-intent classification works
The intent labels are produced by whole-word regular-expression matching against four fixed keyword lists. There is no model, no training data, no scoring network and no external inference call — the classifier is roughly forty lines of Python, and you can predict its output by hand. This is a keyword heuristic. It is not AI, and nothing in this Actor should be read as claiming otherwise.
The four buckets and their exact trigger words
The lists below are reproduced verbatim from the intent word table in src/main.py. There are 95 built-in triggers in total.
| Bucket | Trigger words (exact list) | Count |
|---|---|---|
| transactional | buy, purchase, order, price, prices, pricing, cost, costs, cheap, cheapest, affordable, deal, deals, discount, discounts, coupon, coupons, promo, promo code, sale, for sale, on sale, shop, shopping, near me, in stock, quote, subscription, subscribe, book, booking, rent, rental, hire, delivery, free shipping, bundle, wholesale, bulk, trial, demo | 41 |
| commercial | best, top, review, reviews, rating, ratings, compare, comparison, vs, versus, alternative, alternatives, which, recommended, recommendation, worth it, pros and cons, brands | 18 |
| navigational | login, log in, sign in, sign up, website, official, app, download, account, portal, dashboard, customer service, phone number, contact, careers, jobs | 16 |
| informational | how, how to, what, what is, why, when, where, who, guide, tutorial, tutorials, tips, ideas, examples, meaning, definition, explained, step by step, learn, diy | 20 |
Buyer intent is defined in the source as exactly two of these buckets: transactional and commercial. Navigational and informational completions are never counted as buyer intent, and buyerIntentOnly removes them from the row.
How a completion is matched
- Every trigger word is compiled into a case-insensitive regular expression wrapped in word boundaries —
\bbuy\b,\bnear me\b, and so on. The word boundary is whybuymatcheswhere to buy speakersbut notbuyerorbuying. - Within each bucket, the word list is deduplicated and sorted longest string first, then alphabetically for equal lengths. That is the intra-bucket tie-break: in
how to connect bluetooth speaker, the informational bucket testsstep by stepandhow tobefore it testshow, somatchedIntentWordsrecordshow torather thanhow. - Buckets are tested in a fixed precedence order: transactional → commercial → navigational → informational. The first bucket with any match wins and scanning stops immediately. That is the cross-bucket tie-break, and it is ordered by commercial value on purpose.
- If no trigger word in any bucket matches, the completion is labelled
informationalwithmatchedIntentWordsset tonull.
The precedence rule has consequences worth knowing before you trust the labels:
bluetooth speaker best buy→ transactional (buy), not commercial, because the transactional bucket is scanned first even thoughbestalso matches.how to buy a used car→ transactional (buy), not informational: transactional outranks informational regardless of where the words appear.book a hotelandbest book for beginnersboth match transactionalbook. The lists are built for products and services, so ambiguous words likebook,top,app,demo,quoteandcontactwill occasionally misfile a completion in a niche where those words are ordinary nouns.- Position in the string is irrelevant, and the fallback label is
informational— so a completion with no signal at all inflatesinformationalCountrather than landing in an "unclassified" bucket. UsematchedIntentWords[i] == nullto tell a genuine informational match from a fallback.
There is no numeric intent score
The Actor emits counts, not a score. buyerIntentCount is an integer equal to transactionalCount + commercialCount, and it ranges from 0 to suggestionCount for that row. hasBuyerIntent is simply buyerIntentCount > 0. There is no 0–100 confidence value, no probability, and no weighting between buckets — each completion contributes exactly 1 to exactly one bucket. If you want a ratio, compute buyerIntentCount / suggestionCount yourself.
Extending the word lists
customIntentWords appends to the transactional bucket only. Entries are lowercased and stripped, blank entries are dropped, and any entry already present in the built-in transactional list is skipped so the list stays deduplicated. Because appended words go through the same longest-first sort, a multi-word entry like payment plan is tested before shorter transactional triggers and will be the recorded matchedIntentWords value when it fires. There is no way to add words to the commercial, navigational or informational buckets, and no way to remove a built-in word.
💵 Pricing, charged events and empty rows
This Actor bills on Apify's pay-per-event model with a single charged event: row_result. The event fires once per dataset push, and there is exactly one push per expanded query — so your billed event count equals your query count:
billed rows = number of seeds × (1 + (26 if usePrefix else 0) + (26 if useSuffix else 0))
Three seeds with both expansion flags off is 3 rows. Three seeds with both flags on is 159 rows.
Rows are charged even when Google returned nothing. There is no uncharged error path in the source: if a query exhausts its residential retries and comes back with an empty completion list, the Actor still builds a row and still pushes it as a row_result event. The same applies to a seed whose completions are all removed by buyerIntentOnly. Budget for the full expanded query count, not for the count of rows that turn out to be useful.
To exclude those rows downstream, filter on the count field rather than on row existence:
- With
tagIntent: true— keep rows wheresuggestionCount > 0, orhasBuyerIntent == trueif you only want seeds that produced money keywords. - With
tagIntent: false— keep rows where thesuggestion_01key is present, since an empty result produces a row containing onlyquery.
A run that starts with an empty queries list is the one case that costs nothing: the Actor logs No queries provided and returns before the request loop, pushing zero rows.
How does this Actor compare to other Google autocomplete scrapers?
The Apify Store has several Google autocomplete Actors. The rows below describe observable, checkable differences; competitor entries are taken from each Actor's own live listing, checked on the Apify Store 2026-07-25 — not measured here.
| Feature | Google Autocomplete Scraper (Buyer-Intent Filter) | Generic Google autocomplete scraper |
|---|---|---|
| Search-intent classification | Four-bucket label per completion (intentTypes) plus the matched trigger word (matchedIntentWords) | Not offered. None of the three listings compared advertise intent labelling — lofomachines/…cheaper-faster-reliable and riisager/google-search-suggest-autocomplete both document position, relevance_score, word_count, char_count; scraper-mind/google-search-autocomplete-api documents query + suggestion_01… only |
| Commercial filtering | buyerIntentOnly drops informational and navigational completions inside the run | Filtering is left to the user after export |
| Per-seed aggregation | Six aggregate fields per row (suggestionCount, four bucket counts, buyerIntentCount) plus the hasBuyerIntent boolean | Typically one row per completion with no seed-level rollup |
| Custom money words | customIntentWords extends the transactional bucket at run time | lofomachines and riisager both expose commonSuffixes, which changes which queries are sent, not how the results are classified |
| Row shape | Wide row per seed: numbered suggestion_XX columns plus arrays, so one CSV line per keyword group | lofomachines and riisager both document a long-format row per keyword (seed + keyword + metadata) |
| Expansion controls | Two booleans, usePrefix and useSuffix, a–z only | riisager advertises expansionMode with none/alphabet/alphabet_extended/numbers/full, plus includeQuestions and maxLetters — a broader expansion surface than this Actor offers |
| Pricing model | Pay-per-event, one row_result per query processed | scraper-mind/google-search-autocomplete-api's listing advertises a flat $5/month after a 1-day trial, checked 2026-07-25; lofomachines and riisager are both listed as pay-per-event |
Two honest notes on that table. First, riisager's expansion surface is genuinely broader than this Actor's — if question-prefix expansion and numeric suffixes matter more to you than intent labelling, that is the better fit. Second, if you are building an AI agent or a RAG pipeline, the output-format row is the decision-maker: parsing HTML or re-deriving intent inside an agent loop is a reliability failure mode, not a feature, and a pre-labelled intentTypes array removes an entire classification step from your prompt chain.
How many results can you scrape with this Actor?
The Actor itself imposes no result cap. There is no maxItems, no maxResults and no pagination ceiling anywhere in the input schema or the source. Whatever completion array Google returns for a query is stored in full — the row-builder writes one suggestion_XX key for every completion that survives filtering, however many that is.
The practical limits come from three places, all visible in the code:
Google's own response size. The suggest endpoint returns a prediction list per query; the Actor reads element [1] of the JSON response and does not truncate it. To go deeper than one seed's completions, expand the query set rather than asking for more results per query.
Query expansion. usePrefix and useSuffix are the only volume levers. Each adds 26 derived queries per seed on top of the bare seed, so a seed with both enabled produces 53 queries and 53 rows. Expansion is a straight multiplication, and completions are not deduplicated across queries — the same long-tail can appear under several letters.
Throughput. Queries are processed strictly one at a time — the Actor awaits each fetch before starting the next, logging Processing query i/total as it goes. Each request carries a 30-second total timeout and a 10-second connect timeout, and a blocked query on the residential tier is retried up to three times with backoff. A large expanded run is therefore long rather than parallel; set your run timeout accordingly. No measured throughput figure is published for this Actor, so none is quoted here.
🔌 Integrate the Google Autocomplete Scraper into your workflow
This Actor works with any language or tool that can send an HTTP request to the Apify API. Runs can be started from the Apify Console, from the Apify API, on a schedule, or from a webhook — all with your standard Apify API token.
REST API integration
The example below starts a run, waits for it to finish, and reads the resulting dataset with the official Apify Python client. Replace <YOUR_USERNAME> with the account the Actor is published under and <YOUR_APIFY_API_TOKEN> with your Apify API token.
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_API_TOKEN>")run = client.actor("<YOUR_USERNAME>/google-search-autocomplete-scraper-by-buyer-intent-filter").call(run_input={"queries": ["bluetooth speaker", "crm software"],"buyerIntentOnly": False,"tagIntent": True,"customIntentWords": ["financing", "lease", "installment"],"language": "English","country": "United States",})for row in client.dataset(run["defaultDatasetId"]).iterate_items():if not row.get("hasBuyerIntent"):continuetriples = zip(row["suggestions"], row["intentTypes"], row["matchedIntentWords"])for keyword, intent, trigger in triples:print(f"{row['query']:<20} {intent:<14} {trigger or '-':<12} {keyword}")
Works in Python, Node.js, Go, Ruby, PHP, Java and cURL — the same run can be started with a plain POST to the Apify API's run endpoint and read back from the dataset items endpoint.
Automation platforms (n8n, Make, LangChain)
n8n ships an official Apify node. Use the Apify → Run an Actor operation, point it at this Actor's ID, and pass the run input as JSON; the node's output items are the dataset rows, so a downstream Filter node on hasBuyerIntent gives you a buyer-intent-only branch with no code.
Make (formerly Integromat) has an Apify app with a Run an Actor module and a Watch Actor Runs trigger. A typical build: Schedule → Run an Actor with a fixed queries list → Iterator over dataset items → Google Sheets Add a Row, mapping query, buyerIntentCount and buyerIntentSuggestions into your keyword tracker.
LangChain integrates with Apify through its Apify dataset loader, which turns dataset items into documents. Because intentTypes is already a labelled array, attach the intent bucket as document metadata and let an agent retrieve only transactional keywords — no classification prompt inside the chain.
Is it legal to scrape Google autocomplete suggestions?
Scraping publicly available search suggestions is generally lawful in most jurisdictions, and this Actor returns only publicly available data. Autocomplete completions are aggregate, anonymised query predictions served to any unauthenticated browser — the Actor sends no credentials, sets no cookies, and reads nothing that requires a Google account.
Because the output contains no personal data — just keyword strings and their intent labels, with no names, user identifiers or profile records — the GDPR and CCPA obligations that attach to data subjects do not normally apply here. The relevant frameworks are contractual and database-rights ones: Google's terms of service, and how you use the resulting keyword lists commercially. A completion can incidentally contain a public figure's or a brand's name if that is what people are searching for, so review raw completions before republishing at scale.
Consult legal counsel for commercial use cases involving bulk data collection, and check your obligations before redistributing scraped keyword sets as a product.
❓ Frequently asked questions
Does the Google Autocomplete Scraper work without a Google account?
Yes. The source contains no authentication of any kind — no login flow, no cookie jar, no API key parameter and no OAuth. It sends a single unauthenticated GET to suggestqueries.google.com/complete/search carrying the query, client=firefox, and your hl/gl codes. The only credential involved anywhere is your Apify API token, and that is for talking to Apify, not to Google.
How fresh are the autocomplete suggestions?
They are fetched live on every run. There is no cache layer, no stored snapshot and no database in the Actor — each query hits Google's suggest endpoint at the moment the run reaches it, and the response is classified and pushed immediately. Re-running the same seed list an hour later can legitimately return different completions, because Google's predictions shift with real search behaviour.
What happens when a seed keyword returns no completions?
The Actor writes a row anyway. If Google returns an empty prediction list, or if the query stayed blocked through all three residential retries, the fetch returns an empty list and the row is built with query and no suggestion_XX keys. With tagIntent on, that row carries suggestions: [], suggestionCount: 0, all four bucket counts at 0, buyerIntentCount: 0 and hasBuyerIntent: false. That row is still charged as a row_result event, so filter on suggestionCount > 0 when you process the dataset. The run itself does not abort — it logs the query and moves to the next one.
Can I get search volume, CPC or keyword difficulty?
No, and the Actor deliberately does not fabricate them. Google's autocomplete response contains predicted query strings only — it carries no volume, no cost-per-click and no competition metric, so there is nothing in the payload to extract. Any tool that attaches those numbers to autocomplete data is joining them from a separate planner source. Use buyerIntentCount and the bucket counts as a qualitative demand signal, not as a volume proxy.
Can I scrape private, personalised or logged-in Google suggestions?
No. The Actor only returns the generic, unauthenticated predictions Google serves to an anonymous browser for a given language and country. Personalised suggestions — the ones influenced by your own search history, your Google account, or a signed-in session — are not accessible without credentials and are never returned. The hl and gl parameters are the only personalisation levers available, and they select a market, not a person.
How do I access and run this Actor?
Open the Actor's page on the Apify Store and run it from the Apify Console, or start it programmatically through the Apify API with your Apify API token. Billing is pay-per-event with a single row_result event charged per query processed; the exact per-event price is shown in the Pricing section of the Actor's Store listing, which is the authoritative source for it. There is no separate account to create, no vendor API key, and no self-hosted deployment path.
Does it work for AI agent workflows and LLM pipelines, and is the output LLM-ready?
Yes to both. The Actor is callable as an HTTP endpoint by any agent framework that can issue a POST to the Apify API and read a dataset — LangChain, LlamaIndex, CrewAI, a custom tool-calling loop, or an n8n agent node. Every response is typed, normalized JSON with stable field names: no HTML, no selectors, no parsing step between the Actor and an LLM context window, and suggestions, intentTypes and matchedIntentWords are index-aligned arrays alongside plain-integer counts. A row can be passed into a context window as-is, indexed into a vector store, or routed through an agent tool. The intentTypes array matters most here: classification has already happened deterministically, so your agent filters an array instead of spending tokens judging intent, and the result is identical on every rerun. For the leanest possible payload, set tagIntent to false and you get query plus numbered completions and nothing else.
How does the Actor handle rate limiting and blocking?
With a three-tier proxy escalation plus residential retries. It starts unproxied, and treats a response as blocked if the status is 403, 429 or 503, if the body is empty, if the body is not valid JSON, or if the JSON does not match Google's [query, [completions], …] shape — that last check is what catches soft blocks returning a 200. On the first block it escalates to Apify Proxy's GOOGLE_SERP datacenter group; on the next it escalates to residential and stays there for the remainder of the run. Once on residential, a blocked query is retried up to three times with increasing backoff before the Actor gives up on that query and returns an empty completion list. There is no headless browser and no CAPTCHA solver — the suggest endpoint does not serve interactive challenges.
How does it compare to the other Google autocomplete scrapers on Apify?
The differentiator is the intent layer. Checked on the Apify Store on 2026-07-25, none of the three most comparable listings — scraper-mind/google-search-autocomplete-api, lofomachines/google-search-autocomplete-cheaper-faster-reliable and riisager/google-search-suggest-autocomplete — advertise search-intent classification or a buyer-intent filter; their documented output fields are completions plus positional metadata such as position, relevance_score, word_count and char_count. Conversely, riisager's listing advertises expansion modes this Actor does not have (numbers, includeQuestions, a configurable maxLetters) and lofomachines's listing advertises a configurable delayBetweenRequests. Pick on the axis you need: expansion breadth, or intent segmentation.
Can I use it without managing proxies?
Yes. Leave proxyConfiguration at its default and the Actor handles the network side itself: it begins with no proxy, escalates to Apify Proxy's GOOGLE_SERP datacenter group when Google starts blocking, then to residential, retrying on the way. You never configure a proxy list, rotate an IP pool, or manage a session manually. Note that supplying your own proxyConfiguration only takes effect once the Actor reaches the residential tier — it cannot be used to force proxying from the first request.
What happens if Google changes its suggest response or blocks the scraper?
The Actor is maintained, and the output schema is the stable contract on your side: query, suggestion_XX, suggestions, suggestionCount, intentTypes, matchedIntentWords, the four bucket counts, buyerIntentCount, hasBuyerIntent, buyerIntentSuggestions and buyerIntentOnly keep their names and types across updates. Fixes for endpoint or blocking changes are made inside the fetch and block-detection layer, so integrations built on these field names keep working without changes on your end.
Your feedback
Found a bug, hit a completion that got the wrong intent label, or need a trigger word added to a bucket? We want to know — misclassifications are the most useful bug reports for this Actor, because the fix is a concrete change to a keyword list. Open an issue from the Issues tab on the Actor's Apify Store listing with the seed keyword, the country and language you used, and the completion that was labelled wrongly. Feature requests for new output fields or additional intent buckets are welcome through the same channel.