Skip to content

Twitter analytics API for any account

Every public post on X carries six engagement counts (likes, reposts, replies, quotes, views and bookmarks) that an analytics API can read for any account. The official X API bills each post it returns at $0.005.

Short answer: Those six counts are public, so an API reads them for posts you don't own. Link clicks, profile clicks and follows from a post stay with its author, in X's own analytics, for 30 days. Sorsa API's POST /tweet-info-bulk returns all six counts for 100 posts per request, from $0.014 per 1,000, and 100 free requests cover 10K posts.

Endpoint
POST /tweet-info-bulk
Page size
100 posts per request
Price
from $0.014 per 1,000

#What a Twitter analytics API returns

A Twitter analytics API is an endpoint that returns the numbers behind X posts and accounts as JSON instead of a dashboard: each post's engagement counts, each account's follower and post totals, and the posts themselves to count over. What it can return depends on one split: public numbers anyone can read, and private numbers only the author can.

To see one account's engagement rate in a browser first, the free Twitter Engagement Rate Calculator reads its latest posts. The rest of this guide does the same job in code, for any number of accounts and posts.

Public on every post Any API reads them, for any public account Likes212 Reposts31 Replies24 Quotes6 Views9,640 Bookmarks41 Private to the author X's own analytics, posts from the last 30 days Link clicksauthor only Profile clicksauthor only Follows from the postauthor only Detail expandsauthor only Total engagementsauthor only Read with the author's own OAuth login
Six counts are public on every post and readable for any account; clicks and follows stay with the author for 30 days.

The table maps each number to the field that carries it. Sorsa API returns the six public counts on every post it sends back; the official X API keeps them under public_metrics and the private ones under non_public_metrics.

MetricSorsa API fieldOfficial X API fieldWho can read it
Likeslikes_countlike_countanyone
Repostsretweet_countretweet_countanyone
Repliesreply_countreply_countanyone
Quotesquote_countquote_countanyone
Viewsview_countimpression_countanyone
Bookmarksbookmark_countbookmark_countanyone
Link clicksnoneurl_link_clicksthe author
Profile clicksnoneuser_profile_clicksthe author
  • Likes

    Sorsa API field
    likes_count
    Official X API field
    like_count
    Who can read it
    anyone
  • Reposts

    Sorsa API field
    retweet_count
    Official X API field
    retweet_count
    Who can read it
    anyone
  • Replies

    Sorsa API field
    reply_count
    Official X API field
    reply_count
    Who can read it
    anyone
  • Quotes

    Sorsa API field
    quote_count
    Official X API field
    quote_count
    Who can read it
    anyone
  • Views

    Sorsa API field
    view_count
    Official X API field
    impression_count
    Who can read it
    anyone
  • Bookmarks

    Sorsa API field
    bookmark_count
    Official X API field
    bookmark_count
    Who can read it
    anyone
  • Link clicks

    Sorsa API field
    none
    Official X API field
    url_link_clicks
    Who can read it
    the author
  • Profile clicks

    Sorsa API field
    none
    Official X API field
    user_profile_clicks
    Who can read it
    the author

Views are public too. X's own metrics documentation (opens in a new tab) lists impressions as a public metric that a plain bearer token reads for any post; one person who sees a post twice counts as two impressions.

The private numbers have three doors, all tied to the account that wrote the post. The first is the analytics dashboard on x.com. The second is the official X API's GET /2/tweets/analytics (opens in a new tab): up to 100 of your post IDs, as totals or hourly, daily and weekly series, signed with your account's OAuth token. The third is X's Enterprise Engagement API (opens in a new tab) under a sales contract. Non-public metrics cover posts from the last 30 days only.

