Google Keyword Search Volume & Seasonality avatar

Google Keyword Search Volume & Seasonality

Pricing

from $0.23 / 1,000 keywords

Go to Apify Store
Google Keyword Search Volume & Seasonality

Google Keyword Search Volume & Seasonality

Get Google keyword search volume by month: 48 months of Google Ads data per keyword with CPC, competition, bids, seasonal peaks and a rank for the months you plan for. Keyword ideas, website keywords, any country or city. Keywords without data are free. JSON, CSV or API.

Pricing

from $0.23 / 1,000 keywords

Rating

0.0

(0)

Developer

Automation Craft

Automation Craft

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

7 hours ago

Last modified

Share

Google Keyword Search Volume & Seasonality

Google keyword search volume for your keyword lists, keyword ideas and websites: up to 48 months of monthly searches per keyword from Google Ads (Keyword Planner data), with CPC, competition and top of page bids, plus what the numbers mean for your calendar: the seasonal peak months, the trend, and a rank of your keywords for each of the next 1 to 3 months you plan for. Any Google Ads location: countries, regions, cantons, states and cities. No Google Ads account and no API key needed.

Built for online sellers, Shopify and marketplace merchants, SEO and PPC teams and automation builders who decide which products, listings and campaigns to prepare before the season starts.

What makes it different

  • 48 months, labelled. Every month is written YYYY-MM with its year and month number, oldest first, and a month Google did not report is listed in missingMonths instead of being left out.
  • Seasonality computed for you. A seasonal index per calendar month, the peak and low months, how strong the season is, and in how many years the peak month really was the top month.
  • A plan for the months ahead. For each planned month every keyword row carries the historical average for that calendar month, last year's figure and the change against the latest month, and one plan row per month ranks all keywords of the run. The historical evidence and the planning assumption are two separate texts. Past search demand is history, not a forecast.
  • Fair billing. A keyword without Google data is a free row, and so is everything delivered again from your 30 day memory. A lookup that finds no keyword with data is free.
  • CSV for sheets. MONTHLY_SEARCHES.csv has one line per keyword per month (long format) and PLANNER.csv the ranks per planned month, ready for Google Sheets or Excel.

Quick start

  1. Paste your keywords (one per line), or seed keywords with What to look up set to keyword ideas.
  2. Pick one or more Locations: a country name, a two letter code (CH), Worldwide, or a region or city the way Google Ads writes it (Zurich,Switzerland).
  3. Click Start. A queued lookup is usually ready in 10 to 60 seconds. Export the dataset as JSON, CSV or Excel, or open the two CSV files in the run's key-value store.

Search volume for a keyword list in Switzerland:

{
"keywords": ["winterjacke", "regenjacke", "badehose", "veste d'hiver", "maillot de bain"],
"locations": ["Switzerland"]
}

Keyword ideas for a seed, German, at most 200 ideas:

{
"mode": "ideas",
"keywords": ["winterjacke"],
"locations": ["Switzerland"],
"language": "de",
"maxKeywords": 200
}

The keywords for a website, ranked by search volume:

{
"mode": "website",
"websites": ["example.com"],
"locations": ["United States"],
"sortBy": "search_volume",
"maxKeywords": 500
}

What you get

One keyword row per keyword and location, one plan row per planned month, free status rows for anything that was refused or skipped, and a summary row at the end.

