Twitter (X) Trends API in Python — Three Paths, One Tutorial
Twitter (X) trends — the rotating list of trending topics for a region — are a foundational data point for content monitoring, news triage, and creator workflows. In 2026 you have three practical Python paths to fetch them.
This tutorial walks all three: twitterapi.io's REST endpoint, X's own trends fetch via the official xdk and tweepy, and Apify's third-party scraper. Each section has runnable Python code, the call shape, and the per-call cost as published by the provider. The pricing math is reduced from the cited rates so you can re-derive it.
What 'trends' actually returns
X exposes trends per geographic region (a 'place' under the older WOEID model, or a place identifier under the modern surface). A trends fetch returns a list of trending phrases or hashtags, each typically with a tweet-volume indicator and a position rank.
Trends rotate constantly — the canonical recommendation from older Tweepy docs (still operationally sound) is to poll no faster than every 5 minutes per place. Most production users poll every 5–15 minutes and cache the result, because at typical content-monitoring use cases there's no value in finer-grained polling than the platform itself updates.
Path 1 — twitterapi.io `/twitter/trends`
twitterapi.io exposes a REST endpoint at https://api.twitterapi.io/twitter/trends that returns the current trends as JSON. Authentication is an X-API-Key header; no OAuth flow, no developer-review onboarding. Pricing follows twitterapi.io's general per-call model (twitterapi.io/pricing).
Pick this path when you want the lowest friction to first result and you're optimizing for per-call cost on read-heavy monitoring workloads.
# pip install requests
import os, requests, time
HEADERS = {"X-API-Key": os.environ["TWITTERAPI_IO_KEY"]}
BASE = "https://api.twitterapi.io"
def fetch_trends(woeid: int = 1) -> list[dict]:
"""woeid=1 is worldwide; per-country WOEIDs documented at twitterapi.io/docs."""
r = requests.get(
f"{BASE}/twitter/trends",
headers=HEADERS,
params={"woeid": woeid},
timeout=10,
)
r.raise_for_status()
return r.json().get("data", [])
# Poll every 5 min — trends update at roughly that cadence, faster polling is waste
while True:
trends = fetch_trends(1)
for t in trends[:10]:
print(t.get("name"), t.get("tweet_volume"))
time.sleep(300)
Path 2 — X official via xdk / tweepy
X's docs.x.com publishes a trends surface for code; both xdk (X's official Python SDK) and Tweepy wrap it. Pricing per docs.x.com/x-api/getting-started/pricing is $0.010 per trends fetch (in the "Trends" line of the per-resource read table), deduplicated within a 24-hour UTC window — refetching the same place within the day is one charge.
Pick this when you're already paying X for credits (you write posts, you read profiles), so the marginal trends cost rides on the same auth and same bill.
Note on Tweepy: older tutorials show API.trends_place(woeid) against the v1.1 surface. v1.1 is being progressively retired; the modern equivalents under v2 or the new consumption-based surface are the path to write against — verify the endpoint name in current docs.tweepy.org before relying on a code snippet.
# pip install xdk
from xdk import XDK
client = XDK(bearer_token="YOUR_X_BEARER")
# Read trends for a specific place — billed $0.010 per request, 24h UTC dedup
trends = client.trends.by_place(woeid=1) # 1 = worldwide
for t in trends.data:
print(t.name, t.tweet_volume)
# Tweepy equivalent (v2 path):
# import tweepy
# client = tweepy.Client(bearer_token="YOUR_X_BEARER")
# # Use the trends method on the v2 client per current docs.tweepy.org
Path 3 — Apify Twitter Trends Scraper (actor model)
Apify exposes a Twitter Trends Scraper actor that fetches trends per region. The model differs: rather than a REST endpoint that returns immediately, you start an actor run (a containerized job) with input parameters, then either poll for completion or use Apify's webhook on finish.
Pricing per apify.com/pricing is two-axis: per-result cost (extracted records) plus actor runtime (compute-units used during the run). Exact per-actor numbers vary by which scraper actor you pick — verify on the actor's own pricing page before committing to this path at volume.
Pick Apify when you want a job-and-webhook pattern that fits an event-driven architecture, or when you want a scraper that handles its own platform-fingerprint problem. Skip Apify when you want a low-latency, low-per-call-cost REST surface — twitterapi.io's surface is closer to that pattern.
# pip install apify-client
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
# Start the trends scraper actor (replace actor ID with the current one
# from apify.com/store — actor IDs change)
run_input = {"regions": ["worldwide", "united_states"]}
run = client.actor("scrape-creators/twitter-trends-scraper").call(run_input=run_input)
# Pull results when the actor finishes
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)
Side-by-side comparison — 4 dimensions for trend fetches
Same job (fetch trends for a place, poll every 5 min) framed across the three paths. Numbers are derived from cited pricing pages; sub-second-latency comparison is an operational judgment based on REST vs actor-run patterns.
A poll every 5 minutes is 288 fetches/day per place. Multiply by your tracked places (worldwide + N countries + N cities). The cost curve flattens fastest on twitterapi.io's per-call rate; X official is the natural pick if you're already on the X bill for other reasons; Apify is the natural pick if you've architected around actors + webhooks.
Caching + polling cadence
Don't poll faster than the platform updates. Trends move on the order of every few minutes — polling every 30 seconds buys nothing except 10× the bill. A 5-minute or 15-minute cache covers most monitoring use cases.
If you're triggering on a new entry in the trends list (alerting, content-trigger workflows), set up the polling loop to compare the new list against the cached one and act only on the delta. This pattern also reduces downstream noise — you fire one alert per genuinely new trend, not 100 alerts because the same trend kept being trending.
Picking a path — the decision rule
Reading trends at any meaningful volume on a per-call budget? → twitterapi.io. The cost per call is low and the integration is a single HTTPS request.
Already on the X bill for other reasons (you write posts, you read profiles via xdk / tweepy)? → use X's own trends fetch; the marginal cost is small and the auth is unified.
Building an event-driven scrape pipeline with webhooks? → Apify fits that architecture, with the trade-off being higher cost per fetch and longer time-to-result.
Most teams pick one path and stick. The exception is teams that do both write (X auth) and read at scale (twitterapi.io) — for them, calling X for trends keeps the trends bill on the same X surface as the writes.
# Side-by-side: same job (fetch worldwide trends), two paths, two prices.
import os, requests
from xdk import XDK
TAPI_KEY = os.environ["TWITTERAPI_IO_KEY"]
X_BEARER = os.environ["X_BEARER"]
def trends_twitterapi_io(woeid: int = 1):
"""twitterapi.io — pay per twitterapi.io/pricing."""
r = requests.get(
"https://api.twitterapi.io/twitter/trends",
headers={"X-API-Key": TAPI_KEY},
params={"woeid": woeid},
timeout=10,
)
r.raise_for_status()
return r.json().get("data", [])
def trends_x_official(woeid: int = 1):
"""X official via xdk — billed $0.010/req per docs.x.com/x-api/getting-started/pricing."""
client = XDK(bearer_token=X_BEARER)
return client.trends.by_place(woeid=woeid).data
# Cost framing (math from cited pricing pages):
# Polling worldwide trends every 5 min = 288 fetches/day.
# X official: 288 * $0.010 = $2.88/day (~$86/mo per place).
# twitterapi.io: same number of fetches at twitterapi.io/pricing rate is materially lower.
# Multiply by N tracked places. Read the live pricing pages before committing.Questions readers ask
What is the WOEID for worldwide trends?
WOEID 1 is the worldwide identifier in the legacy place ID system that most trend endpoints still accept. Per-country WOEIDs are documented in the same legacy table — search 'Yahoo WOEID list' for the canonical reference, or check the docs page of whichever provider you're using for their current geo identifier model.
How often should I poll for trends?
Every 5–15 minutes is sufficient for most use cases. Trends rotate on the order of minutes; polling every 30 seconds is mostly waste. Set a 5-minute baseline, increase to 15 minutes for non-time-critical workloads, decrease only if your downstream actually depends on faster signal.
Are trends available per-country only, or per-city too?
Per-country trends are first-class. Some providers also expose city-level trends for major metros. The exact set depends on the underlying X surface and the provider's coverage — check the docs page for the WOEID or place ID list the provider supports.
Can I get historical trends (yesterday's trending list)?
Live trends endpoints return current trends only. Historical trend data is a separate product on most providers — some include a trends archive, some don't. If history matters to your use case, build the archive yourself by polling every 5 min and storing each snapshot.
How does the 33× cost framing in the X-API guides translate to trends?
33× is the tweet-read ratio specifically ($0.005 / $0.00015, cited at docs.x.com pricing and twitterapi.io/pricing). The trends-read ratio depends on twitterapi.io's posted rate for trends calls versus X's $0.010 trends rate — see twitterapi.io/pricing for the current trends rate and divide. Don't take 33× as universal across all endpoints; it's a per-resource ratio.
What if I just want trends for one country and one cron-job poll?
Pick whichever path has the lowest setup tax for you. If you already have an X bearer token, use the X path — one HTTPS call inside cron. If you don't, twitterapi.io's signup-to-first-call path is the shortest. For one-off scripts, the cost difference is irrelevant.
Continue
- X API — pricing (docs.x.com, 2026 verified)
- twitterapi.io — pricing
- Tweepy documentation
- Apify — pricing
- Twitter (X) API — cluster hub
- Twitter Trends API — 2026 guide
- How to get Twitter trending topics via API
- Twitter (X) API in Python — complete guide
- twitterapi.io pricing
Stop reading. Start building.
Starter credits cover real testing on real data. Google sign-in, no card, no application queue.
Get an API key