For public counts, the official X API bills every post read at $0.005, or $5.00 per 1,000, after a developer account and an app (X API pricing (opens in a new tab)). From November 22, 2026, a post read with its author attached costs $0.015 (X's notice (opens in a new tab)). An account's timeline there stops at its 3,200 most recent posts (opens in a new tab), and pay-per-use stops at 3M post reads a month.

#Get engagement metrics for any account with Sorsa API

For engagement metrics on accounts you don't own, use Sorsa API, a Twitter (X) API and scraper: every post it returns carries all six counts and its author's full profile, from $0.014 per 1,000 posts against $5.00 on the official X API. One ApiKey header replaces the developer account and OAuth, every plan runs at 20 requests per second, and your own X account is never involved.

The fastest start is an account's timeline: one request returns its newest posts with their counts, and a cursor leads to older ones. A cursor is a token the API returns with each page; you send it back to get the next page.

  1. Get a key. Sign up and copy the API key from your dashboard. The 100 free requests are already on it.

  2. Pull the account's posts. Send the handle to POST /user-tweets (opens in a new tab). Each page holds up to 20 posts, newest first, with the counts and the author's profile.

    Terminal
    curl -X POST "https://api.sorsa.io/v3/user-tweets" \
      -H "ApiKey: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"username": "harborline_roasters"}'
    
    Response200 OK
    {
      "tweets": [
        {
          "id": "2116184394037384839",
          "full_text": "Winter blend ships Monday. First 200 orders get a tin.",
          "created_at": "2026-10-30T15:04:11Z",
          "lang": "en",
          "likes_count": 212,
          "retweet_count": 31,
          "reply_count": 24,
          "quote_count": 6,
          "view_count": 9640,
          "bookmark_count": 41,
          "is_reply": false,
          "is_quote_status": false,
          "conversation_id_str": "2116184394037384839",
          "user": {
            "id": "1503315520518280839",
            "username": "harborline_roasters",
            "display_name": "Harborline Roasters",
            "followers_count": 8450,
            "followings_count": 312,
            "tweets_count": 3921,
            "verified": false
          }
        }
      ],
      "next_cursor": "DAABCgABG5xQ2bW8AAAKAAIbmN8T0ZbQ6QgAAwAAAAIAAA"
    }
    
  3. Page back to the date you need. Send next_cursor in the next body and stop when it comes back empty or the posts get older than your start date. The loop below writes one row per post to a CSV file.

    import csv
    import requests
    
    API = "https://api.sorsa.io/v3/user-tweets"
    HEADERS = {"ApiKey": "YOUR_API_KEY"}
    FIELDS = ["id", "created_at", "likes_count", "retweet_count",
              "reply_count", "quote_count", "view_count", "bookmark_count"]
    
    
    def account_posts(username, since="2026-10-01"):
        body, rows = {"username": username}, []
        while True:
            r = requests.post(API, headers=HEADERS, json=body, timeout=30)
            r.raise_for_status()
            data = r.json()
            page = data.get("tweets", [])
            rows += [t for t in page if t["created_at"] >= since]
            old = all(t["created_at"] < since for t in page)
            if not data.get("next_cursor") or old:
                return rows
            body["next_cursor"] = data["next_cursor"]
    
    
    posts = account_posts("harborline_roasters")
    with open("metrics.csv", "w", newline="") as f:
        w = csv.DictWriter(f, fieldnames=FIELDS, extrasaction="ignore")
        w.writeheader()
        w.writerows(posts)
    print(len(posts), "posts written")
    
  4. Keep each run as a snapshot. Counts keep growing after a post goes out, so store every pull with its date (post ID, captured at, the six counts). Two snapshots a day apart show which posts are still gaining, and a count plotted against created_at over a month shows whether the account's posts are getting more reach or less.

A 429 status means more than 20 requests in one second: wait a second and send it again. A 403 means the key is missing or out of requests, a 401 that it is wrong; failed requests are never charged.

#Keep metrics fresh: refresh tracked posts 100 at a time

Once you know which posts you track, refresh their counts by ID: POST /tweet-info-bulk (opens in a new tab) takes up to 100 post links or IDs and returns every post with its current counts in one request, from $0.014 per 1,000 posts. Metrics for 1M posts cost from $14 that way.

The account's first timeline page does part of the job for free: it already holds the newest 20 posts with current counts. An account that posts twice a day keeps its last 10 days fresh with that one request; only older posts need the batch call.

POST /user-tweets, page 1 The newest 20 posts with current counts: 1 request day 1 day 2 day 3 day 4 day 5 day 6 day 7 POST /tweet-info-bulk Older posts by ID, 100 per request One account posting 5 times a day, each post re-read daily for 7 days. Newest on the left.
One timeline page refreshes the newest 20 posts; everything older goes 100 posts per request by ID.
Terminal
curl -X POST "https://api.sorsa.io/v3/tweet-info-bulk" \
  -H "ApiKey: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"tweet_links": ["2116184394037384839", "2115861688481928839"]}'

In Python, cut your ID list into slices of 100 and send each slice as tweet_links; the response is one tweets array with no cursor.

Python
HEADERS = {"ApiKey": "YOUR_API_KEY"}


def refresh(ids):
    out = []
    for i in range(0, len(ids), 100):
        r = requests.post(
            "https://api.sorsa.io/v3/tweet-info-bulk",
            headers=HEADERS, json={"tweet_links": ids[i:i + 100]},
            timeout=60)
        r.raise_for_status()
        out += r.json().get("tweets", [])
    return out

The cards compare one pass over a list of posts: every post's six counts, read once.

Posts

Official X API

$5,000

for 1M posts' metrics

$0.005 per post

Sorsa API

from$14

for 1M posts' metrics

from $0.014 per 1,000

#Replies, quotes and retweeters by API

Counts say how many people engaged; three more endpoints say who they were and what they wrote. Each takes a post link or ID, and each reply and quote comes back as a full post with its own counts and author.

You needSorsa API endpointWhat comes back
Replies under a post/comments (opens in a new tab)up to 20 replies a page, by Relevance, Recency or Likes
Quote posts of a post/quotes (opens in a new tab)up to 20 quotes a page, with the added text
Accounts that reposted/retweeters (opens in a new tab)profiles with follower counts, newest first
Totals for many accounts/info-batch (opens in a new tab)up to 100 profiles a request

Each answers a different question. Replies sorted by Likes put the most-liked answers on page one, so a single request shows how the audience took a post. Quotes carry the commentary people added, the raw input for tone or sentiment. Retweeters' follower counts add up to the audience a post reached secondhand.

Python
BASE = "https://api.sorsa.io/v3"
HEADERS = {"ApiKey": "YOUR_API_KEY"}


def pages(path, body, key, limit=10):
    for _ in range(limit):
        r = requests.post(f"{BASE}/{path}", headers=HEADERS,
                          json=body, timeout=30)
        r.raise_for_status()
        data = r.json()
        yield from data.get(key, [])
        if not data.get("next_cursor"):
            return
        body = {**body, "next_cursor": data["next_cursor"]}


post = "https://x.com/harborline_roasters/status/2116184394037384839"
top = list(pages("comments", {"tweet_link": post, "order_by": "Likes"},
                 "tweets", limit=1))[:5]
quotes = list(pages("quotes", {"tweet_link": post}, "tweets"))
fans = list(pages("retweeters", {"tweet_link": post}, "users"))
reach = sum(u.get("followers_count", 0) for u in fans)
print(len(quotes), "quotes,", len(fans), "retweeters,", reach, "reach")

On the official X API, quote posts come from GET /2/tweets/:id/quote_tweets at $0.005 each and retweeters from GET /2/tweets/:id/retweeted_by at $0.010 each, $10.00 per 1,000 accounts. Each of those two endpoints allows 75 requests per 15 minutes (X API rate limits (opens in a new tab)). Replies have no endpoint of their own there: they come from a search on conversation_id, which reaches back 7 days on recent search.

Two jobs live on their own pages. To check whether one account followed, retweeted, quoted or replied, the Twitter verification API guide answers it in a single check. To read a post's replies without code, see how to see comments on X.

#How to calculate engagement rate from API data

Engagement rate is the share of people who interacted with a post, and the API fields give you both common versions. By views, add likes, reposts, replies and quotes, divide by views and multiply by 100. By followers, divide the same sum by the author's followers_count, which every post carries in its user object.

Take the post in the response above: 212 likes, 31 reposts, 24 replies and 6 quotes make 273 interactions. Against 9,640 views that is 2.83%; against 8,450 followers it is 3.23%. The Twitter Engagement Rate Calculator uses the same two formulas, so your code and the free tool agree on any account.

Python
from statistics import median


def engagement(posts):
    followers = posts[0]["user"]["followers_count"]
    for t in posts:
        acts = (t["likes_count"] + t["retweet_count"]
                + t["reply_count"] + t["quote_count"])
        views = t["view_count"] or 1
        t["er_views"] = round(100 * acts / views, 2)
        t["er_followers"] = round(100 * acts / followers, 2)
    return median(t["view_count"] for t in posts)

Report the median views next to the rate. One viral post lifts an average for months, while the median shows what a typical post gets. Leave posts younger than two days out of the median, since their views are still climbing.

Good to know

Views count screens, not people. X counts an impression each time a post appears on a screen, so one reader who scrolls past twice adds two views. Compare rates by views across accounts of similar size, and use the follower rate to compare audiences.

#What an X analytics pipeline costs per month

The cost of an analytics pipeline depends on three numbers: how many accounts you track, how many posts each one publishes a day, and how many days you re-read each post. Move the sliders to see a month on both APIs.

100
5
7
$525
Official X API, a month
105K posts read at $0.005 each. With each post's author attached from November 22: $1,575.
from $4.83
Sorsa API, a month
$1.40 per 1,000 requests; $6.87 at the Pro rate of $1.99. Authors come with every post.

About 6 seconds of requests a day at 20 requests per second: one timeline page per account, the older posts 100 per request by ID.

One timeline page per account each day, older posts refreshed 100 per request; the official X API re-reads every post it returns at $0.005.

The gap comes from the unit. The official X API bills every post it returns, every day you read it again, and stops at 3M post reads a month; above that, only an Enterprise contract from about $42,000 a month remains. Sorsa API bills the request, and one request carries up to 100 posts by ID or 20 from a timeline.

For a dashboard over competitors, clients or creators, choose Sorsa API: tweet metrics cost from $0.014 per 1,000 posts instead of $5.00. Every plan runs at 20 requests per second, one API key replaces the developer account, and the same key reads replies, quotes, retweeters and search back to 2006. It is read-only, so it never touches your X account.

#Analyze a topic, not just one account

Engagement analysis also works on a conversation: search the posts about a topic, then rank them by their counts. POST /search-tweets (opens in a new tab) takes X's own search operators, returns about 20 posts per page with all six counts and the author, and reaches back to 2006.

Terminal
curl -X POST "https://api.sorsa.io/v3/search-tweets" \
  -H "ApiKey: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "\"cold brew\" min_faves:50 lang:en", "order": "popular"}'

Add since: and until: to the query for a date window. Sum the interactions per author to see who drives the topic, or run one query per brand over the same dates for a share of voice. The Twitter search API guide covers the operators, and Twitter competitor analysis turns the same data into a benchmark.

#Start with one account today

Every public post's likes, reposts, replies, quotes, views and bookmarks can be read by API, for any account; only clicks and follows stay with the author. Sorsa API returns all six counts with the author's profile, 100 posts per request by ID, from $0.014 per 1,000 against $5.00 on the official X API. Pull one account's last month with the loop above, refresh it daily, and the 100 free requests cover your first 10K posts.

#FAQ

Can you get Twitter analytics for another account?

Yes, for every public number. Any public account's likes, reposts, replies, quotes, views and bookmarks per post, plus its follower and post totals, can be read without its owner. Link clicks, profile clicks and follows from a post stay private to the author. To compare two accounts in a browser, use Compare Twitter Accounts; for many accounts, an API does it in code.

Does the official X API return view counts for any tweet?

Yes. X lists impressions as a public metric: public_metrics.impression_count comes with any post read through the official X API with a bearer token, at $0.005 per post. Sorsa API returns the same number as view_count on every post, from $0.014 per 1,000 posts. Only the split into organic and promoted views, and clicks, need the author's own login.

