Glossary

Five Engagement Counts: Does Bluesky Have Analytics?

Taras Shynkarenko
Taras Shynkarenko
•Updated: •9 min read
Five engagement counts: does Bluesky have analytics?Five engagement counts: does Bluesky have analytics?

TL;DR, Quick Answer

9 min read

Bluesky exposes no view count, no impression count and no analytics endpoint. The app.bsky.feed.defs#postView definition carries exactly five counters, likeCount, repostCount, replyCount, quoteCount and bookmarkCount, and none of the thirteen namespaces under app.bsky is an analytics namespace. The protocol does define an interactionSeen event, but it is write only and it goes to feed generators, not to the author of the post.

Does Bluesky have analytics?

Ask does Bluesky have analytics and the answer is no: the AT Protocol lexicons that define every Bluesky API response carry no view count, no impression count and no analytics endpoint. A post comes back with five engagement counters. A profile comes back with follower, following and post totals. Nothing anywhere tells you how many people saw the thing you published.

That is a claim about an absence, so here is exactly what was checked before making it, on 10 September 2026:

  • Every lexicon file in bluesky-social/atproto on the main branch, 404 JSON files in total. A case insensitive search across all of them returns zero occurrences of impression, viewCount, analytic and insight.
  • The postView definition in lexicons/app/bsky/feed/defs.json, field by field.
  • The directory listing of lexicons/app/bsky, to name every namespace that exists.
  • A live unauthenticated call to the public AppView, to confirm the running service returns what the schema says it returns.

The claim covers the first party lexicons and the public AppView. It says nothing about whatever internal dashboards Bluesky PBC runs for itself, and nothing about third party services that model reach from other signals.

What fields does app.bsky.feed.defs#postView actually carry?

Fifteen, and five of them are counters.

FieldTypeWhat it gives you
uristring, at-uriThe post's address
cidstring, cidContent hash of this version of the record
authorrefapp.bsky.actor.defs#profileViewBasic
recordunknownThe post record itself, text and all
embedunionImages, video, external link or quoted record
replyCountintegerReplies
repostCountintegerReposts
likeCountintegerLikes
quoteCountintegerQuote posts
bookmarkCountintegerBookmarks
indexedAtstring, datetimeWhen the AppView indexed the post, not when it was written
viewerrefYour own relationship to the post, such as whether you liked it
labelsarrayModeration labels attached to the post
threadgaterefReply restrictions on the thread
debugunknownDescribed in the lexicon as "Debug information for internal development"

Two details in that table are easy to miss. indexedAt is an indexing timestamp, so it is the wrong field to use as a publish time; the createdAt value inside record is the one you want. And the counters are not in the definition's required list, which reads ["uri", "cid", "author", "record", "indexedAt"]. A conforming response is allowed to omit likeCount entirely, so code that reads it should treat a missing value as unknown rather than as zero.

Here is the running service saying the same thing:

GET https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=bsky.app&limit=1
 
"post": {
  "uri": "at://...",
  "cid": "...",
  "author": { ... },
  "record": { ... },
  "embed": { ... },
  "replyCount": 1,
  "repostCount": 2,
  "likeCount": 132,
  "quoteCount": 3,
  "bookmarkCount": 3,
  "indexedAt": "...",
  "labels": []
}

Five keys ending in Count. No sixth.

Is there an analytics namespace under app.bsky?

No. Thirteen namespaces sit under app.bsky, and every one of them has a job that is not measurement.

NamespaceWhat it covers
app.bsky.actorProfiles, preferences, actor search
app.bsky.ageassuranceAge verification state
app.bsky.bookmarkCreating, deleting and listing bookmarks
app.bsky.contactContact import, phone verification, match dismissal
app.bsky.draftServer stored drafts
app.bsky.embedImage, video, external and record embed shapes
app.bsky.feedPosts, likes, reposts, quotes, threads, feed generators
app.bsky.graphFollows, blocks, mutes, lists, starter packs
app.bsky.labelerLabeling services
app.bsky.notificationNotification list, unread count, push registration
app.bsky.richtextText facets such as links and mentions
app.bsky.unspeccedUnstable endpoints the official client uses
app.bsky.videoVideo upload and job status

Widen the search past app.bsky and the picture holds. The repository's other roots are com.atproto for protocol plumbing, chat.bsky for direct messages, tools.ozone for moderation, plus internal.bsky, site.standard and com.germnetwork. The only endpoints in the entire set with a statistical flavour are tools.ozone.report.getLiveStats, tools.ozone.report.getHistoricalStats, tools.ozone.report.refreshStats and tools.ozone.moderation.getReporterStats. Those report on moderation queues for moderators. getLiveStats is documented as "Get live report statistics from the past 24 hours. Filter by queue, moderator, or report type." None of it touches post performance.

Why does the protocol define a seen event but never report it?

Because the seen event flows to feed generators, not to authors. This is the part worth quoting when someone insists the data must be in there somewhere.

app.bsky.feed.sendInteractions is a procedure whose input is an array of app.bsky.feed.defs#interaction objects. Each interaction names an item by AT URI and an event token. The known values include:

TokenLexicon description
app.bsky.feed.defs#interactionSeen"Feed item was seen by user"
app.bsky.feed.defs#clickthroughItem"User clicked through to the feed item"
app.bsky.feed.defs#clickthroughAuthor"User clicked through to the author of the feed item"
app.bsky.feed.defs#interactionLike"User liked the feed item"
app.bsky.feed.defs#requestLess"Request that less content like the given feed item be shown in the feed"

So the vocabulary for an impression exists. interactionSeen is, in plain terms, a view event. What is missing is a read path. The procedure's own description says it sends information "back to the feed generator that served them", and its output schema is an empty object, {"type": "object", "properties": {}}. A feed operator who runs a custom feed can count seen events for items their feed served. You, as the author of a post, have no endpoint that returns how many times your post was seen, in that feed or any other.

That asymmetry is the honest answer to why Bluesky feels like it should have view counts. The signal is defined, collected by clients and delivered to feed generators. It stops there.

A person scrolling through a social app on their phone, illustrating the kinds of engagement figures a post's likes and reposts actually show.

Where the seen event goes
User views the post
Client fires interactionSeen
app.bsky.feed.sendInteractions
Feed generator
The event stops at the feed generator that served the post; the procedure has no route back to the author.

What can you measure on Bluesky today?

Plenty, as long as you stop looking for reach.

AdaptlyPost
AdaptlyPost

Start Your 7-Day Free Trial

All-platform analytics

Social Inbox

AI-powered assistant

QuestionEndpointAvailable
How many likes, reposts, replies, quotes, bookmarks?app.bsky.feed.getPosts or app.bsky.feed.getAuthorFeedYes
Which accounts liked this post?app.bsky.feed.getLikesYes
Which accounts reposted it?app.bsky.feed.getRepostedByYes
Which accounts quoted it?app.bsky.feed.getQuotesYes
How many followers and posts does this account have?app.bsky.actor.getProfileYes, as followersCount, followsCount, postsCount
How many people saw the post?noneNo
What was the impression to engagement rate?noneNo

The named account lists deserve more attention than they get. On most networks you receive a like total and nothing else. Bluesky hands you the accounts, which means you can ask who your reposts come from, whether the same twenty handles carry every launch, and which followers have never once engaged. That is a different kind of analysis from impressions, and on some questions it is a better one.

app.bsky.feed.getPosts takes a uris array with a maxLength of 25, so a batch job checking a month of posts pages through in chunks of 25. app.bsky.feed.getAuthorFeed takes limit with a maximum of 100 and a default of 50, plus a cursor, and it is documented as "Does not require auth", which is why the example above runs against public.api.bsky.app with no token.

An analyst studying a line chart on a laptop, next to the section on turning sampled post counters into a trend over time.

What can a Bluesky analytics tool honestly give you?

Two things, and it should be clear about which is which.

The first is its own publishing record. A scheduler knows what it sent, from which account, at what minute, with what text, hashtags and media, because it did the sending. No API grants that; it is first party data the tool already holds. It is also the half most people are missing, because a spreadsheet of send times is what turns a pile of counters into a comparison.

The second is the public counters, sampled over time. Calling getAuthorFeed or getPosts on a schedule and storing likeCount, repostCount, replyCount, quoteCount and bookmarkCount at each pass turns one number into a curve, which shows how long a post kept collecting engagement after it went out.

Join those two and you can answer real questions: which of your Bluesky posts earned engagement, published at what hour, in what format, next to the same posts on the other networks in your calendar. That join is what AdaptlyPost's Bluesky analytics reports, and the same shape of report covers the other networks through social media analytics.

What no tool can give you, this one included, is impressions, reach, video views or profile visits for a Bluesky post. Those numbers are not in the API, so a dashboard displaying them is either modelling them or relabelling something else. The useful question to ask any vendor is which field the number came from. If the answer is not one of the five counters or a follower total, the number is an estimate.

Scheduling changes none of this either. Publishing through a Bluesky post scheduler gives you a clean send log to measure against; it does not give Bluesky a view counter it does not have.

What this page does not claim

It does not claim Bluesky will never ship view counts. The field list grows: bookmarkCount sits alongside the four older counters, and app.bsky.bookmark is a full namespace with its own create, delete and list endpoints. If a viewCount ever lands, it will appear in lexicons/app/bsky/feed/defs.json before it appears in any client, and that file is public. Check it there rather than trusting a screenshot.

Frequently Asked Questions

Does the Bluesky app show a view count anywhere?

No. The official client renders the same counters the API returns, which are likes, reposts, replies, quotes and bookmarks. There is no view or impression figure on a post, on a profile or in any settings screen, because no endpoint supplies one.

Is there an analytics endpoint anywhere in the AT Protocol lexicons?

No. A search across all 404 lexicon files in bluesky-social/atproto returns no file or field named for analytics, insights or impressions. The four endpoints containing "Stats" all live under tools.ozone, the moderation tooling namespace, and they report on moderation reports rather than on posts.

Can a tool estimate Bluesky impressions from the firehose?

Not measure, only model. The com.atproto.sync firehose streams repository commits, so a consumer sees the creation of app.bsky.feed.like and app.bsky.feed.repost records as they happen. Viewing a post creates no record, which means nothing crosses the firehose when someone reads and scrolls past. Any impression figure derived from it is a model output.

Does app.bsky.feed.sendInteractions let me see who saw my post?

No. It is a procedure, not a query. Clients push interaction events into it, including interactionSeen, and its output schema is an empty object. The events are delivered to the feed generator that served the item, so there is no route back to the author of the post.

Are the engagement counts always present in an API response?

No. The required list on app.bsky.feed.defs#postView is ["uri", "cid", "author", "record", "indexedAt"], which leaves every counter optional. Treat an absent likeCount as an unknown value rather than defaulting it to zero, or a service outage will look like a post that nobody liked.

AdaptlyPost
AdaptlyPost

Start Your 7-Day Free Trial

All-platform analytics

Social Inbox

AI-powered assistant

How many posts can I check for counts in one call?

Twenty five with app.bsky.feed.getPosts, which caps its uris array at maxLength: 25. app.bsky.feed.getAuthorFeed returns up to 100 posts per page with a cursor for the next page, and it needs no authentication, so it is the cheaper route when you want a whole account's recent history.

Does Bluesky's bookmarkCount mean more metrics are coming?

bookmarkCount is the newest of the five counters, added alongside likeCount, repostCount, replyCount and quoteCount, and app.bsky.bookmark already has its own full namespace with create, delete and list endpoints. A viewCount could follow the same path. If it ships, it will show up in lexicons/app/bsky/feed/defs.json before it reaches any client, so that file is the place to check rather than a screenshot.

Do the tools.ozone stats endpoints count as Bluesky post analytics?

Not for posts. The four stats endpoints in the repository, getLiveStats, getHistoricalStats, refreshStats and getReporterStats, all live under tools.ozone, the moderation namespace, and they report on moderation queues and reporters for moderators. None of them touches replies, likes or reach on a post.

Do I need to log in to check a Bluesky post's engagement numbers?

Public counters don't require a login. app.bsky.feed.getAuthorFeed is documented as not requiring auth, which is why a call to public.api.bsky.app with no token returns the same likeCount, repostCount, replyCount, quoteCount and bookmarkCount fields shown in this post. Anything gated behind your own account, such as notification settings, is a different matter, but reading another account's public counters needs nothing more than the URL.

Should I trust a Bluesky dashboard that shows impressions or reach?

Treat it with suspicion if the vendor can't name the field. Impressions, reach, video views and profile visits sit outside the AT Protocol lexicons entirely, so a dashboard showing them is either modelling the number from other signals or relabelling one of the five real counters. Ask which field the number came from; if the answer isn't likeCount, repostCount, replyCount, quoteCount, bookmarkCount or a follower total, it's an estimate.

Was This Article Helpful?

Let us know what you think!

See us more often in Google

One click marks AdaptlyPost as a preferred source, so our articles sit higher in your Top Stories, AI Mode, and AI Overviews.

Before you go...

AdaptlyPost

AdaptlyPost

Schedule your content across all platforms

Manage all your social media accounts in one place with AdaptlyPost.

All-platform analytics

Social Inbox

AI-powered assistant

Related Glossary Terms

Related Articles