Google Keyword Search Volume API: 7 Countries + Global avatar

Google Keyword Search Volume API: 7 Countries + Global

Pricing

from $2.00 / 1,000 keyword results

Go to Apify Store
Google Keyword Search Volume API: 7 Countries + Global

Google Keyword Search Volume API: 7 Countries + Global

Bulk Google keyword search volume API: monthly volume, CPC, competition and 12-month trend for up to 10,000 keywords a run. Global, US, UK, Canada, Australia, New Zealand, India and South Africa only. Keywords with no data return null and are charged; invalid and failed ones are free.

Pricing

from $2.00 / 1,000 keyword results

Rating

0.0

(0)

Developer

Quarrywise

Quarrywise

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 hours ago

Last modified

Share

Keyword search volume API for bulk keyword lists: paste up to 10,000 keywords and get monthly search volume, cost per click (CPC) and advertiser competition for each one, in one table you can download as JSON, CSV or Excel or read through the API. The numbers are Google Keyword Planner data from the Keywords Everywhere API, used with the provider's permission; not affiliated with Keywords Everywhere or Google.

Markets: Global, United States, United Kingdom, Canada, Australia, New Zealand, India and South Africa only. Other countries are not available from our data source, and this Actor does not estimate them. There is no language setting.

What you get for every keyword

  • Search volume: the source's own 12-month average of monthly searches in the market you choose, rounded the way Google Keyword Planner rounds (for example 301,000 rather than 291,500). That is what we measured in our live test on 2026-10-26: every volume matched the average of the source's 12 monthly values, snapped to Keyword Planner's volume steps. The source does not document it. Spikes in those monthly values can raise it (see "Known data issue" below).
  • CPC: the cost per click advertisers pay, converted into the currency you choose (about 130 currencies). In our live test the same keyword cost USD 0.47 with usd and GBP 0.35 with gbp: a real conversion, not a relabelled dollar amount. The list is the source's own and still holds ten retired currencies, marked "retired" (ANG, BYR, EEK, HRK, MRO, SKK, SLL, STD, VEF and ZMK); whether the source still converts them at a current rate is not known (we checked conversion live for USD, GBP and AUD only), so use EUR instead of HRK, EEK and SKK.
  • Competition: the advertiser competition index from 0 (low) to 1 (high), as reported by the source. It is about paid search, not SEO ranking difficulty. A 0 may mean the source has no competition data for the keyword rather than low competition (in our live test a keyword with 480 searches a month came back with competition 0 and no bid estimate).
  • Monthly values, on request: the source's 12 monthly values for this keyword, labelled by the source, oldest first, with ISO months (2026-09). Off by default (includeTrend), same price. Read "Known data issue" below before you use them: they looked a month or more older than their labels in our check.
  • An honest "no data": a keyword the source has no data on gets status: "no_data" and empty (null) numbers, never a made-up 0. See "No data is not zero" below.
  • Clean input handling: pasted blocks are split into lines; case, extra spaces, invisible characters and match-type symbols ("...", [...], +word) are removed; duplicates are looked up and charged once.

Typical uses: keyword research and content planning, sizing a list of topics before writing, checking CPC before a paid campaign, enriching a spreadsheet or a database of keywords, and giving an AI agent or an automation real search demand numbers.

How to use it

  1. Paste your keywords, one per line (up to 10,000 lines per run).
  2. Pick the market (country), the CPC currency and the data source.
  3. Run it. Each keyword becomes one row. The Overview tab shows volume, CPC and competition. The "Status and errors" tab shows every row with its status and, for invalid and failed rows (which are free), the reason. Dataset views cannot filter rows, and the API returns every row, so to list only the problems, download the dataset as CSV or Excel and filter the status column for invalid and failed, or filter status in your own code after reading the items.

From code or an automation, call the Apify API, for example POST https://api.apify.com/v2/acts/quarrywise~keyword-search-volume-api/run-sync-get-dataset-items with your Apify token in the Authorization: Bearer header and the input JSON as the body. The call waits at most 300 seconds; for lists above about 5,000 keywords start the run asynchronously and read the dataset when it finishes. Apify's apps for Make, Zapier and n8n, and Apify's MCP server for AI agents (https://mcp.apify.com?tools=quarrywise/keyword-search-volume-api), work the same way.

