twitterapi.io is an independent third-party service. Not affiliated with X Corp.

Blogtwitter trends api

Twitter (X) Trends API — A Developer's Tutorial

By Sarah Wong5 min read

Twitter (X) trends are the platform's real-time snapshot of what topics are gaining traction in a given place. Building on top of them — trend dashboards, notification services for marketers, content-planning tools that surface hot topics — starts with a simple decision: which trends API to use.

This tutorial walks the two paths (twitterapi.io + X official), the WOEID place-code system that both use, and the honest cost math that decides which path is right for your workload. Pricing references URL-cited to each provider.

01 — Section

Twitter's trends are computed per place (a WOEID — Where On Earth ID). The global-worldwide WOEID is 1; individual countries and cities have their own IDs (e.g., United States = 23424977, London = 44418, Tokyo = 1118370).

The trending algorithm considers both raw volume of tweets containing a topic and rate-of-change (velocity). A topic doesn't have to be the highest-volume of the moment — it has to be growing fast relative to its baseline. That's why breaking news + niche moments both appear alongside sustained-high-volume ongoing conversations.

The refresh cadence on both API paths is ~5-15 minutes. Polling more often than every 5 minutes gets you the same list — you pay per call but the underlying data hasn't changed.

02 — Section

Auth via X-API-Key header. Pass the WOEID as the woeid parameter. Returns a JSON list of trending topics with the topic name, tweet volume (if known), tweet URL, and promoted flag.

Pricing per twitterapi.io/pricing: $0.00018 per call (billed as a profile-level lookup). At 1 poll per 10 minutes = 144 polls/day = $0.026/day (~$0.80/month per WOEID watched).

python
import os, requests

HEADERS = {"X-API-Key": os.environ["TWITTERAPI_IO_KEY"]}
BASE = "https://api.twitterapi.io"

def get_trends(woeid: int = 1):
    """Fetch trending topics for a place. woeid=1 = global."""
    r = requests.get(
        f"{BASE}/twitter/trends",
        headers=HEADERS, params={"woeid": woeid}, timeout=10,
    )
    r.raise_for_status()
    return r.json()

# Global trends
for t in get_trends(1).get("trends", [])[:10]:
    vol = t.get("tweet_volume") or "n/a"
    print(f"  {t['name']} — {vol} tweets")

# United States trends (WOEID 23424977)
for t in get_trends(23424977).get("trends", [])[:10]:
    print(f"  US: {t['name']}")
03 — Section

X's official endpoint. Same WOEID system, same shape response. Bearer-token auth via the X Developer Console.

Pricing per docs.x.com/x-api/getting-started/pricing: $0.010 per call. At 1 poll per 10 minutes = 144 polls/day = $1.44/day = ~$43/month per WOEID watched. Cost ratio to twitterapi.io: ~55×.

python
# pip install tweepy
import tweepy

client = tweepy.Client(bearer_token="YOUR_X_BEARER")

def get_trends_x(woeid: int = 1):
    resp = client.get_place_trends(id=woeid)
    return resp.data or []

for t in get_trends_x(1)[:10]:
    print(f"  {t['name']} — {t.get('tweet_volume', 'n/a')} tweets")
04 — Section

Common WOEID codes worth knowing

Global: 1

Country-level: United States 23424977 · United Kingdom 23424975 · Canada 23424775 · Australia 23424748 · India 23424848 · Japan 23424856 · Germany 23424829 · France 23424819 · Brazil 23424768

City-level (large cities): New York City 2459115 · Los Angeles 2442047 · London 44418 · Paris 615702 · Tokyo 1118370 · Berlin 638242 · Sydney 1105779 · São Paulo 455827

The full WOEID hierarchy is published historically by Yahoo (Twitter inherited the taxonomy). Not every possible place has trends — smaller cities may return empty or an error. Start with country-level for reliable data + granularize down as needed.

05 — Section

Costs derived from each provider's published pricing page. Refresh cadence is native to the trending algorithm and identical across both providers.

Dimensiontwitterapi.io /twitter/trendsX official trends/place
AuthX-API-Key headerBearer token via X Developer Console
WOEID coveragefullfull
Per-call cost$0.00018 (twitterapi.io/pricing)$0.010 (docs.x.com)
Refresh cadence~5-15 min (native)~5-15 min (native)
Cost @ 10-min poll~$0.80/month/WOEID~$43/month/WOEID
Setup frictionemail + API keyX Developer Console + bearer
Best fordashboards, notification products, multi-WOEID workflowsteams already on X Developer bill

Two practical observations: (a) 55× cost ratio at scale (multi-WOEID + frequent poll) compounds quickly; (b) polling faster than 5-min refresh is money burned — the underlying data isn't newer.

06 — Section

Real-time trend dashboard for marketing / brand team: poll global + relevant country WOEIDs every 10 min, render as a live-updating table. Cost via twitterapi.io: ~$3-5/month for 4-5 WOEIDs.

Trend-based content-recommendation for creators / publishers: same polling pattern + filter to trends matching your topic area (e.g., tech-adjacent, entertainment, sports). Use trend name + tweet volume as ranking signals for content ideas.

Notification service — 'ping me when a keyword trends near me': cross-reference the trend list against user-supplied keyword watchlists; push notifications when a match hits a threshold volume.

Historical trend archival: snapshot the trend list every N minutes to your storage layer; query later for time-series analysis (which topics trended when, for how long).

07 — Section

Picking the path

Building a product or dashboard consuming trends: twitterapi.io. 55× cheaper per call + no Developer Console gating.

Already on X Developer bill for other workloads: X official — marginal cost rides on the same auth.

One-off script for personal use: either works cheaply enough that the choice is auth convenience.

python
# Practical example: multi-WOEID trend snapshot for a marketing dashboard.
import os, requests, json
from datetime import datetime, timezone
from pathlib import Path

HEADERS = {"X-API-Key": os.environ["TWITTERAPI_IO_KEY"]}
BASE = "https://api.twitterapi.io"

WATCHED_WOEIDS = {
    "global": 1,
    "us": 23424977,
    "uk": 23424975,
    "japan": 23424856,
    "brazil": 23424768,
}

def poll_trends(out_path: str = "trends_snapshot.jsonl"):
    snapshot = {
        "captured_at": datetime.now(timezone.utc).isoformat(),
        "places": {},
    }
    for label, woeid in WATCHED_WOEIDS.items():
        r = requests.get(
            f"{BASE}/twitter/trends",
            headers=HEADERS, params={"woeid": woeid}, timeout=10,
        )
        r.raise_for_status()
        snapshot["places"][label] = r.json().get("trends", [])[:20]
    Path(out_path).parent.mkdir(exist_ok=True)
    with open(out_path, "a") as f:
        f.write(json.dumps(snapshot) + "\n")
    return snapshot

snap = poll_trends()
for label, trends in snap["places"].items():
    print(f"{label}: {trends[0]['name']} (top)")

# Cost framing per twitterapi.io/pricing:
#   5 WOEIDs × 1 call per 10-min poll × 144 polls/day = 720 calls/day
#   720 × $0.00018 = $0.13/day = ~$3.90/month for a global marketing dashboard
# X official equivalent: $0.13 × 55 = ~$7.15/day = ~$215/month — 55x delta
08 — Questions

Questions readers ask

How often does the trends list actually change?

Every 5-15 minutes on both API paths. That's the native refresh cadence of the underlying trending algorithm. Polling faster than 5 min returns the same list until the next algorithmic refresh — you pay per call but the data hasn't moved.

Why do some trends show tweet volume and others don't?

Trend velocity matters more than raw volume in the algorithm. Some trends are gaining fast but haven't accumulated enough absolute tweets for a stable volume estimate — the API returns null in that case. Later, once volume stabilizes, the number appears.

Can I get trends for a specific city that isn't in the standard WOEID list?

Only cities with sufficient tweet volume have their own WOEID. Smaller cities roll up to their country-level WOEID for trend computation. If a WOEID returns empty consistently, the place doesn't have enough activity for trend-level surfacing.

Is the trends data commercially usable?

Public trend names + tweet volumes are broadly usable in commercial products (dashboards, alerts, content tools) per both providers' terms. Watch specifics of downstream use (resale of the trend list itself as a data product, model training) — review docs.x.com developer terms + twitterapi.io terms for your case.

What about the 'trending near me' feature — can I get personalized trends via API?

The API paths above return place-based trends (all viewers at that place see the same list), not user-personalized trends. X's frontend applies additional per-user personalization that isn't exposed via public API. For 'near me' functionality, use the geo-nearest WOEID; you won't get the exact per-user personalized view.

How do I map a lat/lon to the nearest WOEID?

Yahoo's original geo-planetary WOEID service was retired years ago. Community-maintained JSON files of the WOEID hierarchy circulate on GitHub; for programmatic mapping, keep a static WOEID → lat/lon table for the places you care about and do nearest-neighbor lookups client-side.

09 — Further reading

Continue

Sources & further reading
More from this series
Build it

Stop reading. Start building.

Starter credits cover real testing on real data. Google sign-in, no card, no application queue.

Get an API key
    Twitter (X) Trends API — Developer Tutorial | TwitterAPI.io