Can an API show who liked a tweet?

No API can list a post's likers for posts you don't own. X made likes private in June 2024, and its liking-users endpoint returns at most 100 users per post, for all time (X's likes docs (opens in a new tab)). The like count stays public: Sorsa API returns it as likes_count on every post, and /retweeters, /quotes and /comments name the people behind the other actions.

What is the best API for Twitter analytics?

For analytics on accounts you don't own, Sorsa API: every post comes with likes, reposts, replies, quotes, views, bookmarks and the author's profile, from $0.014 per 1,000 posts against $5.00 on the official X API. It runs at 20 requests per second on every plan, needs one API key and no developer account, and adds replies, quotes and retweeters. Clicks on your own posts stay in X's own analytics.

How much does a Twitter engagement API cost?

On Sorsa API, post metrics by ID cost from $0.014 per 1,000 posts, and timelines, replies and quotes from $0.07 per 1,000, because one request returns 100 or 20 of them. The official X API charges $5.00 per 1,000 posts and $10.00 per 1,000 retweeters, $15.00 per 1,000 posts with authors from November 22, 2026. Sorsa API's 100 free requests need no card and never expire.

#How we checked

On November 2, 2026 we compared every endpoint, parameter and response field in this guide with the live Sorsa API reference (45 endpoints) and its docs pages for /user-tweets, /tweet-info-bulk, /comments, /quotes and /retweeters. The requests and responses use a demo account. The official X API's metrics, analytics endpoints, prices and rate limits come from docs.x.com, and the November 22 billing change from X's developer forum, read the same day. The costs are our own arithmetic from both rate cards.

By the Sorsa API team. We build and run Sorsa API, the read-only Twitter/X API and scraper, in production since 2022 (formerly TweetScout API) with 6B+ requests served. About Sorsa API

What changed
  • Rewritten from scratch and merged with the Twitter engagement API guide: a table of public and author-only metrics with both APIs' field names, a timeline loop in Python and Node.js, daily refresh 100 posts per request, replies, quotes and retweeters as engagement data, engagement rate with median views, a monthly cost calculator, and the official X API's 2026 prices, limits and November 22 billing change.
  • First published.