WEIR

X Analytics API in 2026: Impressions, Clicks, Cost

What the X analytics API returns: public_metrics for any post, private clicks for your own, $0.001 Owned Reads, and an engagement-rate script we ran.


Published · Updated · 7 min read

Cover image: Who can see each metric

The X analytics API is the metrics part of X's API: public counts for any post, and private clicks for your own.

This guide is for developers who want tweet impressions, likes or an engagement rate in code. You get X's metric fields and prices, what Weir (the API we run) returns, and a tested script.

You can ask X for one post's public metrics:

curl "https://api.x.com/2/tweets/2019881223666233717?tweet.fields=public_metrics" \
  -H "Authorization: Bearer $X_BEARER_TOKEN"

What the X analytics API returns

X's metrics page splits post metrics into four groups, by who may read them:

Field group Who can read it Fields Posts covered
public_metrics Anyone, bearer token Six counts, impressions included Any post
non_public_metrics The author, user token Impressions, clicks and engagements Last 30 days
organic_metrics The author, user token Counts and clicks from unpaid views Last 30 days
promoted_metrics The author, user token Counts and clicks from ad views Last 30 days

Here is what each field means, in X's words where it gives them:

  • impression_count: times the post "appeared on a user's screen." One person seeing it twice counts twice.
  • retweet_count: reposts, not counting quotes.
  • quote_count: quote posts, which X says are always organic.
  • url_link_clicks and user_profile_clicks: clicks on the post's links and on the author's profile.
  • engagements: X's private total of interactions. The metrics page gives no formula for it.
  • Video: view_count sits on the media object, with playback counts at 0, 25, 50, 75 and 100% for the author.

How to get tweet impressions with public_metrics

Add tweet.fields=public_metrics to a post lookup, a search or a timeline call. A bearer token is all you need, so it works on anyone's public post.

X's metrics page shows this response:

{
  "data": {
    "id": "1234567890",
    "text": "Hello world!",
    "public_metrics": {
      "retweet_count": 50,
      "reply_count": 12,
      "like_count": 234,
      "quote_count": 5,
      "bookmark_count": 8,
      "impression_count": 5432
    }
  }
}

That's X's own example, not our run. We have no X API key here, and X answers a call without one with a 401.

Without tweet.fields, you get only id, text and edit_history_tweet_ids. Its changelog added view counts to the API on 5 January 2023, as impression_count.

How to read private metrics for your own posts

For private metrics, you need a user token, from OAuth 1.0a or OAuth 2.0 with PKCE, for the account that wrote the post. X's example:

curl "https://api.x.com/2/tweets/1234567890?tweet.fields=non_public_metrics,organic_metrics" \
  -H "Authorization: OAuth oauth_consumer_key=...,oauth_token=..."

Three rules decide whether they come back:

  • Your posts only. Another account's post won't return them.
  • The last 30 days only, for non-public, organic and promoted metrics alike.
  • Not through full-archive search. It takes only app tokens, so X's search guide rules private metrics out.

X's reference also lists GET /2/tweets/analytics. It takes up to 100 post ids, a required start_time and end_time, and a granularity of hourly, daily, weekly or total. Its fields include impressions, engagements, url_clicks and follows.

That page lists no price or access level. Typefully's guide of 6 October 2026 says it's Enterprise-only and returns client-not-enrolled on pay-per-use. We couldn't test it.

What does the X analytics API cost?

Reading your own posts is the cheap case. X's pricing page, as of October 2026:

  • Owned Reads cost $0.001 per post from GET /2/users/{id}/tweets, when {id} is you and you own the app. Post lookup by id isn't on that list.
  • Every other post read costs $0.005, from lookup, search or a timeline.
  • Repeats within a UTC day are free. X bills a post once per 24-hour window.

Say you refresh the counts on 100 posts every day for 30 days:

Refreshing 100 posts' metrics daily for 30 days, October 2026
X API, your own timeline$3
X API, anyone's posts$15
Weir, $5 packabout $0.61

The Weir job is 3,030 credits: 30 calls to GET /v1/x/posts with 100 ids each, at 1 credit per call plus 1 per post. It fits in Weir's 5,000 free monthly credits.

What Weir returns for public posts, and what it can't

We run Weir, a read-only API for public X and Reddit data, so weigh this part knowing that. It returns X's public counts on every post, under its own names:

  • likeCount, retweetCount, replyCount, quoteCount and bookmarkCount.
  • viewCount, the view count shown under each post.
  • author.followersCount, for rates per follower.

It can't return clicks, engagements, organic or promoted splits, or video playback counts. For those, you need the author's token on X's API.

curl https://api.weirapp.io/v1/x/posts/2019881223666233717 \
  --header "Authorization: Bearer $WEIR_API_KEY"