Input

FieldWhat it doesDefault
keywordsKeywords, one per line, 1 to 10,000 lines per run (pasted blocks count line by line). Duplicates (ignoring case and spacing) are looked up and charged oncerequired
countryglobal, us, uk, ca, au, nz, in or za. global sends no country filter and returns the source's global dataus
currencyCurrency for CPC only, as a lowercase code such as usd, gbp or eur. Search volume is not affectedusd
dataSourcegkp: Google Keyword Planner only. cli: Google Keyword Planner plus clickstream data. Same price either waygkp
includeTrendAdds the source's 12 monthly values for this keyword, labelled by the source. For rough direction only, not timing (see "Known data issue" below). Same pricefalse

There is no language setting: the source has none, and volume is per market.

Example:

{
"keywords": ["keyword research", "content marketing", "email marketing"],
"country": "us",
"currency": "usd",
"dataSource": "gkp",
"includeTrend": false
}

Output fields

One dataset row per unique keyword: the invalid rows come first, then every other keyword (ok, no_data and failed rows) in the order you entered them (the first occurrence counts when a keyword appears twice). To match rows to your own list, join on input_keyword (as you entered it) or keyword (as looked up) rather than on row position. Keywords that were not looked up because the run reached your maximum charge get no row. After a restart a keyword can appear twice (see "Aborts, restarts and safety stops" below): keep its ok or no_data row. Every row has the same fields.

FieldMeaning
keywordThe keyword as looked up: lowercase, spaces collapsed, match-type symbols removed
input_keywordThe keyword as you entered it (the first spelling when duplicates were merged)
statusok, no_data, invalid or failed
search_volumeThe source's own 12-month average of monthly searches, rounded as Keyword Planner rounds; spikes in the source's monthly values can raise it (see "Known data issue"); null on no_data, invalid and failed rows (an ok row always has it)
cpcCost per click in cpc_currency, two decimals as the source sends them; null when there is no data, when the source sent 0.00 (no bid estimate, see below), or when the value could not be read or trusted; never 0
cpc_currencyThe currency code you chose, for example USD; null when cpc is null
competitionAdvertiser competition index as reported by the source, 0 to 1; 0 may mean the source has no competition data for the keyword, not low competition; null when there is no data or the value could not be read
trendThe source's 12 monthly values for this keyword, labelled by the source: [{"month": "2026-09", "search_volume": 480}, ...], oldest first; for rough direction only, not timing (see "Known data issue"); null when not requested (the default) or no data
countryThe market, or global
data_sourcegkp or cli
error_reason, error_messageWhy an invalid or failed keyword has no data; null otherwise
retrieved_atWhen the row was produced (ISO 8601, UTC)

The source returns every keyword exactly as it was sent and in the same order (checked in our live test); the Actor still matches each answer to its keyword by the keyword itself, and a keyword it cannot match safely gets a free not_returned row instead of someone else's numbers.

Example rows, built from the source's answers in our live test on 2026-10-26 (country us, data source gkp, currency usd, includeTrend: true so the first row shows the source's monthly values; with the default false its trend is null):

{
"keyword": "running shoes",
"input_keyword": "Running Shoes",
"status": "ok",
"search_volume": 301000,
"cpc": 0.47,
"cpc_currency": "USD",
"competition": 1,
"trend": [
{ "month": "2025-10", "search_volume": 550000 },
{ "month": "2025-11", "search_volume": 368000 },
"... 10 more months, oldest first, up to 2026-09 ..."
],
"country": "us",
"data_source": "gkp",
"error_reason": null,
"error_message": null,
"retrieved_at": "2026-10-26T17:51:49.000Z"
}
{
"keyword": "quokka sanctuary entrance tickets",
"input_keyword": "quokka sanctuary entrance tickets",
"status": "no_data",
"search_volume": null,
"cpc": null,
"cpc_currency": null,
"competition": null,
"trend": null,
"country": "us",
"data_source": "gkp",
"error_reason": null,
"error_message": null,
"retrieved_at": "2026-10-26T17:51:49.000Z"
}