FieldWhat it holds
keywordThe keyword as Google Ads keys it (lower case)
dataStatusok (Google has data, the row is charged unless it came from the memory) or no_data (free)
searchVolumeGoogle Ads average monthly searches (last 12 months)
monthlySearchesOldest first: month (YYYY-MM), year, monthNumber, searches
missingMonths, monthsWithDataMonths of the window Google did not report
cpc, competition, competitionIndex, lowTopOfPageBid, highTopOfPageBid, currencyGoogle Ads cost per click, competition and top of page bids (USD)
emptyFieldsThe metric fields Google left empty on a row with data
seasonalityseasonalIndex and monthlyAverages per calendar month, peakMonth, peakMonths, lowMonth, lowMonths, strength, label (steady, seasonal, strongly seasonal), peakConsistency, cyclesCovered
trendyoyChangePct, qoqChangePct, momChangePct, last3MonthsVsYearBeforePct, last12MonthsTotal, previous12MonthsTotal, direction (growing, stable, declining), latestMonth
planningPer planned month: historicalAverage, seasonalIndex, lastYearSearches, changeFromLatestPct, historicalEvidence, planningAssumption
locationCode, locationName, locationType, countryCode, language, searchPartnersThe targeting of the row
dateFrom, dateTo, dataAsOf, retrievedAt, source, sourceEndpoint, lookupIdThe month window, the date Google last updated its keyword data, when the row was read and where it came from
closeVariants, spellCorrectedToKeywords of the same lookup that Google gave the same figures (close variants), and Google's spelling
discoveredBy, seedKeywords, isSeed, extraWords, extraWordsNote, conceptGroups, discoveryFor ideas and website keywords: the source, the seeds it matches, the words it adds to them, Google's concept groups, and for ranked keywords the ranking position, page, title and estimated traffic
inputPositionsWhere the keyword stood in your list
fromMemory, memoryDeliveredOnDelivered again from your 30 day memory (free)
insights (add-on)keywordDifficulty (0 to 100), searchIntent, otherIntents, serpFeatures, googleResultsCount, coreKeyword, categories, longHistory (about 8 years of months), insightsUpdatedAt
aiSearchVolume, aiMonthlySearches (add-on)How often the keyword is asked in AI tools, 12 months
bing (add-on)Bing searchVolume, cpc, competition (a number from 0 to 1, where Google Ads gives a level and an index), monthlySearches (24 months)

Words of demand, not product facts. In ideas, extraWords lists what a keyword adds to its seed (damen, wasserdicht, lang). They describe what people search for. Use one in a product title only when the product really has it: this Actor never says what a product is.

Measured fill

FieldHead keywords: 86 rows of the platform matrix (US, CH, CA, GB; 2026-10-18)Keyword ideas, long tail: 8,180 ideas of 3 Swiss seeds (2026-10-18)
searchVolume and 48 monthlySearches86 of 86 (100 percent), every month of the window filled8,163 of 8,180 (99.8 percent); 17 ideas without figures are left out
cpc86 of 86 (100 percent)5,181 of 8,180 (63 percent)
competition, competitionIndex86 of 86 (100 percent)6,135 of 8,180 (75 percent)
lowTopOfPageBid, highTopOfPageBid83 of 86 (96.5 percent)3,208 of 8,180 (39 percent)
seasonality with a seasonal index86 of 86 (67 strongly seasonal, 15 seasonal, 4 steady)computed for every idea with 12 or more months
insights (add-on)intent on the rows the Labs database holds and keyword difficulty on most of them (of 50 Swiss test keywords: 38 held, with intent on 38 and difficulty on 35; long tail and nonsense ones left out)

Sources: the platform runs of platform-results/matrix-t1.json and the feasibility spike (FEASIBILITY.md). Long tail keywords carry fewer bids and CPC figures because Google Ads has no auction data for them.

Seasonality and planning, and what they are not

The seasonal index of a month is that calendar month's average searches divided by the average month, over the whole 12 month cycles of the window (48 months by default gives 4 cycles). A month at 1.25 or more is a peak month. peakConsistency says in how many full calendar years the peak month was really that year's top month. The planned months are, by default, the three months after the month the run starts; planFrom and planningMonths change them. Every planned month carries two texts: historicalEvidence (what the history shows) and planningAssumption (that the month will follow that history). The data is past search demand: it is not a forecast of demand or sales.

How much does it cost to get Google keyword search volume?

You pay per result with Apify's pay per event pricing. Prices in USD:

EventWhen it is chargedFREEBRONZESILVERGOLD
KeywordOne keyword row with Google data0.000320.000290.000270.00023
LookupOne Google Ads or Bing request (up to 1,000 keywords, or one set of ideas) that delivered a charged keyword0.360.330.300.26
Fast lookupFast speed only: one paid request that was sent live0.210.190.170.15
Keyword insightAdd-on, one charged row with insights0.000840.000770.00070.0006
Discovered keywordOne charged row found through related searches, suggestions, autocomplete or ranked keywords0.000840.000770.00070.0006
AI search volumeAdd-on, one charged row with an AI search volume0.000840.000770.00070.0006
Actor startOnce per run0.400.400.400.40