We ran this on 22 October 2026 through Weir's MCP server, for 2 credits: 1 for the call and 1 for the post. @XDevelopers' pay-per-use launch post, trimmed:

{
  "id": "2019881223666233717",
  "createdAt": "2026-02-06T21:09:45.000Z",
  "author": { "username": "XDevelopers", "followersCount": 697849 },
  "likeCount": 5595,
  "retweetCount": 896,
  "replyCount": 792,
  "quoteCount": 596,
  "bookmarkCount": 2803,
  "viewCount": 2558782
}

A count can be null, which means X didn't report it, not zero. Our tweet JSON example maps each Weir name to its v2 twin.

Compute an engagement rate from recent posts

Here is the formula, with every count public:

engagement rate = (likes + reposts + replies + quotes + bookmarks) / views × 100

Applied to the @XDevelopers post above:

10,682likes, reposts, replies, quotes and bookmarks
2,558,782views
0.42%engagement rate by views

Clicks are private, so your public rate can't include them. Treat it as a floor next to the author's own numbers. Divide by followers instead to compare accounts of different sizes.

This part pulls an account's recent original posts through Weir's search, the one in our Twitter search API guide. It stops on a null cursor, with a page cap:

import json, os, statistics, sys, requests
SEARCH = "https://api.weirapp.io/v1/x/search"
def recent_posts(user, max_pages=3):
    body = {"fromUsers": [user], "query": "-filter:nativeretweets", "onlyOriginal": True}
    head = {"Authorization": f"Bearer {os.environ['WEIR_API_KEY']}"}
    posts = []
    for _ in range(max_pages):
        r = requests.post(SEARCH, json=body, headers=head, timeout=60)
        r.raise_for_status()
        posts += r.json()["data"]
        cursor = r.json()["meta"]["nextCursor"]
        if not cursor:
            break
        body["cursor"] = cursor
    return posts

This part applies the formula to each post, by views and by followers. You give it a username, or a saved .json response:

COUNTS = ["likeCount", "retweetCount", "replyCount", "quoteCount", "bookmarkCount"]

def rate(post, base):
    return 100 * sum(post[k] or 0 for k in COUNTS) / base

arg = sys.argv[1]
posts = (json.load(open(arg, encoding="utf-8"))["data"] if arg.endswith(".json")
         else recent_posts(arg.lstrip("@")))
posts = [p for p in posts if p["viewCount"]]  # X gave no views: skip
for p in posts:
    print(p["createdAt"][:10], f'{p["viewCount"]:>7,} views',
          f'{rate(p, p["viewCount"]):.2f}% of views',
          f'{rate(p, p["author"]["followersCount"]):.3f}% of followers')
print(f'median: {statistics.median(rate(p, p["viewCount"]) for p in posts):.2f}% of views')

We saved a real Weir search for GitHub's three latest original posts on 22 October 2026, then ran python engagement.py github.json:

2026-10-21  22,408 views 0.47% of views 0.004% of followers
2026-10-21  57,605 views 0.90% of views 0.019% of followers
2026-10-21  70,748 views 1.46% of views 0.038% of followers
median: 0.90% of views

The top post, a research preview quoting @GitHubNext, drew 410 bookmarks out of 1,032 actions. A likes-only rate would have missed about half of what made it land.

A live run costs you 1 credit per page plus 1 per post, so max_pages=3 caps it at about 63 credits.

When not to use Weir

  • You need clicks, engagements or video drop-off. Only the author's token on X's API returns them.
  • You only track your own account. Owned Reads cost $0.001 per post, and your token returns private metrics.
  • You promote posts. The X Ads API reports paid impressions, clicks and spend.
  • Price per post matters most. TwitterAPI.io lists $0.15 per 1,000 tweets, as of October 2026.

Weir reads public data only, can't post, and isn't licensed by X, so access can change. Check X's terms for your use; this isn't legal advice.

FAQ

Does the X API give tweet impressions?

Yes. You get public_metrics.impression_count on any post with a bearer token. It counts times the post appeared on a screen, so one person can count twice. X added it to the API in January 2023.

Can I get analytics for someone else's tweets?

You can read the public counts: likes, reposts, replies, quotes, bookmarks and impressions. Clicks and engagements, no. X returns those only to the author, with a user token, for posts from the last 30 days.

Is there a free Twitter analytics API?

Not from X: its pay-per-use plan has no free tier, though your own posts cost $0.001 each. Weir gives 5,000 free credits a month, enough for public counts on about 4,900 posts looked up by id.

Why is non_public_metrics missing from my response?

Usually one of three causes: the post is older than 30 days, it isn't yours, or you sent a bearer token instead of a user token. Full-archive search can't return private metrics at all.

Sources

All checked on 22 October 2026. We read docs.x.com as Markdown, adding .md to each URL: