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

Blogtwitter api search hashtags

Twitter (X) API — Search Hashtags Tutorial

By Sarah Wong4 min read

Searching hashtags via API is one of the simplest advanced-search patterns and one of the most common. Brand campaigns, event tracking, trend research, community-management workflows — all of them start with 'get me every tweet using #tag'.

This tutorial walks the exact API call with runnable Python, the useful filter combinations, and the honest cost per provider. Pricing references URL-cited.

01 — Section

The basic hashtag search — three parameters

Query: #hashtag — that's the whole operator. Case-insensitive. Combine with other operators separated by spaces (AND is implicit).

Language filter (optional but useful): #tag lang:en — English-only. Prevents your English-language monitor from being drowned by, say, K-pop fan chatter.

Engagement floor (optional but useful): #tag min_faves:50 — only tweets with 50+ likes. Filters out spam / low-signal noise.

Date range (optional): #tag since:2024-01-01 until:2024-12-31 — bounded window. Note until: is UTC-exclusive; add a day for inclusive semantics.

02 — Section

Auth via X-API-Key. Cursor pagination to 100K+ results per query.

Pricing per twitterapi.io/pricing: $0.00015 per returned tweet. A hashtag pulling 500 tweets/day = $0.075/day = ~$2.25/month for continuous monitoring.

python
import os, requests

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

def search_hashtag(tag: str, lang: str = "en", min_faves: int = 0, max_pages: int = 10):
    """Search tweets containing #tag with optional filters."""
    query = f"#{tag}"
    if lang: query += f" lang:{lang}"
    if min_faves > 0: query += f" min_faves:{min_faves}"

    tweets, cursor = [], None
    for _ in range(max_pages):
        params = {"query": query}
        if cursor: params["cursor"] = cursor
        r = requests.get(
            f"{BASE}/twitter/tweet/advanced_search",
            headers=HEADERS, params=params, timeout=15,
        )
        r.raise_for_status()
        resp = r.json()
        tweets.extend(resp.get("tweets", []))
        cursor = resp.get("next_cursor")
        if not cursor: break
    return tweets

# Example: high-signal #machinelearning tweets
for t in search_hashtag("machinelearning", lang="en", min_faves=100)[:5]:
    print(f"  @{t.get('author', {}).get('userName')}: {t.get('text', '')[:80]}")
    print(f"    -> {t.get('public_metrics', {}).get('like_count')} likes")
03 — Section

Same query syntax. Auth via bearer token from X Developer Console. Recent-search covers last 7 days; older date ranges require Enterprise /2/tweets/search/all.

Pricing per docs.x.com/x-api/getting-started/pricing: $0.005 per post read.

python
# pip install tweepy
import tweepy

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

def search_hashtag_x(tag: str, min_faves: int = 0, max_results: int = 100):
    query = f"#{tag}"
    if min_faves > 0: query += f" min_faves:{min_faves}"
    tweets = []
    for page in tweepy.Paginator(
        client.search_recent_tweets, query=query,
        tweet_fields=["public_metrics", "created_at", "author_id"],
        max_results=max_results, limit=10,
    ):
        tweets.extend(page.data or [])
    return tweets

for t in search_hashtag_x("machinelearning", min_faves=100)[:5]:
    print(f"  {t.public_metrics['like_count']} likes: {t.text[:80]}")
04 — Section

Common hashtag-search patterns

Live campaign monitoring — poll #your-campaign-tag every 5 min, alert on volume spikes or negative-sentiment matches.

Event tracking#EventName since:CONFERENCE_START until:CONFERENCE_END for a full conference archive. Perfect for post-event content curation.

Trend research#tag since:MONTH-AGO min_faves:1000 to find breakthrough moments; useful for content-marketing hindsight.

Community management#your-community-tag -is:retweet for original-post tracking (excluding amplification retweets).

Cross-hashtag intersection#tag1 #tag2 for tweets using both. Useful for niche-community mapping.

Exclusion#brand -#brand-competitor to filter out competitive-mention noise.

05 — Section

Costs derived from each provider's published pricing pages.

Dimensiontwitterapi.io advanced_searchX official recent-search
Query syntax#hashtag + operators#hashtag + operators (same)
Date rangeFull archive (since: / until: back years)Last 7 days only (basic tier)
Per-tweet cost$0.00015 (twitterapi.io/pricing)$0.005 (docs.x.com)
AuthX-API-Key headerBearer token from X Dev Console
PaginationCursor to 100K+ resultsCursor with tier-based limits
Best forHistorical + high-volume monitoring productsRecent lookups on existing X bill

