Google Trends Scraper and Data API avatar

Google Trends Scraper and Data API

Pricing

from $0.25 / 1,000 results

Go to Apify Store
Google Trends Scraper and Data API

Google Trends Scraper and Data API

Google Trends scraper and data API: export interest over time (timeline), interest by region and related/rising queries for your keywords, location and date range, plus the Trending Now board by country. Export JSON, CSV or Excel.

Pricing

from $0.25 / 1,000 results

Rating

0.0

(0)

Developer

Eli J

Eli J

Maintained by Community

Actor stats

0

Bookmarked

11

Total users

5

Monthly active users

8 days ago

Last modified

Share

Use this Google Trends data API to export Google Trends data as clean, structured JSON, CSV or Excel — no API key, no browser, no scraping code.

This Actor reads the same endpoints the Google Trends website uses and returns four kinds of rows, one per dataType value: interest_over_time, interest_by_region, related_queries and trending_now.

DatasetWhat you get
Interest over timeThe 0–100 popularity score for each date in your range
Interest by regionThe 0–100 score broken down by country, state or sub‑region
Related & rising queriesThe top and fastest‑rising searches associated with your term
Trending nowWhat is trending in a country right now — with estimated search volumes

Two modes, one Actor. Keyword research analyses terms you supply. Trending now needs no keywords at all — pick a country and get the live trending board, each term carrying an estimated search volume (e.g. 500000), a growth percentage, whether it is still active, and the queries it broke down into.

Why this Actor

Google rate-limits its Trends endpoints and rejects a cold request, and this Actor is built around that.

  • Warmed sessions. A cold request is rejected before it is even rate-limited. Every session is established the way a browser establishes one.
  • Exponential backoff with jitter. Genuine rate limits are waited out instead of hammered.
  • Automatic identity rotation. When an IP gets throttled, the run rotates onto a fresh Apify Proxy session.
  • Proactive IP rotation. Each proxy identity is retired before Google throttles it, rather than after.
  • One failed read does not stop the others. If one dataset for one keyword cannot be read, the rest still land, and the problem is recorded in SUMMARY and ERRORS.
  • Transparent pricing. Result rows and an automatic, memory-scaled Actor Start fee are charged separately. See Pricing below for storage and data-traffic costs.

What you get

  • Any number of keywords per run, each scored on its own scale, or up to 5 on a shared scale for direct comparison.
  • Keyword research and Trending Now in one Actor.
  • Every value states its scale. valueScale tells you whether a number is a 0–100 index, a percentage share between compared terms, or a growth percentage. Mixing those up is the most common way to draw a wrong conclusion from Trends data.
  • Sortable ISO-8601 dates, not locale display strings that drop the year on short ranges.
  • No result charge without result rows. The automatic Actor Start fee still applies; an empty or failed run is not promised to be free.
  • Failed requests are never written to your dataset, so a Google-side error cannot appear on your bill as a result row.
  • Paste a Google Trends URL instead of filling in fields.

One thing worth knowing: Google's Trending Now board is country-level. Sub-region codes return the parent country's identical board, and metro (DMA) codes return nothing at all — verified by direct testing. This Actor accepts a sub-region code, warns you in the log, and uses the country, rather than implying a precision Google does not provide.

  1. Choose mode: keywords for keyword research or trending for the Trending Now board.
  2. Enter keywords or paste a Google Trends URL in startUrls; in trending mode, set geo instead.
  3. In keyword mode, set geo, timeRange, dataTypes and compareKeywords.
  4. Optionally turn on includeKeywordInsights (keyword mode) and set maxItems.
  5. Start the run, then split the dataset rows by dataType.
  6. Read SUMMARY for processing coverage, ERRORS for handled failures and, when you opted in, KEYWORD_INSIGHTS.

You can also start from a published task. Each one runs the saved input shown for it under Input:

Pricing

Pay per result row plus the automatic apify-actor-start event. The configured start-event price is $0.00005 per event: Apify charges one event for up to and including 1 GB of allocated RAM, then one additional event for each extra GB. The start charge depends on allocated memory; it is not a fixed fee per run. Consult the Actor's current Pricing tab for applicable result rates.

No rows means no result-row charge. Errors and the processing summary are stored in the key-value store and add no result or custom-event charge. The keyword-insight list lives in the run's key-value store, not the dataset. When the keyword-insight event is listed in the Actor's pricing, it is charged once per written insight if includeKeywordInsights is on and that keyword has at least four emitted interest_over_time points whose hasData is not false; opting in before then returns the KEYWORD_INSIGHTS record without an add-on charge. If the record write fails after the charge, ERRORS says so under keywordInsightWrite. A spending-limit skip is recorded there under keywordInsightSkipped. A skip is recorded under keywordInsightUnknown when charged_count was unavailable and event_charge_limit_reached was true, or was zero without event_charge_limit_reached. This does not waive the start charge. Apify storage and dataset read/write traffic can still incur charges according to your plan.

maxItems caps emitted rows, not upstream requests or the start charge: the Actor can fetch a batch before applying the cap, including when the cap is zero. Selecting fewer datasets or a narrower range can reduce output; actual row counts depend on Google.

Input

In keyword mode, only keywords is required (or a Trends URL in startUrls). In trending mode nothing is required — geo defaults to US. Everything else has a sensible default.

FieldTypeDefaultDescription
modestringkeywordskeywords (research) or trending (live board).
keywordsarray—Search terms, or Google Trends topic IDs such as /m/0k8z.
startUrlsarray—Paste Trends explore URLs; q/geo/date/cat are parsed out. Keywords from several URLs are pooled; geo/date/category come from the first URL.
geostring""US, GB, DE, or a sub‑region such as US-CA. Empty means Worldwide.
timeRangestringtoday 12-mPreset (now 1-d, today 3-m, today 5-y, all, …) or a custom range like 2024-01-01 2024-12-31.
dataTypesarrayall threeWhich datasets to return. Requesting fewer costs less.
compareKeywordsbooleanfalseSee below.
includeKeywordInsightsbooleanfalseOpt-in add-on. When on, keyword mode writes one derived insight per keyword to the KEYWORD_INSIGHTS key-value record (never the dataset) from that keyword's emitted rows. The keyword-insight charge applies once per written insight when that event is listed in the Actor's pricing; opting in before then returns the record without an add-on charge. Fewer than four emitted interest_over_time points whose hasData is not false skip the charge; a write that fails after the charge is reported under keywordInsightWrite in ERRORS, a spending-limit skip under keywordInsightSkipped, and a skip under keywordInsightUnknown when charged_count was unavailable and event_charge_limit_reached was true, or was zero without event_charge_limit_reached. Partial coverage still bills once when the event is listed. Off: no insight and no add-on charge. Ignored in Trending now mode.
searchTypestring"" (Web search)images, news, froogle (Shopping) or youtube. Web search is the empty string, not "web".
categorystring"0"Labelled Google Trends category picker.
languagestringen-USLanguage of returned labels.
maxItemsinteger—Hard cap on result rows.
maxRetriesPerRequestinteger8How hard to retry when Google throttles.
maxRunSecondsinteger3600Stop starting new batches after this long, so an outage cannot burn a run. 0 disables.
rotateAfterRequestsinteger24Retire each proxy identity after N requests. 0 disables.
timezoneOffsetMinutesinteger0Offset used to bucket hourly data.
proxyConfigurationobjectApify Proxy onStrongly recommended to leave enabled.

Trending-now mode only

FieldTypeDefaultDescription
trendingHoursstring244, 24, 48 or 168 (7 days).
trendingCategoriesarrayallMulti-select of Google's 19 trending categories.
trendStatusstringallall, active (still rising) or ended.

Trending mode ignores timeRange, dataTypes, category, searchType, compareKeywords, includeKeywordInsights, language, timezoneOffsetMinutes and maxRunSeconds.

Saved inputs of the published tasks

Each block below is a published task's saved input, exactly as stored. It includes fields its mode ignores (trending-only fields in the keyword tasks, and the fields listed above as ignored by trending mode in the trending task), and it does not contain every available field.

Find rising related queries for a keyword in the US

{
"mode": "keywords",
"keywords": ["air fryer"],
"dataTypes": ["related_queries"],
"geo": "US",
"timeRange": "today 12-m",
"maxItems": 50,
"compareKeywords": false,
"searchType": "",
"category": "0",
"language": "en-US",
"timezoneOffsetMinutes": 0,
"trendingHours": "24",
"trendStatus": "all",
"maxRunSeconds": 3600,
"maxRetriesPerRequest": 8,
"rotateAfterRequests": 24,
"proxyConfiguration": {"useApifyProxy": true}
}

Compare two keywords on one Google Trends scale (US)

{
"mode": "keywords",
"keywords": ["air fryer", "espresso machine"],
"compareKeywords": true,
"dataTypes": ["interest_over_time"],
"geo": "US",
"timeRange": "today 12-m",
"maxItems": 120,
"searchType": "",
"category": "0",
"language": "en-US",
"timezoneOffsetMinutes": 0,
"trendingHours": "24",
"trendStatus": "all",
"maxRunSeconds": 3600,
"maxRetriesPerRequest": 8,
"rotateAfterRequests": 24,
"proxyConfiguration": {"useApifyProxy": true}
}

What is trending on Google in the US right now

{
"mode": "trending",
"geo": "US",
"trendingHours": "24",
"maxItems": 100,
"timeRange": "today 12-m",
"dataTypes": ["interest_over_time", "interest_by_region", "related_queries"],
"compareKeywords": false,
"searchType": "",
"category": "0",
"language": "en-US",
"timezoneOffsetMinutes": 0,
"trendStatus": "all",
"maxRunSeconds": 3600,
"maxRetriesPerRequest": 8,
"rotateAfterRequests": 24,
"proxyConfiguration": {"useApifyProxy": true}
}

Research worldwide Google Trends for kitchen appliances

{
"keywords": ["air fryer", "espresso machine"],
"startUrls": [],
"mode": "keywords",
"geo": "",
"timeRange": "today 12-m",
"dataTypes": ["interest_over_time", "interest_by_region", "related_queries"],
"compareKeywords": false,
"includeKeywordInsights": false,
"searchType": "",
"category": "0",
"language": "en-US",
"timezoneOffsetMinutes": 0,
"trendingHours": "24",
"trendStatus": "all",
"maxRunSeconds": 3600,
"maxRetriesPerRequest": 8,
"rotateAfterRequests": 24,
"proxyConfiguration": {"useApifyProxy": true}
}

Summarize Google Trends for air fryers and espresso machines

{
"keywords": ["air fryer", "espresso machine"],
"dataTypes": ["interest_over_time"],
"includeKeywordInsights": true,
"maxItems": 120,
"mode": "keywords",
"geo": "",
"timeRange": "today 12-m",
"compareKeywords": false,
"searchType": "",
"category": "0",
"language": "en-US",
"timezoneOffsetMinutes": 0,
"trendingHours": "24",
"trendStatus": "all",
"maxRunSeconds": 3600,
"maxRetriesPerRequest": 8,
"rotateAfterRequests": 24,
"proxyConfiguration": {"useApifyProxy": true}
}

Independent scores vs. comparison

This matters.

  • compareKeywords: false (default) — each term is fetched on its own and scored 0–100 against itself. Use this when you want each keyword's own trend shape. You can pass any number of keywords. Rows carry valueScale: "index_0_100".
  • compareKeywords: true — up to 5 terms are fetched together on one shared scale, so they are directly comparable. This is the Google Trends comparison view.

Read valueScale before comparing numbers. In comparison mode interest_by_region is a percentage share between the compared terms (valueScale: "comparison_share_percent") — Wyoming returns bitcoin 82% / ethereum 18%, summing to 100 across terms. That is a different quantity from the self-normalised 0–100 index, and mixing them up is the classic way to draw a wrong conclusion from Trends data.

Passing more than 5 terms with comparison on splits them into groups of 5; terms in different groups are not comparable to each other, only within their group.

Output

One flat row per data point — ready for a spreadsheet, a database, or a dashboard.

Interest over time — date is always a sortable ISO-8601 UTC timestamp; Google's own display label is kept beside it.

