Platform Guides

X (Twitter) Views vs Impressions: What Each Metric Counts, and What the API Gives You (2026)

What views, impressions, engagements, and profile visits mean on X in 2026, whether anyone can see who viewed your profile, and which metrics the X API v2 exposes through public_metrics and non_public_metrics.
September 10, 2026 by Jesse Eisenbart8 min read
Oil painting of a still alpine lake at dawn mirroring the peaks so exactly that the mountains appear twice

TLDR: On X, views and impressions are one metric with two names: a count of every time a post was served on a screen, repeats included. Engagements are interactions with the post, and engagement rate is engagements divided by impressions. X has no reach metric and no way for anyone to see who viewed a profile; the dashboard shows an aggregate profile-visits number and nothing more. The API returns the view count as public_metrics.impression_count for any post, and link and profile clicks as non_public_metrics only for your own posts from the last 30 days, at $0.005 per post read (a fifth of that for your own data since April 2026). Checked against docs.x.com and X’s own statements on September 10, 2026.

What is an impression on X?

An impression is recorded each time a post appears on a user’s screen: in the Home timeline, in search results, on a profile, or on the post’s detail page. X’s analytics documentation describes it that way, and three consequences follow that surprise people:

  • Repeats count. If the same person scrolls past your post three times, that is three impressions.
  • You count. Opening your own post to read the replies adds to it.
  • Nobody has to read it. An impression is a display, not attention. A post that scrolls past at speed still registers.

So impressions are a measure of distribution, not of people. There is no deduplicated “reach” on X the way there is on Instagram; the closest proxy is comparing impressions with your follower count.

What is a “view” on X?

The number under every post is the same thing. X added public view counts on December 22, 2022, and Elon Musk’s announcement framed the reason: “Twitter is rolling out View Count, so you can see how many times a tweet has been seen! This is normal for video. Shows how much more alive Twitter is than it may seem, as over 90% of Twitter users read, but don’t tweet, reply or like.”

“How many times a tweet has been seen” is the impressions definition. Every source that has compared the public view count with the dashboard’s impressions column finds them to be the same measurement, and the API confirms it: there is no separate view_count field on a post, only impression_count. When someone asks “what do views mean on X,” the answer is “impressions, shown publicly.”

The name change had a side effect that still confuses reports: a post from 2021 shows a view count that only started accumulating in late 2022, so old posts look like they underperformed. They did not; they were not being counted.

Views, impressions, and reach, side by side

Metric What it counts Where you see it API field
Views Times the post was served on a screen, repeats included Under every post public_metrics.impression_count
Impressions The same count Analytics dashboard and post activity public_metrics.impression_count
Reach Unique people who saw it Not offered by X None
Engagements Interactions with the post Post activity Sum of the engagement fields below
Engagement rate Engagements ÷ impressions Post activity Compute it yourself

Engagements and engagement rate

An engagement is any interaction with the post: a like, repost, reply, or quote; a click on a link, a hashtag, the author’s avatar or name; expanding the post to see details; viewing attached media. Follows that come from the post count too. X’s dashboard reports the total and the rate, and the rate is simply engagements divided by impressions.

Two engagement metrics have their own rules. Video views have historically followed the Media Rating Council standard: at least 50% of the player in view for at least two continuous seconds. On August 13, 2026 X’s changelog redefined the Ads API’s video_total_views as 100% in view for at least three seconds, or any manual click on play, and preserved the older definition as a separate field; if you compare video numbers across that date, expect a drop that is definitional, not real. Media views on images and GIFs are simpler: the media was displayed.

Because the rate divides by impressions, a post with huge distribution and modest interaction shows a low rate even when the raw engagement is your best ever. Report both numbers.

Where to see your stats, and the Premium gate

There are three surfaces:

  1. The view count under every post, visible to everyone.
  2. Post activity, opened from the bar-chart icon on your own post, showing impressions, engagements, engagement rate, and the breakdown (link clicks, profile clicks, detail expands, media views, follows).
  3. The account analytics dashboard, with 28-day summaries of impressions, profile visits, mentions, and followers.