Platinum and Diamond plans pay the Gold price. The Store pricing card shows these same prices per 1,000 events: "$0.23 / 1,000" on the Keyword row means one keyword costs $0.00023, and "$260.00 / 1,000" on the Lookup row means one lookup costs 26 cents.

What a run costs (Gold plan): 3 keywords cost 0.40 (start) + 0.26 (one lookup) + 3 x 0.00023 = 0.6607. 1,000 keywords in one lookup cost 0.40 + 0.26 + 0.23 = 0.89. 5,000 keywords take five lookups: 0.40 + 5 x 0.26 + 1.15 = 2.85. Keyword ideas: 1,000 ideas from one lookup cost 0.89, like 1,000 keywords. The price does not depend on how many months you ask for.

Never charged as events (the start fee is charged at every run, refused ones included): keywords without Google data, rows delivered again from your memory, filtered keywords, refused input, the plan rows, the status rows and the summary, a lookup that finds no keyword with data, a close variant left out by Merge close variants, and an add-on for a keyword the data source does not hold. A run whose lookups keep finding nothing stops after what its start fee can carry, with a free row that says so (spend_bound); free rows past what the run's price can carry are not written, and a status row says how many (free_rows_capped, memory_rows_capped).

Spending control: set spendingLimitUsd, or the run option Max total charge; the run stops before its charges would pass it; the keywords it did not reach are counted in the summary (keywordsNotLookedUp, and rows.withheldByChargeLimit for keywords looked up but held back by the limit), and resumeFromPosition names the first list position to run again. An add-on is bought only for the keywords whose add-on event still fits the limit, and only while the run's price carries its request; an add-on request it does not carry is skipped with a free row (addon_not_bought), and the keyword rows go out without it. With more locations or lookups still ahead in the run, an add-on request that would leave too little room for the next lookup gives way first, so the keyword rows of every location are looked up before add-ons. The free row names which of the two happened and what to do: run that location on its own, or run the keywords again with the add-on in a smaller run.

Restarts. When the platform restarts a run (a migration), the run goes on from its ledger without buying or charging anything twice; its summary counts the rows and charged events of the whole run, and its outcome is partial with a note, since a lookup or add-on in flight at the restart may be missing. If the restarted run cannot read its dataset back, it stops (restart_read_failed) and rowCountsCover says its row counts cover that attempt only.

Input

SettingWhat it does
modevolume (your keywords), ideas (ideas from seeds, seeds included), website (keywords for websites)
keywords, keywordsTextKeywords or seeds, one per line; the paste box takes a copied column
websites, websiteScope, websiteSourceWebsite mode: up to 100 domains or page links; Google Ads keywords for them, or the keywords a domain ranks for
ideasSource, maxKeywords, maxIdeasPerSeed, sortByIdeas mode: Google Ads ideas, related searches, suggestions or autocomplete; the caps and the order (sortBy for the Google Ads source: relevance, search volume, competition, bids or CPC)
locations, languageUp to 10 locations; the language for ideas, website keywords and insights
historyMonths, dateFrom, dateToThe month window (default the latest 48 months)
planningMonths, planFromThe months to plan for (default the next 3)
minSearchVolume, includeWords, excludeWordsFilters (whole words, one rule for both lists)
mergeCloseVariants, searchPartners, includeAdultKeywordsGoogle Ads options (mergeCloseVariants delivers one keyword of each close variant group in the whole run, across lookups and the memory; it works with your list, Google Ads ideas and Google Ads website keywords, and since 2026-10-20 a run that combines it with related searches, suggestions, autocomplete or ranked keywords is refused, free)
speedslow (queued, default) or fast (live requests)
includeInsights, includeAiVolume, includeBingAdd-ons
memoryName, refreshMemoryThe 30 day memory and its refresh (a memory holds up to 30,000 keywords and 32 MB of stored figures, about 9,000 keywords with insights; past that, new rows are not delivered and not charged, with a free memory_full row)
spendingLimitUsd, maxRunMinutesLimits