A run summary (keyword counts, charged rows, warnings and the settings used) is saved in the key-value store record OUTPUT, not in the dataset. A run that is not stopped early also says on the run page what it saved, for example

Done: 3 keyword rows saved (3 charged). Details in the OUTPUT record.

No data is not zero

The source answers a keyword it has no data on with a volume of 0, a CPC of 0.00, a competition of 0 and an empty trend, without a "not found" flag (seen in our live test: the keyword still costs the source one credit). Showing that as 0 searches would be misleading, so this Actor reads it as status: "no_data" and leaves the numbers empty (null). That reading is our interpretation of an answer with no volume and no monthly searches.

  • no_data: a volume of 0 where the trend is empty or no month is above 0 (every month 0 or without a value), with a CPC or competition value present as in the source's no-data answer. All numbers are null. A bare volume of 0 with neither is a free failed row (unexpected_response), not no_data.
  • A volume of 0 with at least one month above 0 in the trend is a measured zero (the 12-month average rounds to 0): status: "ok", search_volume: 0.
  • A volume above 0 with an empty trend is ok with trend: [].
  • A missing volume is never shown as 0, and a row without a volume is never charged, not even as no_data: when the source answers a keyword without a volume (not seen live), whatever its trend holds, the keyword gets a free failed row (unexpected_response). We do not work out a volume from the trend ourselves, because the source's rounding is not documented. A month the source sent without a value has search_volume: null in the trend.
  • On ok rows the source sends a CPC of 0.00 when it has no bid estimate for the keyword (seen live for a keyword with 70 searches a month and a competition of 0.02). That is not a price of 0, so this Actor outputs cpc: null and cpc_currency: null for it (an average over your rows is not pulled down), and the run summary counts those rows as cpc_zero_as_null.
  • When the source sends CPC, competition or the trend in a format we cannot read, or reports the CPC with another symbol than the one of the currency you chose, that value is null, the row stays ok, and the run summary says how many rows were affected. That symbol check only works for a currency with a symbol of its own: the source writes nine currencies as a bare $ (ARS, AUD, CLP, COP, KYD, MOP, MXN, NZD and USD), so for those it cannot tell them apart. In our live test the source did convert: running shoes in Australia came back at 0.24 in AUD and 0.17 in USD.

no_data rows are charged like ok rows: the source bills us for every keyword it answers, including keywords without data, and "no data" is a real answer about that keyword.

Known data issue: source data age (checked 2026-10-28)