{
"keyword": "air fryer",
"dataType": "interest_over_time",
"date": "2025-07-20T00:00:00+00:00",
"dateLabel": "Jul 20, 2025",
"dateRangeLabel": "Jul 20 – 26, 2025",
"timestamp": 1752969600,
"value": 60,
"hasData": true,
"geo": "US",
"timeRange": "today 12-m",
"searchType": "web"
}

Interest by region

{
"keyword": "air fryer",
"dataType": "interest_by_region",
"geoCode": "US-WY",
"geoName": "Wyoming",
"value": 100,
"formattedValue": "100",
"valueScale": "index_0_100",
"hasData": true
}

Rows where hasData is false are regions Google has no signal for; they carry value: 0 and are still written (and billed) so the region list stays complete. Filter on hasData if you only want regions with real signal.

Related & rising queries

{
"keyword": "air fryer",
"dataType": "related_queries",
"rankType": "TOP",
"query": "air fryer chicken",
"value": 100,
"link": "https://trends.google.com/trends/explore?q=air+fryer+chicken&date=today+12-m&geo=US"
}

Trending now (mode: "trending")

{
"dataType": "trending_now",
"term": "david jonsson",
"geo": "US",
"searchVolume": 500000,
"growthPercent": 1000,
"isActive": true,
"startTimestamp": 1785029400,
"endTimestamp": null,
"categoryIds": [4],
"breakdownQueries": ["david jonsson", "black panther 3", "damson idris"],
"trendsUrl": "https://trends.google.com/trends/explore?q=david+jonsson"
}

Filter by the dataType field to split the datasets apart, or use the Apify API to export each separately.

Processing summary and request errors

The Output tab links the result dataset and the key-value store collections. Read the SUMMARY JSON record for processing coverage; ERRORS contains handled request failures when any occur; KEYWORD_INSIGHTS is the opt-in keyword-insight list when includeKeywordInsights is on. None of these records is written to the billable result dataset.

SUMMARY has schemaVersion, mode, status, requested, completed, failed, skipped, rowsEmitted, rowsOmitted, limits, and work. Invalid input also carries reason. A keyword work item is one keyword occurrence and selected dataset within its batch; keywordIndex is zero-based within that batch. Trending mode has one board item. Each item records batch, dataType, state, and, for keyword mode, keywordIndex and keyword. Skips/failures include a reason; request failures also include error.

  • completed: the upstream read and row processing returned, including a valid empty result. This does not prove Google supplied every possible data point.
  • failed: a handled explore, widget or Trending Now request error. When the keyword-insight add-on is on, an unexpected error inside a batch is also marked failed with reason unexpected_error and recorded on ERRORS. Useful results from other work remain available.
  • skipped: a requested widget was missing (missing_widget) or work was not started when the existing row/time limit stopped the loop.
  • requested equals completed + failed + skipped. rowsOmitted counts only fetched rows withheld by maxItems; it never estimates unfetched data. limits names encountered max_items or max_run_seconds boundaries.

status is complete when all requested work was processed with no failures, skips or observed row omissions; incomplete otherwise. Zero selected work is no_work; handled input rejection is invalid_input. This status is separate from Apify's run status: a SUCCEEDED run can have incomplete output. An exact row cap need not imply incomplete work if nothing was omitted or left unstarted.

These records are saved on normal and explicitly handled exits. They may be absent after an abort, timeout, uncaught exception or storage failure; absence is not evidence of completeness. Existing request/error and stopping behavior is preserved.

Keyword insight add-on

includeKeywordInsights is an opt-in rollup of rows this run already paid for. It makes no extra Google requests. When on, keyword mode writes one insight object per keyword to the KEYWORD_INSIGHTS key-value record (never the default dataset), computed from that keyword's emitted interest_over_time and related-query rows after maxItems trimming. The keyword-insight charge applies once per written insight when that event is listed in the Actor's pricing; opting in before then returns the record without an add-on charge. Fewer than four emitted interest_over_time points whose hasData is not false skip the insight and the charge. Partial coverage — a planned dataset for that keyword failed or was skipped, or maxItems trimmed this keyword's rows — still bills once when the event is listed. Result-row prices still apply to the dataset rows. A charge that raises is recorded on ERRORS as keywordInsightCharge; a write that fails after a successful charge is recorded as keywordInsightWrite; any other unexpected error while computing, charging or recording one keyword's insight is recorded as keywordInsightError and the next keyword proceeds; a spending-limit skip is recorded as keywordInsightSkipped; a skip is recorded as keywordInsightUnknown when charged_count was unavailable and event_charge_limit_reached was true, or was zero without event_charge_limit_reached. Neither drops already-pushed rows nor fails the run. Off: no insight and no add-on charge. Trending mode ignores the flag.

Each object carries:

FieldDefinitionScale
keywordThe term this object summarises.—
geoThe geo used for that keyword's fetch (Worldwide when empty).—
timeRangeThe time range used for that keyword's fetch.—
latestValuevalue of the last interest_over_time point in timestamp order.index_0_100_derived
meanValueArithmetic mean of those points' values.index_0_100_derived
minValueSmallest value among those points; ties keep the earliest point.index_0_100_derived
minDatedate (else dateLabel) of the minValue point.—
maxValueLargest value among those points; ties keep the earliest point.index_0_100_derived
maxDatedate (else dateLabel) of the maxValue point.—
peakDateSame date as maxDate: the first point that reaches maxValue.—
linearSlopePerPointOrdinary-least-squares slope of value against the 0-based series index.index_0_100_derived
firstToLastWindowChangePercent((mean of last n//4 points) - (mean of first n//4 points)) / (mean of first n//4 points) * 100. A 0-to-0 window is 0; a 0-to-nonzero window is omitted (null).growth_percent
coefficientOfVariationPopulation standard deviation of value divided by the mean. A constant series is 0. A zero mean with nonzero spread is omitted (null).ratio
pointsCount of numeric interest_over_time rows used.—
dateRangeLabelFirst point's date (else dateLabel) and last point's, joined with to.—
risingQueryCountCount of related_queries rows with rankType RISING for this keyword; null when none are present.—
maxRisingGrowthPercentLargest numeric value among those RISING rows; null when none are present.growth_percent
valueScaleMap of the numeric fields above to index_0_100_derived, growth_percent, or ratio.—
coveragecomplete only when every planned data type for this keyword has RunSummary state completed and maxItems did not drop any of this keyword's rows in this batch; otherwise partial.—
coverageReasonsPresent when coverage is partial: the reason (else state) of each non-completed work unit for this keyword, and max_items when that cap trimmed this keyword's emitted rows.—

ERRORS is a JSON list of handled failures. When the keyword-insight add-on is on, the record is written as add-on failures occur and again at the end of the run. Request failures keep their existing shape. Add-on failures name the keyword and one of keywordInsightCharge (the add-on charge raised; base rows for that keyword were still delivered), keywordInsightSkipped (the spending limit was reached before this insight could be charged; base rows were still delivered), keywordInsightUnknown (charged_count was unavailable and event_charge_limit_reached was true, or charged_count was 0 and event_charge_limit_reached was not reported; the insight was not written and base rows were still delivered), keywordInsightWrite (the insight was charged but its record write failed; base rows were still delivered) or keywordInsightError (an unexpected error while computing, charging or recording that keyword's insight; charged is true when Actor.charge returned for that keyword and the run had not decided against writing; a keyword that failed before its charge was not charged, and base rows were still delivered).

ActorResearch fitWhat it exports
Kalshi Weather Price HistoryWeather-market price historyHourly or daily candles for named Kalshi weather markets: prices, bids, asks, volume and open interest as exact decimal strings
UFCStats Fight & Round StatsUFC fight statisticsUFCStats fight and round statistics as flat rows with fighter IDs, event dates and locations
Tennis Abstract Data APITennis match statisticsATP and WTA player match histories from Tennis Abstract: scores, opponents, surfaces and available serve and return statistics
Clutch Scraper: Agency DirectoryAgency research and lead generationB2B agency listings from Clutch.co directories: company names, websites, locations, headcounts and service mix
Google Ads Archive: Ads Transparency ExportAd-creative researchAdvertiser ad records from Google's Ads Transparency Center: creative format, available images, first and last shown dates and source links

FAQ and support

Include related_queries in dataTypes. Rows with rankType TOP carry valueScale: "index_0_100"; rows with rankType RISING carry valueScale: "growth_percent", so a rising value is a growth percentage, not a 0–100 index. Filter on rankType to keep the rising queries. The Find rising related queries for a keyword in the US task is set up this way for one keyword.

Set compareKeywords: true. Up to 5 terms are then fetched together on one shared scale, so they are directly comparable: interest_over_time rows carry valueScale: "comparison_index_0_100", and interest_by_region values become a percentage share between the compared terms (valueScale: "comparison_share_percent"). More than 5 terms are split into groups of 5, and terms in different groups are not comparable to each other. See Independent scores vs. comparison under Input, or start from the Compare two keywords on one Google Trends scale (US) task.

Set mode to trending and geo to a country code; geo defaults to US, and trendingHours sets the window. Google's Trending Now board is country-level: sub-region codes return the parent country's board and metro (DMA) codes return nothing, so this Actor uses the country for a sub-region code and warns you in the log. searchVolume and growthPercent are Google's bucketed lower bounds; treat them as floors, not exact counts. The What is trending on Google in the US right now task reads the US board.

In keyword mode, interest_over_time and interest_by_region values represent relative popularity, not search volumes. With compareKeywords off, those values are scored 0–100 against each keyword's own scale. Related-query values use their own scales: TOP is a 0–100 index and RISING is a growth percentage; check valueScale before comparing numbers. Only the Trending Now searchVolume is an absolute figure, and it is a bucketed lower bound. Leave geo empty for Worldwide. Very long ranges return coarser buckets; see Notes and limits. The Research worldwide Google Trends for kitchen appliances task is a worldwide keyword setup.

What are keyword insights, and when are they charged?

Turn on includeKeywordInsights in keyword mode to get one derived insight per keyword in the KEYWORD_INSIGHTS key-value record, never the dataset. Each insight is computed from that keyword's emitted rows after maxItems trimming and makes no extra Google requests; it is derived from collected rows and is not a forecast. A keyword with fewer than four emitted interest_over_time points whose hasData is not false gets no insight and no charge. The keyword-insight charge applies once per written insight only when that event is listed in the Actor's pricing; opting in before then returns the record without an add-on charge. Partial coverage still bills once when the event is listed; coverage is then partial and coverageReasons lists why. Field definitions and error classes are under Keyword insight add-on in Output. The Summarize Google Trends for air fryers and espresso machines task turns the add-on on.

Why can a SUCCEEDED run have incomplete data?

The SUMMARY status is separate from Apify's run status, so a SUCCEEDED run can have incomplete output. A completed work item means the upstream read and row processing returned; it does not prove Google supplied every possible data point. maxItems caps emitted rows, not upstream requests or the start charge. rowsOmitted counts only fetched rows withheld by maxItems, and limits names encountered max_items or max_run_seconds boundaries; an exact row cap need not imply incomplete work if nothing was omitted or left unstarted. SUMMARY, ERRORS and KEYWORD_INSIGHTS may be absent after an abort, timeout, uncaught exception or storage failure; absence is not evidence of completeness. See Processing summary and request errors under Output.

Notes and limits

  • Keyword-mode values (interest_over_time, interest_by_region) are relative popularity indices, not absolute search counts — either 0–100 against the term itself, or a percentage share between compared terms. Check valueScale.
  • Trending-now searchVolume is an absolute figure, but it is Google's own bucketed lower bound — 500000 is displayed by Google as "500K+", and growthPercent of 1000 means "1,000%+". Treat both as floors, not exact counts; summing them understates the true total.
  • Google's Related topics widget currently returns an empty list for every query we tested, so this Actor does not offer it rather than shipping a field that is always blank.
  • Very long ranges return coarser buckets (5 years → weekly, all → monthly). That is Google's own resolution behaviour.
  • This Actor collects public, aggregated, non-personal statistics only.

Support

Found a bug or need a dataset that isn't here? Open an issue on the Actor's Issues tab and I'll take a look.