In June 2024 X restricted the account-wide dashboard to Premium subscribers, and in August 2024 added an audience-insights section for them, as Social Media Today reported. Reports at the time also noted a minimum account age of 14 days and 10 posts before the dashboard appears. Per-post activity and the public view count did not move behind the paywall.

Can you see who viewed your X profile?

No, and this deserves a direct answer because the question outranks most others in this cluster. X has never exposed the identities of people who visit a profile, to free accounts or to Premium subscribers, in the app or in the API. The analytics dashboard shows profile visits as a single number over a rolling window; that is the entire feature. There is no field in the X API v2 post or user objects that identifies a viewer, so no third-party tool can have that data either.

Any app or website that promises to show who viewed your profile is either guessing from public interactions (who liked and replied recently) or collecting your login. Treat the second kind as phishing.

What the X API exposes

The metrics reference splits post metrics into four groups, and the split decides what you can build.

Field group Fields Who can request it Which posts Age limit
public_metrics impression_count, like_count, reply_count, retweet_count, quote_count, bookmark_count Any app token Any public post None
non_public_metrics impression_count, url_link_clicks, user_profile_clicks OAuth user context Posts the authenticated user owns Last 30 days
organic_metrics The same fields, organic only OAuth user context Owned posts Last 30 days
promoted_metrics The same fields, paid views only OAuth user context Owned, promoted posts Last 30 days

Three implications:

  • Views are public. impression_count in public_metrics is readable for anyone’s post with an app-only token. A competitor’s view counts are one API call away.
  • Clicks are private and perishable. Link clicks and profile clicks require the account owner’s OAuth grant, and X only serves them for posts “created within the last 30 days.” A product that wants click history has to sync it inside that window and store it.
  • User metrics are counts, not analytics. The user object’s public_metrics carries follower, following, post, listed, like, and media counts. There is no account-level analytics endpoint in the API that mirrors the Premium dashboard; a follower time series is something you build by sampling.

Every read is metered under X’s pay-per-use pricing: $0.005 per post read and $0.010 per user read. Since April 20, 2026 reads of your own account’s data are priced as “owned reads” at $0.001, and a resource requested more than once in the same 24-hour UTC window is not charged again. Pay-per-use plans cap at 3 million post reads per month.

Pulling post metrics with the API

Public metrics for several posts in one call, in Node:

const X = 'https://api.x.com/2'

export async function getPostMetrics(ids, token, { includeNonPublic = false } = {}) {
	const fields = includeNonPublic ? 'public_metrics,non_public_metrics' : 'public_metrics'
	const url = new URL(`${X}/tweets`)
	url.searchParams.set('ids', ids.join(','))     // up to 100 per request
	url.searchParams.set('tweet.fields', fields)
	const response = await fetch(url, { headers: { Authorization: `Bearer ${token}` } })
	const { data = [], errors } = await response.json()
	if (errors?.length) console.warn(errors)         // e.g. non_public_metrics on a post over 30 days old
	return data.map((post) => ({
		id: post.id,
		views: post.public_metrics.impression_count,
		likes: post.public_metrics.like_count,
		replies: post.public_metrics.reply_count,
		reposts: post.public_metrics.retweet_count + post.public_metrics.quote_count,
		bookmarks: post.public_metrics.bookmark_count,
		linkClicks: post.non_public_metrics?.url_link_clicks ?? null,
		profileClicks: post.non_public_metrics?.user_profile_clicks ?? null,
	}))
}

includeNonPublic needs a user-context token for the account that owns the posts; with an app-only token the request fails. The same lookup in Python, computing engagement rate the way X does:

import requests

X = 'https://api.x.com/2'

