pytrends was archived in April 2025, and scripts that use it often fail with 429 Too Many Requests. trendreq keeps the TrendReq interface for the common methods (see the table below), so most scripts only need a new import. The requests run on the CleanScrape Google Trends Actor on Apify, with proxies and retries on the server side.
# from pytrends.request import TrendReq # before
from trendreq import TrendReq # after
pytrends = TrendReq(hl="en-US", tz=360)
pytrends.build_payload(["iced coffee", "cold brew"], timeframe="today 12-m", geo="US")
df = pytrends.interest_over_time() iced coffee cold brew isPartial
date
2026-09-20 47 51 False
2026-09-27 42 49 False
2026-10-04 32 33 True
pip install trendreqThen set your Apify API token. A free Apify account includes $5 of usage a month. Copy the token from Apify Console > Settings > API & Integrations.
export APIFY_TOKEN=your_token # macOS / Linux
setx APIFY_TOKEN your_token # Windows (open a new terminal afterwards)You can also pass it in code with TrendReq(apify_token="..."). Keep the token out of shared notebooks and repositories.
| pytrends method | trendreq | Notes |
|---|---|---|
build_payload(kw_list, cat, timeframe, geo, gprop) |
Same | Up to 5 keywords. gprop (YouTube, News, Images, Shopping) is not supported yet. |
interest_over_time() |
Same shape | Date index (UTC), one int column per keyword, isPartial. |
interest_by_region(resolution, inc_low_vol, inc_geo_code) |
Same shape | COUNTRY, REGION, CITY and DMA (US metro areas). City rows also get latitude and longitude, so towns with the same name stay apart. With a country chosen, COUNTRY gives its regions, as pytrends does. |
related_queries() |
Same shape | {keyword: {"top": DataFrame, "rising": DataFrame}} with query and value. |
related_topics() |
Same shape | Google currently returns no related topics for automated requests (pytrends gets the same), so this gives None with a warning. |
trending_searches(pn) |
Same shape | pn can be a pytrends country name ("united_kingdom") or a code ("GB"). |
today_searches(pn) |
Same | A Series of today's trending searches. |
realtime_trending_searches(pn) |
Similar | Columns: title, approxTraffic, pubDate, relatedNews. |
suggestions(), categories(), top_charts() |
Not available | They raise NotImplementedError with an explanation. |
Exceptions keep pytrends' names: ResponseError and TooManyRequestsError (raised only if Google still limits the request after the server-side retries). retries= re-runs a rate-limited data type.
Time ranges work as in pytrends: "today 5-y", "today 12-m", "today 3-m", "now 7-d", "now 1-d", "all", or exact dates such as "2024-01-01 2024-06-30". Regions take codes such as "US", "US-CA" or "DE".
Settings that only made sense for direct requests (proxies, timeout, backoff_factor, requests_args) are accepted and ignored, so you don't need to change your constructor call.
One run for several data types. Each method call starts one Apify run. To collect several data types for the same keywords, call fetch() first. It saves the per-run start fee:
pytrends.build_payload(["bitcoin", "ethereum"], timeframe="today 5-y")
pytrends.fetch("interest_over_time", "related_queries", "interest_by_region")
over_time = pytrends.interest_over_time() # no new run
related = pytrends.related_queries() # no new runTrending searches with context. pytrends.trending_now("US") returns rank, approximate traffic, publish time and related news headlines.
Spending cap. TrendReq(max_charge_usd=0.50) stops any single run at 50 cents.
You pay Apify for the Actor's results, at the Actor's current price. At the base price that is $0.05 per run plus $0.003 per row, with discounts on paid Apify plans. Some examples at base prices:
| Job | Rows | Cost |
|---|---|---|
2 keywords, 12 months, weekly (interest_over_time) |
106 | about $0.37 |
1 keyword, US states (interest_by_region) |
51 | about $0.20 |
2 keywords, time series + states + related queries in one fetch() |
102 | about $0.36 |
| Today's trending searches for one country | 10 | about $0.08 |
The free $5 monthly credit covers roughly 15 to 60 typical calls.
Google's official Trends API is an alpha with access by application, and pytrends does not use it. pytrends sends requests from your own IP address, first to get a short-lived token and then to fetch each chart. Google limits how often one address can do that, so scripts that loop over keywords quickly hit 429 Too Many Requests. Waiting, rotating proxies by hand and lowering the request rate only helps for a while. trendreq moves those requests to Apify, where the Actor rotates residential proxies and retries for you.
- Values are relative interest from 0 to 100 within your comparison, the same as on the Google Trends website. They are not search counts.
- Results can differ slightly between runs, as they do on the website, because Google samples its data.
- Each method call is one Apify run and takes about 5 to 30 seconds. Use
fetch()to collect several data types at once. - Related topics are currently empty, because Google returns none for automated requests.
- Retries reduce rate-limit failures but cannot rule them out. If Google still limits a request, trendreq raises
TooManyRequestsErrorinstead of returning partial data.
python -m unittest discover -s testsThe tests run offline against real rows saved from the Actor, so they need no token.
trendreq is maintained by CleanScrape. It is not affiliated with Google or with the pytrends project. MIT licence.
Bugs and ideas: open an issue or email contact.cleanscrape@gmail.com.