Two practical observations: (a) the 33× per-call cost ratio makes twitterapi.io the default for any sustained hashtag-monitoring product; (b) the full-archive depth matters for retrospective research (looking back at past campaigns or events).

06 — Section

What can go wrong — three gotchas

Case sensitivity is not what you'd expect: hashtags are matched case-insensitively, so #AI and #ai and #Ai all match. Don't run three separate queries thinking they'll return different results.

Special characters break silently: #c++ and #f# don't work as hashtags on X — the platform strips at the special character. If you're monitoring a tech-adjacent hashtag with symbols, monitor the plain-alphanumeric substring.

Non-Latin scripts are supported but you need proper URL encoding: #人工知能 works but must be URL-encoded in the query parameter. Most HTTP clients handle this automatically; if you see empty results for a non-Latin hashtag, check your client's encoding.

07 — Section

Picking the path

Building a hashtag-monitoring product / campaign dashboard → twitterapi.io. Cheap per call + full-archive depth for historical context.

One-off recent search of a hashtag → either works; X official if already authenticated.

Long-tail archive research on historical hashtags → twitterapi.io (full-archive) or X Enterprise (also full-archive but enterprise-priced).

python
# Practical example: continuous hashtag monitor with rolling window + alert threshold.
import os, requests, json
from datetime import datetime, timezone
from collections import Counter

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

TAG = "YourBrand"
MIN_FAVES = 5
SPIKE_THRESHOLD = 100  # tweets in last hour to trigger alert

def monitor_tag_last_hour(tag: str):
    tweets, cursor = [], None
    for _ in range(10):
        params = {"query": f"#{tag} within_time:1h lang:en"}
        if cursor: params["cursor"] = cursor
        r = requests.get(f"{BASE}/twitter/tweet/advanced_search", headers=HEADERS, params=params, timeout=15)
        r.raise_for_status()
        resp = r.json()
        tweets.extend(resp.get("tweets", []))
        cursor = resp.get("next_cursor")
        if not cursor: break

    if len(tweets) >= SPIKE_THRESHOLD:
        # Alert: volume spike
        top_authors = Counter(t.get("author", {}).get("userName", "") for t in tweets).most_common(5)
        print(f"🚨 #{tag} SPIKE — {len(tweets)} tweets in last hour")
        print(f"   top voices: {[a for a, _ in top_authors]}")
    else:
        print(f"#{tag} normal: {len(tweets)} tweets in last hour")
    return tweets

result = monitor_tag_last_hour(TAG)
# Cost per twitterapi.io/pricing:
#   Hourly poll × 24h × $0.00015 × ~50 tweets/poll = $0.18/day
#   ~$5.40/month for continuous hashtag monitoring with alert threshold
#   X official equivalent: ~$180/month (33x)
08 — Questions

Questions readers ask

Can I search multiple hashtags at once?

Yes — #tag1 #tag2 finds tweets containing BOTH (implicit AND). Use #tag1 OR #tag2 for either. Group with parentheses: (#a OR #b) #c for boolean precedence. Same operator set as X's advanced-search UI.

How do I get only original tweets, not retweets?

Add -is:retweet to your query: #tag lang:en -is:retweet. For only-retweets: #tag is:retweet. Both operators work across twitterapi.io and X official APIs.

What about tweets that just mention the hashtag as text but don't tag it?

The #hashtag operator matches only when the platform's parser identified the string as a hashtag entity (linked, part of tweet metadata). Plain text mentions of 'the hashtag #tag' where the # was escaped or the entity wasn't parsed don't match. To include mention-of-hashtag prose, add the plain word too: #tag OR "tag".

Can I get engagement metrics along with the tweets?

Yes — the response includes public_metrics per tweet (like_count, retweet_count, reply_count, quote_count). Filter by these client-side or use the min_faves: / min_retweets: / min_replies: operators server-side.

How do I follow a hashtag in real time (not polled)?

Use twitterapi.io's /oapi/tweet_filter/add_rule webhook: register #hashtag as the rule value, provide a callback URL. Matching tweets get pushed to your endpoint in near-real-time. See /blog/twitter-firehose-api-developer-guide for the streaming pattern.

Are hashtag counts the same as trending 'tweet volume' numbers?

Related but not identical. Trending tweet-volume is the algorithm's estimate for the trending list; hashtag search returns actual tweet counts you can pull. Search counts are more precise; trending volumes are indicative + cover a slightly different window.

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) API Search Hashtags — Tutorial | TwitterAPI.io