Google Trends API Python: ~4.6s Typical (Was ~9s)
A Google Trends API Python GET is ~4.6s typical (was ~9s on 22 billed calls). Live interest-over-time and related queries, same 5 credits, 2026-09-08 UTC.
A Google Trends API Python GET now typically returns in ~4.6s on a billed miss (was ~9s). That was measured on production across 22 billed calls after 2026-09-07. Credits stayed 5. Interest-over-time (GET /v1/google_trends/explore) and related/rising (GET /v1/google_trends/rising) share that contract.
Google announced a Trends API alpha on 24 Jul 2025. Access is apply-only for limited testers — not a public REST key. pytrends is the unofficial pandas library people already pip install — last release 13 Apr 2023, looking for maintainers. You call it with x-api-key and a GET.
Which Google Trends API to pick, and what it costs, is on best Google Trends APIs 2026. This post is the speed change and how to call explore / rising.
Stack: Python 3 · requests · GET https://www.socialcrawl.dev/v1/google_trends/explore and /v1/google_trends/rising · header x-api-key. JSON is trimmed from a 2026-09-08 production harvest on the SocialCrawl API — not a screenshot, not a DataFrame stub. A free 404 and a free 400 are in here too, so a dead keyword does not look like a timeout.
How do you pull Google Trends interest over time in Python?
GET /v1/google_trends/explore is the Google Trends interest over time API. Pass 1–5 keywords, an optional location, and a timeframe. The response is dated series plus per-keyword averages on Google's relative 0–100 index, not search volume. The request is one GET. No SDK.
This Google Trends API Python example compares three US terms over past_12_months (the default window). Harvest row #2, 2026-09-08, cache miss, request_id req-xyaesW1MDftWKcMP. HTTP 200, 5 credits, 6,751 ms.
import os
import requests
BASE = "https://www.socialcrawl.dev"
r = requests.get(
f"{BASE}/v1/google_trends/explore",
params={
"keywords": "oat milk,almond milk,soy milk",
"location": "US",
"timeframe": "past_12_months",
},
headers={"x-api-key": os.environ["SOCIALCRAWL_API_KEY"]},
timeout=90,
)
r.raise_for_status()
payload = r.json()
print(payload["credits_used"], payload["data"]["averages"])
# 5, oat milk 51 / almond milk 68 / soy milk 24Curl twin of the same GET:
curl -s --max-time 90 -H "x-api-key: $SOCIALCRAWL_API_KEY" \
"https://www.socialcrawl.dev/v1/google_trends/explore?keywords=oat%20milk,almond%20milk,soy%20milk&location=US&timeframe=past_12_months"Trimmed envelope from that call (three series × 53 weekly points; first and last bucket only):
{
"success": true,
"data": {
"averages": [
{ "keyword": "oat milk", "value": 51 },
{ "keyword": "almond milk", "value": 68 },
{ "keyword": "soy milk", "value": 24 }
],
"series": [
{
"keyword": "oat milk",
"points": [
{ "date": "2025-09-07", "value": 43, "partial": false },
{ "date": "2026-09-06", "value": 60, "partial": true }
]
},
{
"keyword": "almond milk",
"points": [
{ "date": "2025-09-07", "value": 56, "partial": false },
{ "date": "2026-09-06", "value": 71, "partial": true }
]
},
{
"keyword": "soy milk",
"points": [
{ "date": "2025-09-07", "value": 18, "partial": false },
{ "date": "2026-09-06", "value": 22, "partial": true }
]
}
]
},
"credits_used": 5,
"request_id": "req-xyaesW1MDftWKcMP"
}Read the averages as one 0–100 scale across the set. Almond milk 68, oat milk 51, soy milk 24. Those three numbers are comparable only inside this call. Almond milk is the only term that hits 100 (week of 2026-04-12). Soy milk never exceeds 36 in the full series. That is the normalisation proof: three terms, one request, directly comparable. Two separate explores are not comparable. Google's own FAQ is blunt about this — a point is a share of searches in that geography and window, scaled 0–100, not a headcount.
The envelope also carries success, platform, endpoint, credits_used, and request_id. credits_used is 5 on a billed miss. Drop the last bucket before you chart: every explore series in this harvest set partial: true on the week of 2026-09-06 (still counting).
Same object, one term. keywords=solid state battery (req-T98bfg3d2yGqBi4r) returned 53 points, average 42, peak 100 the week of 2026-06-07, min 17 on 2025-09-28. 7,284 ms, 5 credits, cache miss. Same series / averages shape. Swap the keywords param; do not learn a second schema.
Caveats that bite in practice:
- Relative index ≠ search volume. Almond milk at 68 does not mean 68 searches.
- 1–5 keywords. More than five is a free 400.
locationaccepts ISO (US,KR), the full country name as Trends spells it (South Korea), or a numeric code. Default leans worldwide-US.- Default
timeframeispast_12_months. Eight presets, no arbitrary date range.
How do you get Google Trends related queries from an API?
GET /v1/google_trends/rising returns rising and top for one keyword. The resource name is rising, not related-queries. Google's alpha announcement is about consistently scaled interest data, not related-query lists. This path is the related queries API: breakouts with a percent growth, plus the most-searched related queries on a 0–100 value.
Rising is the list you want when a term is about to move — breakouts that are not yet large enough to dominate the interest-over-time series. Top is where demand is concentrated right now. The param is keyword (singular). A comma-separated list is a free 400. Usual order: explore to size the series, then rising on the winner.
Harvest row #4. keyword=solid state battery, US, past_12_months. HTTP 200, 5 credits, 19,059 ms, cache miss, req-JmaL2ZAMP0bYaoVT. 15 rising rows (numeric growth on 7 of 15), 25 top rows.
r = requests.get(
f"{BASE}/v1/google_trends/rising",
params={
"keyword": "solid state battery",
"location": "US",
"timeframe": "past_12_months",
},
headers={"x-api-key": os.environ["SOCIALCRAWL_API_KEY"]},
timeout=90,
)
r.raise_for_status()
payload = r.json()
print(
payload["credits_used"],
len(payload["data"]["rising"]),
len(payload["data"]["top"]),
)
# 5, 15, 25curl -s --max-time 90 -H "x-api-key: $SOCIALCRAWL_API_KEY" \
"https://www.socialcrawl.dev/v1/google_trends/rising?keyword=solid%20state%20battery&location=US&timeframe=past_12_months"Trimmed body. Numeric growth kept; two nulls left as Google sent them:
{
"success": true,
"data": {
"rising": [
{ "query": "donut battery", "growth": null },
{ "query": "donut lab", "growth": null },
{ "query": "solid state portable battery", "growth": 650 },
{ "query": "solid state drive", "growth": 500 },
{ "query": "silver solid state battery", "growth": 200 },
{ "query": "solid state battery phone", "growth": 200 },
{ "query": "samsung solid state battery", "growth": 180 }
],
"top": [
{ "query": "solid state drive", "value": 100 },
{ "query": "what is solid state battery", "value": 64 },
{ "query": "solid power", "value": 59 },
{ "query": "solid state battery toyota", "value": 57 },
{ "query": "samsung solid state battery", "value": 56 }
]
},
"credits_used": 5,
"request_id": "req-JmaL2ZAMP0bYaoVT"
}rising[].growth is percent growth. A true breakout can read into the thousands; this harvest's max is +650 (solid state portable battery), then +500, +200, +200, +180. Eight of the 15 rising rows came back growth: null. Google omitted the number; the envelope carries _warnings for those. Do not fill them in. top[].value is 0–100 relative. solid state drive at 100 is the related-query ceiling in this window, not a volume count.
This rising call was 19.1s on this run — that number belongs with the n=4 session below, not as the production typical.
How long does a Google Trends API Python call take?
Typical billed call is ~4.6s now (was ~9s), measured on 22 billed calls after 2026-09-07. Two tables. Do not mix them.
Production claim, 22 billed calls after 2026-09-07:
| Fact | Before → after (22 billed calls, 2026-09-07) |
|---|---|
| Typical billed call | ~9s → ~4.6s |
| Slow tail | p95 ~47s → ~12s as the worst of those 22 |
| Timeouts | 273 of 19,459 over 30 days, each after ~48s → now rare |
| Unchanged | Same params, same shape, same 5 credits, same free 400 / 404 |
This Google Trends Python API run, n=4 cache-miss billed calls on 2026-09-08 (window 00:23:27Z–00:26:45Z), all 5 credits:
| Call | latency |
|---|---|
explore multi (oat milk,almond milk,soy milk, US) | 6.8s (6,751 ms) |
explore single (solid state battery, US) | 7.3s (7,284 ms) |
rising (solid state battery, US) | 19.1s (19,059 ms) |
explore Hangul (선풍기, South Korea) | 19.7s (19,745 ms) |
US English explore answered in ~7s. Hangul and rising sat near 19s — slower than the 22-call worst of ~12s, on a sample of four. Still inside a 60s client timeout; not a 48s timeout failure. Cold, non-English and non-US terms are where the update shows most. Do not overwrite the production table with a four-call mean.
Captured call, harvest #3. keywords=선풍기 (electric fan), location=South Korea, past_12_months. 53 points, average 21, winter floor 4 (week of 2026-02-15), summer peak 100 (week of 2026-07-26), last point 13 partial: true. 19,745 ms, 5 credits, cache miss, req-PIzuSdK1giC8D5Zw.
r = requests.get(
f"{BASE}/v1/google_trends/explore",
params={
"keywords": "선풍기",
"location": "South Korea",
"timeframe": "past_12_months",
},
headers={"x-api-key": os.environ["SOCIALCRAWL_API_KEY"]},
timeout=90,
)
r.raise_for_status()
payload = r.json()
print(payload["credits_used"], payload["data"]["averages"][0]["value"])
# 5, 21{
"success": true,
"data": {
"series": [
{
"keyword": "선풍기",
"points": [
{ "date": "2025-09-07", "value": 18, "partial": false },
{ "date": "2026-02-15", "value": 4, "partial": false },
{ "date": "2026-07-26", "value": 100, "partial": false },
{ "date": "2026-09-06", "value": 13, "partial": true }
]
}
],
"averages": [{ "keyword": "선풍기", "value": 21 }]
},
"credits_used": 5,
"request_id": "req-PIzuSdK1giC8D5Zw"
}A seasonal series is the easy read: winter 4, July 100, window average 21. The latency is not tidy. 19.7s is not ~4.6s. The upgrade note says this lane improved most; this one pull, on a sample of four, was still the slowest billed call of the morning.
Empty interest is a 404 at 0 credits, and that 404 can be slow. keywords=zzqxjbv7wmpl3nonsense99 explore took 52,918 ms, req-Q2kdMXZn17dS9X6l. That is a fallback confirming no data, not a billed timeout. The message names that location and timeframe were accepted, so you know it is the keyword. Some nonsense strings return a sparse 200 and get billed 5 — only the 404 that actually 404'd is below. The matching rising 404 (req-JSVh0G2ZHHUy7YbJ) is the same contract: 0 credits, 11.7s.
{
"success": false,
"error": {
"type": "RESOURCE_NOT_FOUND",
"message": "No search-interest data were returned for this keyword. The location and timeframe were accepted; Google Trends simply holds too little search volume for this keyword in that combination to build a result. Try a wider `timeframe`, a broader keyword, or the keyword in the local language of the location you requested. You were not charged for this request.",
"status": 404,
"doc_url": "https://www.socialcrawl.dev/docs/errors#resource-not-found"
},
"credits_used": 0,
"request_id": "req-Q2kdMXZn17dS9X6l"
}Bad location is a 400 at 0 credits, and it is fast. location=Atlantis returned in 413 ms, req-xOeHKo1Bw5ZaRyJP. The message names ISO / full name / numeric forms so the caller knows it is the location, not the keyword. Error taxonomy: /docs/errors.
{
"success": false,
"error": {
"type": "INVALID_REQUEST",
"message": "Google Trends did not recognise one of the request parameters. `location` must be an ISO country code (\"KR\", \"US\"), the full country name as Google Trends spells it (\"South Korea\", \"United States\"), or a numeric location code (\"2410\"). Google Trends does not publish every country, so a location it has no data for is refused here as well. `category` must be a numeric Google Trends category code. Your credits have been refunded.",
"status": 400,
"doc_url": "https://www.socialcrawl.dev/docs/errors#invalid-request"
},
"credits_used": 0,
"request_id": "req-xOeHKo1Bw5ZaRyJP"
}Cache hits are free and millisecond-fast. None of the billed four were hits (cached: false on every success). Set the client timeout ≥60s (this harvest used 90). Credits stayed 5 across the speed change.
How do you use a Google Trends API from Python?
You send header x-api-key and one GET. No SDK, no OAuth.
- Get a key. Sign up; new accounts get 100 free credits. Send it as header
x-api-keyonly — no OAuth, no query-string key. Auth notes:/docs/authentication. That is one API key for both GETs above. - Copy the first
requestsblock. Printcredits_usedand theaveragesarray. Set timeout to 90. - Named timeframes:
past_hour,past_4_hours,past_day,past_7_days,past_30_days,past_90_days,past_12_months(default, what the harvest used),past_5_years. No arbitrary date range.past_hour/past_4_hoursare minute-level;past_5_yearsis weekly. - Next: Google Trends endpoint docs for the field map, and try the same call in the explorer. Responses sit on the unified schema — a
dev.socialcrawlenvelope, not a one-off Trends dump.
That docs page is the Google Trends API documentation for these two paths. This post is the live harvest, not a second copy of it.
Frequently asked questions
How long does a Google Trends API take?
Typical billed call is ~4.6s now (was ~9s), measured on 22 billed calls after 2026-09-07. A four-call production check on 2026-09-08 landed 6.8s–19.7s depending on the term — that table is "this run", not the typical.
Why did the Google Trends API timeout?
273 of 19,459 calls over 30 days died after ~48s. Slow tail on the 22 billed calls after the change was ~12s worst-case. Timeouts are rare, not gone. Empty-interest 404s can still sit near 50s at 0 credits — that is not a billed timeout. Use a client timeout ≥60s.
Is there an official Google Trends API?
Yes. Google announced a Trends API alpha on 24 Jul 2025, limited testers, apply-form access, not a drop-in public REST key. SocialCrawl is a public x-api-key GET returning website-style 0–100 series. For which-API / pricing, see best Google Trends APIs 2026.
How do you call a Google Trends related queries API?
GET /v1/google_trends/rising?keyword=… returns rising and top for one keyword. Resource is rising. 5 credits on a billed miss. keyword is singular.
Did credits or the response shape change?
No. Same params, same shape, same 5 credits, same free 400s and free 404s.
Do you need pytrends to call a Google Trends API from Python?
No. One Google Trends API Python GET with x-api-key. pytrends is an unofficial library (pandas, last release Apr 2023); it is not a dependency, and this is not a wrapper around it.
Where is the Google Trends API documentation?
Google Trends endpoint docs for params and field maps. Try the same call in the explorer against production. The field map lives there — this post does not copy it.
Rerun any harvest row with your own key. A cache miss on explore or rising is 5 credits. A 400 or empty-interest 404 is 0. That is the whole Google Trends API Python path: two GETs, same 5 credits, same shape as this harvest.
Related posts
Google Trends API: Empty Searches Cost 0 Credits
Empty Google Trends API searches now return 404 with 0 credits charged. Live production curls cover Trends empties, News ranks, and app filter refusals.
Instagram API: About is back, 1 credit, named 404s
/v1/instagram/profile/about is back: United States, February 2012, 1 credit. Wrong Instagram API paths return did_you_mean at 0 credits. Checked 2026-09-08.
LinkedIn Post History API: Full Archive, 100/Page
LinkedIn post history API: 100/page at 5 credits each. Two no-cache calls matched published_at to the millisecond; limit=100 returned 97 posts and a cursor.
