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

Blogtwitter streaming api

Twitter (X) Streaming API — A Real-Time Developer Guide

By Michael Park4 min read

'Streaming' on Twitter (X) means receiving tweets as they're posted, in near-real-time, without polling on a schedule. Two practical delivery patterns exist in 2026: long-running HTTP stream (the classic model, still used by X official) and webhook-callback (the modern model, used by twitterapi.io).

This guide walks both patterns with runnable code, the honest cost per matched tweet, and the operational trade-offs that decide which fits your workload. Pricing references URL-cited to the providers.

01 — Section

Two delivery patterns for real-time tweets

Long-running HTTP stream (X official filtered_stream): your client opens an HTTP connection to /2/tweets/search/stream and holds it open. X pushes matched tweets down the connection as JSON-lines. You process each tweet as it arrives; you handle reconnection, back-pressure, and connection loss.

Webhook callback (twitterapi.io): you register a rule via /oapi/tweet_filter/add_rule and provide a callback URL. When matching tweets arrive, twitterapi.io POSTs them to your endpoint. No connection to hold open on your side. Standard HTTPS ingress handling.

Which fits which team: teams with existing streaming infrastructure (Kafka, connectors, streaming ETL) map naturally to the HTTP-stream pattern. Teams without that (most SaaS product teams) find webhooks operationally simpler — deploy an HTTPS endpoint, let it receive.

02 — Section

Path 1 — twitterapi.io webhook