The source labels its 12 monthly values with the last 12 months (on 2026-10-28: October 2025 to September 2026), but in our check the values looked older than their labels, by an amount that differs per keyword and per market:

  • United States and Global: about 1 month late. Seasonal peaks fall in the month after the event: christmas gifts peaks in January, halloween costumes in November,
    valentines day gifts
    in March and black friday deals in December. For 7 US keywords we compared with Google Ads data from another provider, every monthly value equalled that data for the month before.
  • Canada, Australia and the United Kingdom: often 2 to 3 months late, for some keywords more. snow blower in Canada peaks at June and July 2026 (165,000 each), against 8,100 for October to December 2025: a winter keyword peaking in summer, so far more than 3 months off.
    mothers day gifts
    peaks in July to August in Canada and Australia (Mother's Day is in May there) and in June in the UK (Mothering Sunday was in March); valentines day gifts peaks in April in Canada. For 2 UK keywords compared with that other data, the values were 2 and 3 months older than their labels (a third UK keyword matched no single offset). Some keywords there look only about 1 month late: halloween costumes in Canada peaks in November, and christmas gifts in January in Australia and in December and January (tied) in the UK.
  • Shared spikes. Unrelated commercial keywords carry identical spikes from about April 2026: in the US, crm software, project management software and black friday deals all show 550,000 (June), 246,000 (July), 201,000 (August) and 201,000 (September); in the Global data, four software keywords all show 823,000 for June 2026.

What it means for you:

  • Use trend for rough direction only (for example a steady, rising or seasonal keyword), not for timing: do not read the month of a peak from it. That is why it is off by default.
  • search_volume is the source's own 12-month average, so such spikes can raise it. Global
    email marketing software
    has a search_volume of 201,000, while its values for October 2025 to March 2026 range from 8,100 to 22,200.
  • The cli data source returned the same values for the keywords we checked.
  • This Actor passes the source's numbers through unchanged: it only converts month names to ISO months and sorts them oldest first (a comparison of the raw answers with our rows found 0 differences). Because the offset differs per keyword, we do not try to correct it.

Pricing

Pay per result: USD 2.00 per 1,000 keyword rows (USD 0.002 per keyword), on every Apify plan, plus Apify's small start fee per run.

  • Charged: ok and no_data rows (keywords the source answered, including "no data").
  • Free: duplicates (merged before lookup), invalid keywords (never sent), and failed lookups (for example when the source does not answer).
  • Your maximum charge per run is respected: before every batch the Actor checks how many keywords your remaining maximum charge can pay for and looks up only those. When it is used up the run ends (it still shows as succeeded) with a status message saying how many keywords got no row, the remaining keywords are neither looked up nor charged, and the run summary (OUTPUT) shows status: "limit-reached" and keywords_not_processed_budget. The lowest maximum charge you can set for this Actor is USD 0.05, which pays for 24 keywords after Apify's start fee.
  • Every Apify plan, the same limits. A keyword cap for Apify's free plan (100 keywords a run) is built but switched off in this version, until we have checked how Apify reports paid plans to a run; free-plan runs are not capped. The run log names the plan it detected, for information only (Plan: ...). If we switch the cap on, the changelog will say so first.

Cost examples, when every keyword is unique, valid and answered (each one a charged row):

RunCharged keyword rowsCost
The prefilled example (3 keywords, us)3USD 0.006
1,000 keywords1,000USD 2.00
10,000 keywords (the maximum per run)10,000USD 20.00

The costs are for the keyword rows only: Apify's small start fee per run comes on top. Duplicates, invalid keywords and failed lookups are free, so they make a run cheaper, never dearer. Set your maximum charge per run above the cost, since the start fee comes off it first: at exactly USD 20.00 a 10,000-keyword run stops at least one keyword short.

Rows that are free: invalid and failed keywords

statuserror_reasonWhen
invalidemptyNothing is left after removing spaces, invisible characters and match-type symbols
invalidtoo_longLonger than 80 characters (Google Ads keyword limit)
invalidtoo_many_wordsMore than 10 words (Google Ads keyword limit)
invalidno_letters_or_digitsNo letter or digit at all
invalidrejected_by_sourceThe source rejected this keyword as invalid
failedrejected_in_batchThe source rejected a request containing this keyword when the run had reached its limit of 30 rejected requests, so it stopped narrowing down which keyword caused it; try it again in a shorter list
failednot_returnedThe source's answer did not include this keyword, or we could not match it safely (for example an echo that fits two of your keywords)
failedunexpected_responseThe source's answer for this keyword had an unexpected format, or no volume
failedsource_errorThe source did not answer (timeout, server error or rate limit), or the run stopped early for a safety reason (see "Aborts, restarts and safety stops" below); error_message says which
failedservice_unavailableThe keyword data service is temporarily unavailable for this Actor

Invalid keywords are filtered out before any lookup: they would come back without data anyway. When the keyword data service is temporarily unavailable for this Actor, the run ends early with a message saying how many keywords were not looked up; those are not charged, so you can simply run them again later. When the source rejects the request settings themselves (the whole list and three single keywords from it), the run stops with a message that names the country, currency and data source it used, so you can check them.

Aborts, restarts and safety stops

  • Abort. If you abort a run gracefully (the API's gracefully=true option), the Actor sends no new lookups, waits up to 10 seconds for the lookup already on its way so its rows are written too, keeps every row written (charged when it is ok or no_data) and writes a short run summary. An abort that is not graceful (the API default) stops the run at once: rows already written are kept and charged, the lookup on its way gets no row and is not charged, and no run summary is written. Either way, keywords not looked up get no row and are not charged. Rows answered for later keywords while the run is narrowing down a rejected keyword are not written either and not charged (the run summary says so).
  • Restarts. If Apify moves or restarts a run (a migration, a reboot or a crash), the restarted run waits about 20 to 25 seconds until the platform's count of charged rows has settled, then continues after the last row written, so no keyword is charged twice. A keyword whose row was written just before a crash can get a second row: join on keyword and keep its ok or no_data row. A free invalid or failed row can also appear twice after a restart; the copies are identical, keep either.
  • When the lookups stop instead. A crash or kill before the run has charged its first row (with 20 or more keywords left to look up), a restart the run cannot verify (its saved place RESUME_POSITION is missing, changed or out of date, or two restarts came at once), a charged count that does not settle within two minutes, a saved place the run could not write, or a set of rows whose write or charge failed: the run then charges nothing more for the rows concerned, gives the remaining keywords free failed rows, and its status message says why. A run metamorphed into this Actor from another Actor looks nothing up: start this Actor directly. Known limit: if you resurrect a run that ended before its last keyword (for example aborted or timed out) and that was restarted before it ended (a reboot, a migration or a metamorph), the resurrected run cannot verify its saved place when Apify kept the restart counts from before the end (as it did in our checks), so it looks nothing up and gives the keywords left free failed rows; start a new run for those. A run that Apify moved before it had saved anything (no rows, nothing charged) waits about 60 seconds, then starts from the beginning. Please do not edit, delete or put back an older copy of RESUME_POSITION while a run may still be restarted: an older copy put back by hand can make a restart charge some of your keywords a second time, past your maximum charge, if Apify's count of charged rows lags by more than about 25 seconds; a deleted copy can do the same after Apify moves the run, if both that count and the run's dataset lag by more than about 60 seconds. We measured lags of about 5 to 6 seconds.
  • Safety stops. A run starts small: its first batches hold 20, 20, 40 and 80 keywords before reaching 100. It stops looking up keywords, with free rows for the rest, after two failed batches in a row, after 30 rejected requests, when more keywords come back without a usable answer (or fail in a way that may have used credits) than the larger of 20 and 5% of the keywords sent, or when 20 have done so before any row was charged, or after 200 keywords in all came back unusable. A request that goes unanswered (a timeout or a network error) before the first charge also ends the lookups, because whether it used credits is not confirmed; a server error that the source answers, and that the balance shows was not billed, does not. The run summary counts such keywords as unpaid_lookups.

Data source, privacy and limits

  • Source: Keywords Everywhere API, used with the provider's permission; not affiliated with Keywords Everywhere or Google. The figures are Google Keyword Planner data (with cli, blended with clickstream data).
  • Your keywords: they are sent to that provider for lookup and are not stored by us after the run. There is no cache across runs; each run looks its keywords up fresh. Your keywords are returned to you exactly as you entered them (input_keyword), so the Actor does not filter them; please do not put personal data in a keyword list.
  • Personal data: the source returns search statistics only, no personal data.
  • Per run: up to 10,000 keyword lines. Longer lists: split them over several runs.
  • Speed: keywords are looked up up to 100 at a time (the first batches of a run hold 20, 20, 40 and 80), and each lookup follows a free balance read: one request to the provider at a time, at most one per second in all. In our live test one lookup request (1 to 3 keywords) was answered in about 0.2 seconds. A full 100-keyword request has not been timed yet, so 10,000 keywords (about 103 lookups and as many balance reads, so at least about 3.5 minutes) taking about 4 to 6 minutes is still an estimate.
  • Markets: the seven countries above plus Global, with no language setting. Volume is counted per market. The source does answer keywords in other languages (in our live test the French keyword chaussures de running had 70 searches a month in the United States and 10 in Canada), but whether every language spoken in a market is counted is not confirmed, so we do not claim it.

Provider

Provided by Quarrywise, a trade name of Picazzo Research & Development, Zinkstraat 24, Box C4687, 4823 AD Breda, the Netherlands. KvK 42060545, VAT NL005464235B85. Contact: hello@quarrywise.com or the Issues tab.