USE CASE
Twitter API for Social Listening
Updated July 2026
What is a social listening API and how do you build one on X?
A social listening API is a search endpoint that returns every public post matching a query, so you can measure a whole category conversation rather than only the posts that tag you. On X you run boolean, date-bounded queries against one REST search endpoint, split into lanes for the category, the named brands and your own mentions, then divide your counts by the set total to get share of voice. TwitterAPIs serves it at $0.0008 per call with no developer account, no monthly plan, and one flat ceiling of 600 requests a minute per key. Where the collection is destined for a model rather than a dashboard, the cost, reach and dataset-card questions are set out at the best Twitter API for AI training data. Choosing between polling the mentions timeline and registering a standing watch is worked through at monitoring Twitter mentions in real time.
How the numbers on this page were produced
Written by Emma, TwitterAPIs developer relations
Every cost below is call arithmetic against one contractual number, the flat $0.0008 per read call on our published pricing. Cadence times query count times days gives calls, and calls times the rate gives the bill. Nothing here is a plan price or a modelled per-mention rate, because we do not charge one. On yield, per our own billed-call measurement, 11.44 tweets came back on an average keyword-search call across 484,424 paying read calls from October 22 to 28, 2026 (UTC), and 29.6% returned none, so a panel should budget against calls rather than against the 20-tweet page ceiling.
Listening is a category question, not a brand question
Brand monitoring answers what people are saying about us. Social listening answers what is happening in our market, and the difference is not a matter of degree. The listening corpus includes every conversation where nobody names a vendor at all: somebody describing the problem, asking the room for a recommendation, or complaining about a workaround they built themselves. Those are the tweets you can still influence.
In practice that means a listening panel is several queries rather than one, and the category lane is almost always the largest and the least watched. A brand-only setup will report a quiet week while the category argues about you by description rather than by name.
The five lanes below are the shape that has held up: one for the category, one for the named competitive set, one for direct mentions, one that goes deeper on whatever is spiking, and one that resolves authors so volume is not confused with reach. If you only want the second and third of those, a narrower watcher on your own name and handle is the cheaper build.
The five lanes of a listening panel
| Lane | What it captures | Endpoint | Typical cadence |
|---|---|---|---|
| Category conversation | Every tweet about the problem your product solves, whoever is named in it | GET /twitter/tweet/advanced_search | Hourly |
| Named brands | Your handle and your rivals, so a share figure has something to divide by | GET /twitter/tweet/advanced_search | Every 15 minutes |
| Owned mentions | Tweets that tag you directly, including ones the category query misses | GET /twitter/user/mentions | Every 5 minutes |
| Thread depth | Replies and quotes under whatever is spiking, where the real argument sits | GET /twitter/tweet/replies, GET /twitter/tweet/quotes | On spike |
| Voice quality | Author resolution so a handful of loud accounts cannot pass as a trend | GET /twitter/user/info | On new author |
Every lane authenticates with the same Bearer key and bills at the same flat $0.0008, so the panel shape is an engineering decision rather than a pricing one.
Compute share of voice across a competitive set
The sample below pulls the identical bounded window for every brand in the set, counts mentions and engagement, and returns both shares side by side. The window is passed once and reused for every brand, which is the part most implementations get wrong.
import requests
API = "https://api.twitterapis.com/twitter/tweet/advanced_search"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY"}
def pull(query, since, until, max_pages=40):
"""One brand, one bounded window. The window is a parameter so every
brand in the set is measured over exactly the same period."""
seen, cursor = {}, None
bounded = f"{query} since:{since} until:{until} -filter:retweets lang:en"
for _ in range(max_pages):
params = {"query": bounded, "product": "Latest"}
if cursor:
params["cursor"] = cursor
res = requests.get(API, params=params, headers=HEADERS, timeout=30).json()
for tweet in res.get("tweets") or []:
seen[tweet["id"]] = tweet
if not res.get("has_more"):
break
cursor = res.get("next_cursor")
return list(seen.values())
def share_of_voice(brands, since, until):
rows = {}
for name, query in brands.items():
tweets = pull(query, since, until)
rows[name] = {
"mentions": len(tweets),
"engagement": sum(
(t.get("likeCount") or 0) + (t.get("retweetCount") or 0)
for t in tweets
),
}
total_m = sum(r["mentions"] for r in rows.values()) or 1
total_e = sum(r["engagement"] for r in rows.values()) or 1
for name, r in rows.items():
r["mention_share"] = round(100 * r["mentions"] / total_m, 1)
r["engagement_share"] = round(100 * r["engagement"] / total_e, 1)
return rows
SET = {
"us": '"acme cloud" OR @acmecloud',
"rival_a": '"beta stack" -"beta stack overflow"', # exclude the collision
"rival_b": '"gamma db"',
}
for brand, row in share_of_voice(SET, "2026-08-17", "2026-08-24").items():
print(f"{brand:<8} {row['mentions']:>5} mentions "
f"{row['mention_share']:>5}% voice {row['engagement_share']:>5}% engagement")# One lane of the panel: the category conversation, nobody named.
curl -G "https://api.twitterapis.com/twitter/tweet/advanced_search" \
-H "Authorization: Bearer YOUR_API_KEY" \
--data-urlencode 'query=("data warehouse" OR "etl pipeline") (recommend OR alternative OR "looking for") -filter:retweets lang:en since:2026-08-17 until:2026-08-24' \
--data-urlencode 'product=Latest'const API = "https://api.twitterapis.com/twitter/tweet/advanced_search";
const HEADERS = { Authorization: "Bearer YOUR_API_KEY" };
async function pull(query, since, until, maxPages = 40) {
const seen = new Map();
let cursor = null;
const bounded = `${query} since:${since} until:${until} -filter:retweets lang:en`;
for (let page = 0; page < maxPages; page += 1) {
const url = new URL(API);
url.searchParams.set("query", bounded);
url.searchParams.set("product", "Latest");
if (cursor) url.searchParams.set("cursor", cursor);
const data = await (await fetch(url, { headers: HEADERS })).json();
for (const tweet of data.tweets ?? []) seen.set(tweet.id, tweet);
if (!data.has_more) break;
cursor = data.next_cursor;
}
return [...seen.values()];
}
// Same since/until for every brand, or the shares are not comparable.
const set = { us: '"acme cloud"', rivalA: '"beta stack"' };
const counts = {};
for (const [name, q] of Object.entries(set)) {
counts[name] = (await pull(q, "2026-08-17", "2026-08-24")).length;
}
console.log(counts);Note the exclusion on the second rival. A brand whose name collides with a common phrase will inflate the set total, which shrinks your share without anything looking broken. Read a sample of each rival query by hand before you publish a share number.
Brand and reputation monitoring
The brand lane is the narrow end of the panel, and for reputation it is the one that has to be fast. Watch three things at once: posts that tag your handle through GET /twitter/user/mentions, posts that name you without tagging you through a search on your brand and product names, and posts that misspell you, which matter more than teams expect because an angry customer rarely stops to check the spelling. Exclude your own account from the search with a -from: operator so your own posts do not count as the market talking about you.
Reputation is not a count. A day with twice the usual mentions can be a good launch or a bad outage, and the difference is in who is talking and how. Resolve the authors behind any jump, so one large account and a thousand small ones read differently, and read the replies under the posts driving it, since that is where a complaint either finds agreement or dies out.
Monitor conversations in real time
Real time on X means polling at a short interval, not a stream you subscribe to. Run the brand lane in Latest mode every five minutes, remember the highest post ID you have seen, and treat anything above it as new, so a duplicate run processes nothing twice. Spikes show up as a count, so keep a rolling baseline per hour of the week and compare each interval against the same hour last week rather than against yesterday, which stops every Monday morning reading as a crisis. When a lane crosses its baseline, switch the thread-depth lane on for the posts behind the jump and pull their replies and quotes. At five-minute cadence a single brand query is 288 calls a day, about $0.23.
Configure alerts and escalation
An alert that fires on every mention gets muted within a week, so alert on change rather than on volume. A workable starting set is two rules: mentions in an interval at three times the baseline for that hour, and a negative share above a level you pick after a month of data. Send the first rule to a team channel with the three most-engaged posts linked, and send the second to whoever owns the response, with a named backup. Add a quiet period after each alert, an hour is typical, so one running story raises one alert rather than twelve. And log every alert next to what it turned out to be. After a quarter that log is the only honest way to tune the thresholds.
Four share-of-voice metrics, and what each one hides
| Metric | Formula | Reads needed | What it hides |
|---|---|---|---|
| Mention share | Your mentions divided by all brand mentions in the set | One search call per brand per interval | A rival with a generic name inflates on false matches, so exclude aggressively |
| Engagement share | Your likes plus reposts divided by the same total across the set | Same calls, engagement counts already in the payload | One viral post distorts a week, so report median beside mean |
| Reach-weighted share | Mentions weighted by each author's follower count | Adds one user/info call per unseen author | Follower count is not impressions, so treat it as a proxy and say so |
| Positive share | Your positively scored mentions over all positive mentions in the set | Same calls plus a local scoring pass | Needs a sentiment step, and inherits every one of its failure modes |
Report at least two of these together. Mention share alone rewards noise, and engagement share alone rewards one lucky post.
Measure results: share of voice and reach over time
A share figure on its own says where you stand; a result is a change in it. To measure a campaign, a launch or a crisis response, take two windows of identical length, a baseline before and a measurement window during, and run the identical query set over both. Because search takes since: and until: bounds, the baseline can be rebuilt after the fact for a launch you forgot to baseline, at the same per-call rate as a live query.
Report three numbers side by side: the change in mention share, the change in engagement share, and the change in reach-weighted share, with the medians beside the means. If all three move the same way, the result is real. If only reach-weighted share moved, one large account probably carried it, which is still a result but a different one. Tying any of this to signups or revenue happens outside this API, by joining your dates against your own analytics, and it is worth doing once to learn which of the three shares tracks your business at all.
Competitive intelligence beyond mentions
Share of voice tells you how loud each rival is. Competitive intelligence asks why: which of their launches landed, which complaints keep recurring, and who their most engaged customers are. Two lanes answer most of it, and both use the same key and the same flat rate as the rest of the panel.
Competitor tracking by keyword and hashtag
Give each rival its own query: the company name in quotes, the handle, the product names, any campaign hashtag, and a -from: exclusion for the rival's own account so you read the market rather than their marketing. Add one extra query per rival for complaint language, their name next to words like slow, down, refund or switching, because the recurring complaints about a competitor are the most direct product brief you will ever get for free. Keep the same exclusions across every rival, or the comparison between them stops being fair.
Track competitor accounts
The other half is what rivals publish themselves. Page each competitor's own posts through GET /twitter/user/tweets once a day and store the engagement on each post after a couple of days, when most of it has accrued. Over a quarter that gives you their posting cadence, the formats that work for their audience, and the launches that landed or fell flat, measured the same way for every rival. For any launch that clearly landed, read GET /twitter/tweet/quotes on it to see what people actually said. Ten rivals read once a day is 300 calls a month, about $0.24.
Trends by location
Your category queries only find conversations you knew to describe. Trends cover the rest. GET /twitter/trends returns the current ranked trends for one location, about 50 of them, and takes a country name, an ISO code or a numeric WOEID. The full list of supported locations and their WOEIDs comes from GET /twitter/trends/locations. Pass a category instead of a location to read one of the Explore tabs, such as news or sports, or to keep only the trends X labels business and finance.
Snapshot the markets you sell into on a schedule and keep every snapshot, because the useful signal is movement: a term entering the list in one country before another, or a term near your category climbing for three snapshots in a row. Ten markets read hourly is 7,200 calls a month, about $5.76. When a trend touches your category, hand the term to the search lane and read the posts behind it. The trends API guide builds trending-topic detection by location with code.
X sentiment analysis, done honestly
The API returns the text of every post, not a sentiment label. That is a choice in your favour: you pick the scoring method, you can rerun last quarter's posts with a better model, and no vendor score changes underneath a chart you already published. Run the scoring as a local pass over the stored text, from a lexicon method for speed to a language model for nuance.
Whatever you pick, measure it before you trust it. Label 200 of your own posts by hand, score the same 200, and count the disagreements. Sarcasm, category jargon and posts that quote a complaint in order to rebut it are where scoring goes wrong on X, and every category has its own share of each. Always publish sentiment beside the volume it was computed on, since a strongly negative reading across nine posts is noise and a mild one across nine thousand is news. The sentiment analysis in Python tutorial walks through a full scoring pipeline, and the sentiment API buyer's guide compares the data sources.
What a listening panel actually costs
| Panel | Calls | Cost | Shape |
|---|---|---|---|
| Single-brand listening, 4 queries hourly | 96 calls a day, about 2,920 a month | About $2.34 a month | One brand, its category, and two rivals |
| Competitive panel, 12 queries every 15 minutes | 1,152 calls a day, about 35,000 a month | About $28 a month | Full share-of-voice set at quarter-hour resolution |
| Agency multi-client, 50 queries hourly | 1,200 calls a day, about 36,500 a month | About $29 a month | Ten clients, five queries each |
| Launch week war room, 20 queries every 5 minutes | 5,760 calls a day | About $4.61 a day | Burst cadence, switched back down afterwards |
Each row is cadence times queries times days times $0.0008. Model your own on the cost calculator.
No plan to pick, just a budget
Listening suites ask you to choose a tier before you know how much of the category you need to hear. Here there is no tier. Write the panel down as lanes, give each a query count and a cadence, and the bill follows from the arithmetic in the table above. Start every lane hourly, look at a week of real volume, then tighten only the lanes where an hour of delay would have cost you something. That is usually the brand lane and almost never the category lane.
Two habits keep the number where you planned it. Budget against calls, not tweets, since a narrow query returns fewer than a full page and still bills the call. And check the balance from inside the job with GET /account/me, which is free, so a panel that has drifted above plan raises its own alert before an invoice does. Launch weeks are the one planned exception: raise the cadence for the week, then set it back.
What a listening panel cannot see
Protected accounts. Posts from private accounts are not public data and appear in no listening product, ours included. On a niche category this can be a meaningful slice of the practitioners talking.
Anything deleted before your poll. A post removed inside your polling interval never enters the corpus. Shorter intervals narrow the gap and never close it, which is worth remembering when the deleted posts are the ones that mattered.
Conversation your query did not describe. This is the largest blind spot by far and the only one you control. A category is described in words you did not think of, so re-read a raw sample monthly and harvest the vocabulary your query is missing rather than trusting a term list written once.
Other networks. This is an X API. If your category argues on several networks, this panel is one input rather than the whole picture, and a share-of-voice number computed here should be labelled as X-only rather than as social.
Impressions. Follower counts are a reach proxy, not a measurement of who saw a post. Weight by them if it helps, and never publish the result as if it were an impression count.
API, listening suite, or the official X API
| Option | Price | Control | Coverage | Lock-in |
|---|---|---|---|---|
| TwitterAPIs | $$0.0008 per call, no monthly floor | You own the queries, the scoring and the storage | X only, in depth, including replies and quotes | None, it is a REST endpoint and your own database |
| Listening SaaS suites | Commonly $300 to $2,000 a month plus per-mention fees | Their query language, their sentiment model, their dashboard | Many networks at once, usually shallower on each | History lives in their account and leaves with your contract |
| Official X API | From about $0.005 per post read | Full control, but you build everything anyway | X only, gated by tier | Developer account, app review, per-endpoint windows |
A suite is the right answer when you need many networks and nobody to maintain it. An API is the right answer when you need X in depth, want to own the history, or are paying per mention for volume you could pull for a few dollars.
By the numbers
Social listening on X, by the numbers
TwitterAPIs figures resolve to our published pricing. Every X figure is vendor-documented.
TwitterAPIs bills every listening query at a flat $0.0008 per call, with no monthly plan and no per-mention fee. (TwitterAPIs pricing, 2026)
A twelve-query competitive panel polled every 15 minutes is 1,152 calls a day, which is about $28 a month at the published rate. (TwitterAPIs pricing, 2026)
A new account starts with $0.50 in credit and no card, enough to run a four-query panel hourly for roughly six days before you spend anything. (TwitterAPIs pricing, 2026)
One flat ceiling of 600 requests a minute and 20 concurrent per key applies across every endpoint, with no per-endpoint window to plan around. (TwitterAPIs docs, 2026)
The official X API meters post reads from about $0.005 per resource, one item per request, under its pay-per-use model. (X Developer Platform, 2026)
The official X API enforces per-endpoint rate limits in fixed 15-minute windows, and pay-per-use is hard-capped at 3 million reads per monthly billing cycle. (X API docs, 2026)
Social listening, common questions
A social listening API returns the public posts matching a query so you can measure a whole category conversation rather than only the posts that tag you. On X that is GET /twitter/tweet/advanced_search with boolean operators, date bounds and language filters, returning structured JSON with the text, engagement counts, timestamp and author object on every record. TwitterAPIs bills it at a flat $0.0008 a call with no monthly plan, no developer account and one flat ceiling of 600 requests a minute per key.
Run the same query shape for every brand in the competitive set over the same bounded window, then divide your count by the total. The two things that break it are unequal windows and unequal query quality. Pin every brand to identical since and until bounds, because comparing a 72-hour pull against a 24-hour pull produces a number that is arithmetically perfect and completely wrong. Then check each rival query for false matches, since a brand with a common word for a name inflates the set total and silently shrinks your share.
Poll rather than stream. Run your queries in Latest mode on a short interval and de-duplicate on tweet id between passes. At 600 requests a minute per key you can hold a large panel at five-minute resolution comfortably. There is no separate streaming contract to buy, and burst cadence is a config change rather than a plan upgrade, so a launch week can run at five-minute resolution and drop back afterwards without touching a billing page.
Three operators do most of the work. Use quoted phrases for multi-word brands so the words must appear together. Use minus terms to exclude the collisions you can predict, which matters most for brands whose name is also a common word. Use -filter:retweets so one travelling post does not count as hundreds of separate voices. Then sample a hundred results by hand before you trust the count, because a query nobody has eyeballed is a number nobody should publish.
Brand monitoring watches your own name and answers what people are saying about us. Social listening watches the whole category and answers what is happening in our market, including every conversation where nobody mentions you at all. The second set is larger and usually more useful, because a buyer describing the problem you solve without naming any vendor is the conversation you can still win. Both run on the same search endpoint; the difference is the query and the size of the corpus.
Every call is a flat $0.0008. A single-brand panel of four queries polled hourly is 96 calls a day, about $2.34 a month. A twelve-query competitive panel at quarter-hour resolution is roughly $28 a month. An agency running fifty queries hourly across ten clients lands near $29 a month. Compare that with the packaged listening suites, which commonly run $300 to $2,000 a month before per-mention fees, and the tradeoff is engineering time against subscription cost.
No. The API returns public posts only, so protected accounts, direct messages and anything deleted before your poll ran are outside what any listening tool can see, ours included. That is a real coverage limit rather than a product gap, and it applies equally to every vendor in this category. Practically it means a listening panel is a sample of public conversation, and any share-of-voice figure you publish should say so.
Yes. advanced_search accepts since and until bounds, so you can rebuild a category conversation for a past quarter, a competitor launch or a market event, and establish a baseline before your panel went live. Historical windows bill at the same flat $0.0008 per call as live queries, with no archive tier to unlock and no separate contract.
Related use cases
Point the same panel at rivals and it becomes competitor analysis. Every workload is indexed on the Twitter API use cases hub.
Stand up a listening panel this week
$0.0008 per call, $0.50 in free credit, no card and no X developer account.
Next read
Continue exploring related pages:
Twitter search API
Real-time search with operators via the advanced_search endpoint, $0.0008 a call, $0.04 per 1,000 tweets on full 20-tweet pages.
Twitter API use cases
14 use cases from sentiment analysis to lead generation.
Twitter API v2 pricing vs TwitterAPIs
Side-by-side endpoints, pricing, auth, and response shape, same data, 100x cheaper.