Auth via X-API-Key. Register rules programmatically or via the dashboard. Rules use the same operator syntax as advanced_search (from:user, #hashtag, lang:en, boolean combinations).

Pricing per twitterapi.io/pricing: $0.00015 per matched tweet delivered to your webhook. A rule matching ~5,000 tweets/day = $0.75/day = ~$22/month for continuous coverage.

python
# Register a rule (one-time setup)
import os, requests

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

r = requests.post(
    f"{BASE}/oapi/tweet_filter/add_rule",
    headers=HEADERS,
    data={
        "tag": "ai-news",
        "value": '("artificial intelligence" OR "machine learning") min_faves:50 lang:en',
        "interval_seconds": 5,
    },
    timeout=15,
)
r.raise_for_status()
print(f"rule id: {r.json().get('rule_id')}")

# Webhook handler side (illustrative FastAPI):
#   from fastapi import FastAPI, Request
#   app = FastAPI()
#   @app.post("/twitter-callback")
#   async def receive_tweet(request: Request):
#       body = await request.json()
#       # body has: tag, tweet (full tweet object)
#       await store(body["tweet"])
#       return {"ok": True}
03 — Section

Path 2 — X official filtered_stream

Long-running HTTP stream via /2/tweets/search/stream. Register rules via /2/tweets/search/stream/rules. Bearer-token auth from X Developer Console.

Pricing per docs.x.com/x-api/getting-started/pricing: continuous streaming requires Pro tier and up. Basic tier does not include filtered_stream in the Pro-and-up feature set.

python
# pip install tweepy
import tweepy

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

# 1. Register a rule
rules = tweepy.StreamRule(
    value='("artificial intelligence" OR "machine learning") min_faves:50 lang:en',
    tag="ai-news",
)
client.add_rules(rules)

# 2. Open the stream (long-running)
class Stream(tweepy.StreamingClient):
    def on_tweet(self, tweet):
        print(f"received: {tweet.text[:80]}")

stream = Stream(bearer_token="YOUR_X_BEARER")
stream.filter()  # blocks and streams indefinitely
04 — Section

Side-by-side — 2 patterns for real-time

Per-tweet cost from each provider's published pricing.

Dimensiontwitterapi.io webhookX official filtered_stream
Delivery modelwebhook POSTlong-running HTTP stream
AuthX-API-Key headerBearer token via X Dev Console
Per-tweet cost$0.00015 (twitterapi.io/pricing)Pro tier subscription (docs.x.com)
Connection maintenancenone (your endpoint is called)your side (reconnect, back-pressure)
Setup frictionemail + API keyX Developer Console + Pro tier
Ops complexitylow (any HTTPS ingress)medium (streaming client + resilience)
Best forproduct / SaaS monitoring, small ops teamsteams with existing streaming infra

Two practical observations: (a) ~33× per-tweet cost ratio at scale + free webhook infrastructure = order-of-magnitude total cost delta; (b) the operational cost of maintaining a streaming connection (reconnect logic, back-pressure, ordering) is real engineering time that webhooks eliminate.

05 — Section

Common streaming workloads

Brand-mention real-time alerts: rule = "YourBrand" -is:retweet, webhook posts to Slack/PagerDuty/notification service. Cost ~$5-15/month for typical brand volumes.

Trending-keyword aggregator: rule = broad keyword set, webhook lands in Postgres, dashboards render live counts. Cost tracks matched-tweet volume.

Crisis / PR monitoring: rule includes negative-sentiment keywords, webhook fires alerts on velocity spikes. Cost bursts during actual crisis but is otherwise low.

Real-time news aggregator: rule matches breaking-news accounts + keywords, webhook fans out to CDN cache + push-notification service.

06 — Section

Picking the path

Small product / SaaS team: twitterapi.io webhook. Zero streaming infrastructure + lowest per-tweet cost + fastest time-to-first-tweet.

Already on X Pro tier for other workloads: X filtered_stream. Marginal cost rides on existing subscription; team likely already has stream-client patterns.

Enterprise SLA + guaranteed real-time: X Enterprise (proper firehose or higher-tier filtered_stream). See /blog/twitter-firehose-api-developer-guide for the enterprise-tier tradeoffs.

Most teams building product-adjacent real-time features land at twitterapi.io because operational simplicity + cost economics dominate the decision.

python
# Practical example: webhook-based brand monitoring with Slack fan-out.
import os, requests

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

# 1. Register the rule (one-time setup)
def register_brand_monitor(brand: str, callback_url: str):
    r = requests.post(
        f"{BASE}/oapi/tweet_filter/add_rule",
        headers=HEADERS,
        data={
            "tag": f"brand-monitor-{brand}",
            "value": f'"{brand}" -is:retweet lang:en',
            "interval_seconds": 5,
        },
        timeout=15,
    )
    r.raise_for_status()
    return r.json()

# 2. Webhook handler (FastAPI illustrative)
from fastapi import FastAPI, Request
app = FastAPI()

@app.post("/twitter-callback")
async def receive(request: Request):
    body = await request.json()
    tweet = body["tweet"]
    # Fan out to Slack
    requests.post(
        os.environ["SLACK_WEBHOOK"],
        json={"text": f"@{tweet['author']['userName']}: {tweet['text']}"},
    )
    return {"ok": True}

# 3. One-time rule registration
# register_brand_monitor("twitterapi.io", "https://your-app.com/twitter-callback")

# Cost per twitterapi.io/pricing:
#   ~500 mentions/day × $0.00015 = $0.075/day = ~$2.25/month for continuous coverage
# X Pro tier equivalent: ~$100/month base + per-tweet at Pro rates
07 — Questions

Questions readers ask

Do I have to maintain a streaming connection for real-time?

Not with the webhook pattern — twitterapi.io pushes matched tweets to your HTTPS endpoint as they arrive. Standard ingress handling, no long-running connection to manage. If you use X official's filtered_stream, yes — you hold open an HTTP stream and handle reconnection on your side.

What happens if my webhook endpoint is down when a tweet arrives?

twitterapi.io retries per its published retry policy. For guaranteed delivery, run your webhook behind a queue (SQS / Kafka / Redis) so the receiving endpoint's job is enqueue-and-ack fast; async workers do the real processing.

Can I get replay / catch-up for tweets I missed during downtime?

The streaming APIs are near-real-time delivery only; missed tweets during your downtime aren't re-sent. For catch-up, run a backfill query via /twitter/tweet/advanced_search with a since: timestamp matching your last-known-good moment. Combine streaming for real-time + polling for backfill.

How do I test my webhook locally?

Use ngrok or tunnelmole to expose your local dev server to a public URL, register that URL as the callback in twitterapi.io. For X official filtered_stream, run the stream client locally + iterate on message handling.

What's the latency from tweet-posted to my callback?

Both providers advertise near-real-time (seconds range). twitterapi.io's interval_seconds rule parameter controls the internal polling / delivery cadence — 5s is a reasonable default. X official streams push as X's ingestion allows. Absolute latency depends on X's own post-to-index latency + provider's forwarding.

Can I rate-limit / batch tweets before they hit my webhook?

twitterapi.io delivers as they match. For rate-limiting on your side, add a queue between webhook receive + real processing. For batching, aggregate at your queue-consumer layer — the API delivery model is per-tweet.

08 — 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) Streaming API — Real-Time Guide | TwitterAPI.io