def post_metrics(post_ids: list[str], user_token: str) -> list[dict]:
    response = requests.get(
        f'{X}/tweets',
        params={'ids': ','.join(post_ids), 'tweet.fields': 'public_metrics,non_public_metrics'},
        headers={'Authorization': f'Bearer {user_token}'},
        timeout=30,
    )
    payload = response.json()
    rows = []
    for post in payload.get('data', []):
        pm, npm = post['public_metrics'], post.get('non_public_metrics', {})
        impressions = pm['impression_count']
        engagements = (pm['like_count'] + pm['reply_count'] + pm['retweet_count'] + pm['quote_count']
                       + pm['bookmark_count'] + npm.get('url_link_clicks', 0) + npm.get('user_profile_clicks', 0))
        rows.append({
            'id': post['id'],
            'impressions': impressions,
            'engagements': engagements,
            'engagement_rate': round(engagements / impressions * 100, 2) if impressions else 0.0,
        })
    return rows

That engagement total is a floor: the dashboard also counts hashtag clicks, detail expands, and media views, which the API does not expose individually. Your API-computed rate will run a little below the dashboard’s.

Reading the numbers

Because reach does not exist on X, use ratios the metrics do support:

  • Views ÷ followers approximates how far past your audience a post travelled. Above 1.0 means the algorithm carried it to non-followers.
  • Engagements ÷ views is the engagement rate; compare it across your own posts, not against published benchmarks, which mix account sizes and definitions.
  • Link clicks ÷ views is the number a link post actually exists for, and it is only available for 30 days, so record it.
  • Profile clicks on a post is the leading indicator for follows; profile visits on the dashboard is the aggregate.

What changed in 2026

  • February 6: the X API moved to pay-per-use; every metric read now has a price.
  • April 20: owned reads at $0.001 per resource, plus 24-hour deduplication, which makes syncing your own posts’ metrics daily affordable.
  • August 13: the Ads API’s video view definition tightened to three seconds at 100% in view, with the old figure kept as a separate field.

The public view counter itself did not change in 2026.

PostZen and X analytics

PostZen’s X analytics is opt-in per connected account, because every metric read is metered and billed through at X’s rates with no markup. When it is on, the sync pulls public_metrics for the account’s posts, so views (mapped from impression_count), likes, replies, reposts plus quotes, and bookmarks, and adds url_link_clicks from non_public_metrics for the account’s own posts under 30 days old, alongside follower counts and best-time-to-post suggestions. Reach is not reported because X has no such metric. The per-platform coverage is on the analytics page, the request shapes and pass-through billing on the X integration docs, and publishing on the X page; the X character-limit guide covers the other X question people ask most. Whatever tool shows you the numbers, they are X’s, defined as above.

Frequently asked questions

What is an impression on X (Twitter)?

An impression is counted each time a post is served on someone’s screen, in a timeline, in search, or on the post’s own page. Repeat appearances to the same person count again, and your own views of your post count too. It is a count of displays, not people.

Are views and impressions the same thing on X?

Yes. The view count shown under every post since December 2022 is the same served-on-screen measurement that the analytics dashboard calls impressions. The public label is "views"; the API field is impression_count.

Can you see who viewed your X profile?

No. X has never shown the identities of profile visitors to anyone, including Premium subscribers, and the API has no such field. Analytics shows an aggregate profile-visits count only. Apps claiming to reveal profile viewers are harvesting logins.

What counts as an engagement on X?

Any interaction with the post: likes, reposts, replies, quotes, bookmarks, link clicks, profile clicks, hashtag clicks, media views, and detail expands. Engagement rate is engagements divided by impressions.

How do I get tweet views from the X API?

Request the post with tweet.fields=public_metrics; impression_count is the view count, alongside like_count, reply_count, retweet_count, quote_count, and bookmark_count. Link clicks and profile clicks are in non_public_metrics, which only work for your own posts from the last 30 days with a user-context token.

Does X analytics require Premium?

The account-wide analytics dashboard was restricted to Premium subscribers in mid-2024. Per-post view counts remain visible to everyone, and the API returns public metrics to any app that pays for reads.