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

Blogsocial media listening

Social Listening via X (Twitter) API — Build vs Buy

By Alex Chen6 min read

Social listening SaaS platforms — Brand24, Mention, Awario, Sprinklr, Meltwater — solve a real problem: continuously monitor brand + competitor + keyword mentions across social channels, alert on anomalies, aggregate sentiment. Their price ($200-500 per brand per month, or $2K+ for enterprise) reflects the operational overhead of running that monitoring stack.

For teams with in-house dev capacity and monitoring focused on X (Twitter) specifically, building the same core loop directly against the X API costs 5-100× less. Not because the SaaS platforms overcharge — they don't, given what they provide — but because you're skipping the multi-platform coverage, the pre-built dashboards, and the sentiment classifier they bundle in. If your workflow only needs X monitoring + custom alerts + integration into your existing stack, the build path is dramatically cheaper.

This page covers the build-vs-buy decision honestly: when SaaS wins, when API-build wins, and the exact API pattern + cost math if you go the build route.

01 — Section

Build vs buy — the honest tradeoff table

SaaS social listening bundles four things: (1) multi-platform monitoring, (2) pre-built dashboards + alerts, (3) sentiment / topic classification, (4) team collaboration features. If your workflow needs all four, buy is right — you're not saving money by rebuilding what a $500/mo tool ships out-of-box.

But if you need X-only + custom alert logic + integration into your existing analytics stack (Metabase / Grafana / Notion / Airtable / whatever), building on the X API skips 3 of the 4 SaaS layers and cuts cost 10-100×.

FactorSaaS (Brand24 / Mention / etc.)Build on twitterapi.io
Base cost$200-500/month per brand$5-50/month per brand (X data only)
Multi-platform (LinkedIn, IG, Reddit)✓ bundled✗ X only
Pre-built dashboardsYou build (Metabase / Notion)
Sentiment classifier✓ bundledYou wire (OpenAI / VADER / etc.)
Custom alert logiclimited to their DSL✓ full code control
Data ownershipescapes their DB, exports as CSV✓ your DB from day 1
Integration into your stackwebhooks + Zapier✓ direct API
Time to first alert~1 hour signup~1 day to build MVP
02 — Section

The 3-endpoint build pattern

The core social listening loop is: detect a mention → identify the author → measure reach → alert if criteria met. Three API calls cover it:

1. Detect/twitter/tweet/advanced_search with query lang:en -filter:retweets min_faves:5 since:. Runs every 5-15 min (poll cadence). Returns matching tweets with tweet ID, text, timestamp, engagement counts.

2. Enrich/twitter/user/info?userName= for each unique author in the batch. Returns follower_count, verified, bio. Enables filtering by author quality (e.g. skip low-follower spam).

3. Reach — sum of followers_count across all matching authors = brand reach for that poll cycle. Or use engagement (favorite_count + retweet_count) as engagement proxy.

Alert — if any (a) volume-per-hour spikes 3× baseline, (b) any single tweet accumulates >100 engagement in first 15min (viral signal), (c) any tweet from a specific author (competitor CEO, journalist watchlist) — fire your alert (Slack / email / PagerDuty).

03 — Section

Runnable — brand monitoring loop

One end-to-end script implementing the 3-endpoint pattern:

python
import os, requests, time, json
from pathlib import Path
from collections import defaultdict
from datetime import datetime, timezone, timedelta

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

BRAND = "stripe"
COMPETITORS = ["paypal", "square", "adyen"]
EXCLUDES = " ".join(f"-{c}" for c in COMPETITORS)
STATE_FILE = Path(f".state/{BRAND}_seen.json")
STATE_FILE.parent.mkdir(exist_ok=True)

def load_seen() -> set:
    return set(json.loads(STATE_FILE.read_text())) if STATE_FILE.exists() else set()

def save_seen(s: set):
    STATE_FILE.write_text(json.dumps(sorted(s)[-500:]))

def poll_once():
    since = (datetime.now(timezone.utc) - timedelta(minutes=30)).strftime("%Y-%m-%d")
    query = f"{BRAND} {EXCLUDES} lang:en -filter:retweets min_faves:5 since:{since}"
    r = requests.get(f"{BASE}/twitter/tweet/advanced_search", headers=HEADERS, params={"query": query}, timeout=15)
    r.raise_for_status()
    tweets = r.json().get("tweets", [])

    seen = load_seen()
    new_tweets = [t for t in tweets if t["id"] not in seen]

    if new_tweets:
        # Reach proxy: sum followers of all new-mention authors
        reach = sum((t.get("author", {}).get("followers_count") or 0) for t in new_tweets)
        engagement = sum(t.get("favorite_count", 0) + t.get("retweet_count", 0) for t in new_tweets)
        print(f"  {len(new_tweets)} new · reach {reach:,} · engagement {engagement:,}")

        # Alert criteria: high-reach single mention OR volume spike
        for t in new_tweets:
            author = t.get("author", {})
            if author.get("followers_count", 0) > 50_000:
                print(f"  \U0001F6A8 HIGH-REACH MENTION: @{author.get('userName')} ({author.get('followers_count'):,} followers): {t.get('text', '')[:120]}")
            if t.get("favorite_count", 0) + t.get("retweet_count", 0) > 100:
                print(f"  \U0001F525 VIRAL: {t.get('favorite_count')}\u2764 + {t.get('retweet_count')}\U0001F501: {t.get('text', '')[:120]}")

        seen.update(t["id"] for t in new_tweets)
        save_seen(seen)

while True:
    try:
        poll_once()
    except Exception as e:
        print(f"  ERROR: {e}")
    time.sleep(600)  # 10-min poll · adjust per your alert latency needs

# Cost per twitterapi.io/pricing:
#   ~50-200 tweets/poll x 144 polls/day = ~10-30K tweets/day = ~$1.50-4.50/day = ~$45-135/month per brand
04 — Section

Cost math at 4 monitoring volumes

Monitoring workloadEst. tweets/motwitterapi.io ($0.00015)Brand24 / Mention (SaaS)Delta
1 brand, low-volume (5K mentions/mo)5,000~$0.75~$200/mo267× cheaper
1 brand, mid-volume (50K mentions/mo)50,000~$7.50~$200/mo27× cheaper
5 brands, mid-volume250,000~$37.50~$500-1,000/mo13-27× cheaper
Enterprise 20 brands + 30 hashtags5,000,000~$750/mo$5,000-15,000/mo7-20× cheaper

Two observations: (a) at any volume the API-build wins on data cost; (b) SaaS pricing doesn't scale linearly with volume — they charge per-brand seat, so your delta stays large even at small volumes.

But: the SaaS bundles the dashboard + sentiment + alerts. Build-cost analysis must include eng time to build those layers. Rough parity: build wins if you already have 1 engineer + BI stack + volume >30K mentions/mo.

05 — Section

When to buy the SaaS (honest)

Multi-platform mandatory: You need LinkedIn + Instagram + Reddit + TikTok + X in one dashboard. Building all of that yourself against 5 different APIs is 5-10× the engineering time — the SaaS pricing looks cheap in comparison.

No engineering capacity: 5-person marketing team, no dev support, need it working today. Signup + import brand list in 1 hour vs 1 week to build MVP.

Regulated / compliance-sensitive: Some SaaS have SOC2 / GDPR / retention guarantees you'd otherwise implement in-house.

Turnkey sentiment / topic classification: The SaaS has trained sentiment classifiers per language + industry. Building your own is a project — either use OpenAI (add $0.01-0.05 per classified tweet) or accept lower quality VADER-style rule-based.

Cross-team collaboration UI: Marketers assigning mentions to different responders, tracking response SLA, generating shareable reports for exec review. SaaS ships this; you'd rebuild in Notion or similar.

06 — Section

When to build on twitterapi.io (honest)

X-only workflow: You only care about X (Twitter). 80%+ of dev-focused brands (SaaS, DevTools, crypto, APIs, cloud infra) live primarily on X. Skip the multi-platform tax you'd pay to SaaS.

Existing analytics stack: Data goes into your Metabase / Grafana / Looker / Notion / Airtable already. Adding X mentions as another data source in the same stack is 1 dev-day.

Custom alert logic: 'Alert only if a @ mentions our brand negatively' — that's your rule, not a rule any SaaS ships. Building on the API lets you write arbitrary alert logic.

Cost sensitivity at scale: SaaS pricing tends to hard-cap at their enterprise tier and forces per-brand-seat expansion. Direct-API cost scales cleanly with actual tweet volume.

Data ownership: Every tweet lives in your database from the moment it's polled. No 'export CSV' friction, no SaaS-vendor-lock-in.

07 — Section

Sibling tools + comparison

Brand24 — mid-market SaaS, $99-499/mo, decent X coverage + sentiment. Best for teams that want an easy start.

Mention — similar to Brand24, slightly stronger on real-time alerting.

Awario — cheaper alternative, $29-249/mo, thinner on features but usable.

Sprinklr — enterprise-grade, $1K-10K+/mo, best for large teams with formal social-response workflows.

Meltwater — enterprise media monitoring including press/news alongside social. $5K+/mo.

twitterapi.io + your build — $5-500/mo depending on volume. No SaaS bundling; pure data + code you own. See /pricing for per-call rates.

None of these are strictly better — they solve different points on the price/capability curve. Choose based on team + workflow + budget, not vendor prestige.

python
# Full workflow: 5-brand watchlist + Slack alerts + Notion database sink.
import os, requests, time, json
from datetime import datetime, timezone, timedelta
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor

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

WATCHLIST = ["stripe", "paypal", "square", "adyen", "checkout"]
STATE_DIR = Path(".state"); STATE_DIR.mkdir(exist_ok=True)

def seen_file(brand): return STATE_DIR / f"{brand}_seen.json"
def load_seen(brand):
    f = seen_file(brand)
    return set(json.loads(f.read_text())) if f.exists() else set()
def save_seen(brand, s):
    seen_file(brand).write_text(json.dumps(sorted(s)[-500:]))

def slack_alert(brand: str, tweet: dict, kind: str):
    a = tweet.get("author", {})
    txt = (tweet.get("text") or "").replace("\n", " ")[:200]
    url = f"https://twitter.com/{a.get('userName')}/status/{tweet.get('id')}"
    requests.post(SLACK_WEBHOOK, json={
        "text": f"{kind} on **{brand}**: @{a.get('userName')} ({a.get('followers_count'):,} followers)\n{txt}\n{url}"
    })

def poll_brand(brand: str) -> int:
    since = (datetime.now(timezone.utc) - timedelta(minutes=15)).strftime("%Y-%m-%d")
    query = f"{brand} lang:en -filter:retweets min_faves:5 since:{since}"
    r = requests.get(f"{BASE}/twitter/tweet/advanced_search", headers=HEADERS, params={"query": query}, timeout=15)
    r.raise_for_status()
    tweets = r.json().get("tweets", [])

    seen = load_seen(brand)
    new_tweets = [t for t in tweets if t["id"] not in seen]

    for t in new_tweets:
        a = t.get("author", {})
        if (a.get("followers_count") or 0) > 50_000:
            slack_alert(brand, t, "\U0001F6A8 HIGH-REACH MENTION")
        if t.get("favorite_count", 0) + t.get("retweet_count", 0) > 100:
            slack_alert(brand, t, "\U0001F525 VIRAL MENTION")

    seen.update(t["id"] for t in new_tweets)
    save_seen(brand, seen)
    return len(new_tweets)

while True:
    with ThreadPoolExecutor(max_workers=5) as ex:
        counts = list(ex.map(poll_brand, WATCHLIST))
    print(f"  {sum(counts)} new mentions across {len(WATCHLIST)} brands")
    time.sleep(900)  # 15-min poll cycle

# Cost estimate per twitterapi.io/pricing:
#   ~50-200 new tweets/brand/poll x 5 brands x 96 polls/day = ~24-96K tweets/day = ~$3.60-14.40/day = ~$108-432/month total
#   vs Brand24 for 5 brands = $500-1000/month (roughly 3-5x more)
08 — Questions

Questions readers ask

Which SaaS should I compare against as baseline?

For SMB: Brand24 ($99-499/mo) or Mention ($41-499/mo). For enterprise: Sprinklr ($1K+/mo) or Meltwater ($5K+/mo). All have decent X coverage; differences are in cross-platform depth + sentiment classifier + dashboard UX.

Can I build sentiment analysis on top of the API?

Yes — pipe the returned tweet text through your sentiment classifier of choice. Options: OpenAI (text-embedding-3-small for topic + gpt-4o-mini for sentiment, ~$0.01 per classified tweet), VADER (free but rule-based, English only), or Hugging Face open-source models (self-host).

How do I avoid missing tweets between polls?

Use since: operator + track already-seen tweet IDs (as the script does). Poll cadence of 10-15 minutes is standard for brand monitoring — tighter poll for crisis-response workflows. For sub-minute latency, use streaming API instead of polling.

Do I need X's Enterprise tier for historical data?

No — twitterapi.io exposes historical archive via /twitter/tweet/advanced_search with since:2020-01-01 until:2025-12-31 operators (or any window). Retroactive brand-mention research is 1 API call, no Enterprise contract needed.

What about GDPR / data-retention for stored mentions?

You control storage. Public tweet data is generally cleared for aggregation + research per X's Terms. For EU-user compliance, add a per-tweet TTL in your DB (typical: 90 days) or hash tweet IDs after aggregate metrics computed. If your workflow includes DM contents, that's a different compliance layer — public-tweet monitoring doesn't hit that.

How does this compare to X's official /2/tweets/search/all?

Same underlying data. X official /2/tweets/search/all (Full-Archive) is Enterprise-tier, contract-priced at ~$42K/month per docs.x.com/x-api/enterprise/getting-started. twitterapi.io's advanced_search covers the same historical archive at $0.00015/tweet with no tier gating.

Which is best for 'crisis response' (sub-5min alert latency)?

For sub-5min crisis alerting, use twitterapi.io streaming API (real-time push) instead of polling. See /blog/twitter-streaming-api-real-time-guide. SaaS platforms typically batch every 15-30 min, so build wins on latency for the crisis-response use case specifically.

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
    X (Twitter) Social Listening — Build vs Buy | TwitterAPI.io