A location name must be written the way Google Ads writes it; Zurich alone is refused with the closest names (Zurich,Switzerland is the canton, Zurich,Zurich,Switzerland the city). Country names also work in their own languages (Schweiz, Suisse) and as ISO codes (CH, CHE) or locale tags (de-CH).

Speed. slow sends each lookup through the queue: on 2026-10-18 eight queued lookups were ready in 10 to 21 seconds. fast sends live requests instead, which skip the queue; the same day five live requests took 23 to 161 seconds, so slow is the right default and fast is for the days the queue is long. A fast run sends a lookup live only while its spending bound can carry the live price; otherwise that lookup goes through the queue without the Fast lookup fee, and the row says which speed was used (speedUsed).

Example row

A keyword row from a platform run of this Actor (Switzerland, 2026-10-18), with the series, the seasonal index and the planning list shortened:

{
"type": "keyword",
"keyword": "winterjacke",
"dataStatus": "ok",
"noDataReason": null,
"searchVolume": 5400,
"monthlySearches": [
{
"month": "2022-10",
"year": 2022,
"monthNumber": 10,
"searches": 8100
},
{
"month": "2022-11",
"year": 2022,
"monthNumber": 11,
"searches": 18100
},
{
"...": "46 more months"
}
],
"monthsWithData": 48,
"missingMonths": [],
"competition": "HIGH",
"competitionIndex": 100,
"cpc": 0.99,
"lowTopOfPageBid": 0.41,
"highTopOfPageBid": 1.22,
"currency": "USD",
"seasonality": {
"cyclesCovered": 4,
"seasonalIndex": {
"January": 0.93,
"July": 0.11,
"November": 3.88,
"December": 1.81,
"...": "8 more months"
},
"monthlyAverages": {
"November": 21375,
"June": 338,
"...": "10 more months"
},
"peakMonths": [
"November",
"October",
"December",
"September"
],
"lowMonths": [
"June",
"May",
"April",
"July",
"March",
"February",
"August"
],
"peakMonth": "November",
"lowMonth": "June",
"strength": 63.33,
"label": "strongly seasonal",
"peakConsistency": {
"years": 3,
"peakWasTopMonth": 3
}
},
"trend": {
"latestMonth": "2026-09",
"latestSearches": 6600,
"momChangePct": 83.3,
"yoyChangePct": -19.2,
"last12MonthsTotal": 60770,
"previous12MonthsTotal": 75220,
"last3MonthsVsYearBeforePct": -20.2,
"qoqChangePct": 880.9,
"direction": "declining"
},
"planning": [
{
"month": "2026-11",
"monthName": "November",
"historicalAverage": 21375,
"yearsObserved": 4,
"seasonalIndex": 3.88,
"lastYearSearches": 18100,
"changeFromLatestPct": 223.9,
"historicalEvidence": "November averaged 21,375 searches a month over 4 years (2022 to 2025), 3.88 times the average month; November 2025 had 18,100; that is +223.9% against September 2026 (6,600), the latest month Google reported.",
"planningAssumption": "Assumes November 2026 follows the pattern of 2022 to 2025. Past search demand is history, not a forecast of demand or sales."
}
],
"locationCode": 2756,
"locationName": "Switzerland",
"locationType": "Country",
"countryCode": "CH",
"language": null,
"searchPartners": false,
"includeAdultKeywords": false,
"dateFrom": "2022-10",
"dateTo": "2026-09",
"source": "Google Ads (Keyword Planner data through DataForSEO)",
"sourceEndpoint": "keywords_data/google_ads/search_volume",
"dataAsOf": "2026-10-15",
"retrievedAt": "2026-10-18T18:21:02.757Z",
"spellCorrectedTo": null,
"closeVariants": [],
"inputPositions": [
1
],
"emptyFields": [],
"discoveredBy": "your keyword list",
"isSeed": null,
"discoveredByPaidSource": false,
"seedKeywords": null,
"extraWords": null,
"extraWordsNote": null,
"conceptGroups": null,
"discovery": null,
"fromMemory": false,
"memoryDeliveredOn": null,
"rowKey": "ab72497753414315d87f67f5",
"lookupId": "r0d9c844daf37aaacb283",
"speedUsed": "slow"
}

FAQ

Do I get exact monthly search volumes or ranges like 1K to 10K?

Exact figures as Google Ads reports them to advertisers, for every month of the window, not the ranges Keyword Planner shows to accounts without ad spend. Google rounds its figures (for example 49,500 or 60,500).

How do I get the search volume for each month, not only the average?

Every row carries monthlySearches with one entry per month of the window (48 by default), and MONTHLY_SEARCHES.csv in the run's key-value store has one line per keyword per month for a spreadsheet.

How do I find seasonal keywords and when to prepare for them?

Run your keywords or seeds and read seasonality.peakMonths and seasonality.label on each row, and the plan rows: each ranks the keywords of the run for one upcoming month by that month's historical average. changeFromLatestPct shows how far demand usually rises from the latest month to the planned one.

How accurate are the search volumes?

They are Google Ads' own figures (the numbers Keyword Planner shows advertisers), read through DataForSEO, so they carry Google's rounding and its merging of close variants: keywords Google gives the same figures are listed in closeVariants. A keyword with too few searches has no data and is a free row.

Can I get search volume for a city or region?

Yes. Any Google Ads location works: countries, states, regions, cantons, counties, provinces and cities, up to 10 per run, plus Worldwide. The insights add-on is by country.

Why does this Actor run with limited permissions?

Least privilege: it reads only its input and writes its own dataset and key-value store. The 30 day memory is a named key-value store it creates in your account under the name you choose.

What this Actor does NOT do

  • It does not forecast. Seasonality and plan ranks describe past searches; the next season can differ.
  • It does not say what a product is. Words found in keywords are demand, never product attributes.
  • No current month: Google Ads publishes a month after it ends, usually around the middle of the next month.
  • No data for keywords Google has too few searches for, or that it does not report (some restricted topics): those are free rows with dataStatus no_data.
  • Not split by device, and no click or impression forecasts.
  • Bing figures only for Australia, Canada, France, Germany, the United Kingdom and the United States (and their regions and cities), in English, French or German.
  • No Bing only runs: Bing figures come as an add-on on the Google rows.
  • No intent classifier of its own: search intent comes from the Labs database with the insights add-on.
  • Insights, related searches, suggestions and ranked keywords come from the Labs database, which covers whole countries in the languages it lists, and leaves out keywords it does not hold.
  • No backlinks, domain overviews, competitor domain discovery or competitor traffic reports, no Google Trends index, and no use of your own Google Ads or DataForSEO account.
  • No Standby (always on) HTTP mode: every lookup buys a data request that costs the same whatever it finds, so each call would need a fee of its own of about $0.25 or more; the run sync endpoint below gives the same rows in one HTTP response.
  • Postal code locations are not offered (Google Ads returns no data for them).

Use it through the API

The Actor works through the Apify API, as a scheduled job, and from Make, n8n or Zapier. The run sync endpoint returns the rows in the same HTTP response, which makes it a keyword volume API:

curl -X POST "https://api.apify.com/v2/acts/automation_craft~google-keyword-search-volume/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"keywords": ["winter jacket", "rain jacket"], "locations": ["United States"]}'
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('automation_craft/google-keyword-search-volume').call({ keywords: ['winter jacket'], locations: ['Canada'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
from apify_client import ApifyClient
client = ApifyClient("YOUR_TOKEN")
run = client.actor("automation_craft/google-keyword-search-volume").call(run_input={"keywords": ["winter jacket"], "locations": ["Canada"]})
items = client.dataset(run["defaultDatasetId"]).list_items().items

Changelog

  • 0.1 (2026-10-18): first release.
  • 0.1 (2026-10-20): Merge close variants holds across the whole run, the memory and restarts, and is counted before any maximum; with related searches, suggestions, autocomplete or ranked keywords it is now refused, free. Add-ons of large lists reach every row; an add-on the run cannot carry is skipped with a free row that says why and what to do, never a stop of the run. Memory size bound, restart and summary corrections.
  • 0.1 (2026-10-21): the summary gains rowCountsCover: after a restart that could not read its dataset back, its row counts cover that attempt only, and a note says so; the charged events stay those of the whole run.

More data tools by Automation Craft