Analytics
The Bluesky post metrics and account stats returned by the analytics endpoints, and the errors they report.
Read likes, replies, reposts, quotes and bookmarks for any Bluesky post, and follower counts for a connected account. No extra permission is needed beyond the App Password.
Metrics
| Field | Bluesky metric | Notes |
|---|---|---|
impressions | None | Always null |
reach | None | Always null |
plays | None | Always null |
likes | likeCount | |
comments | replyCount | |
shares | repostCount + quoteCount | Reposts and quotes together |
saves | bookmarkCount | |
engagement | Calculated | likes + comments + shares + saves |
A metric Bluesky does not return for a post is null, not 0.
Read Post Analytics
Pass the Onepostly post id, or the post's at:// URI plus accountId for a post published outside Onepostly. See Targeting Posts.
import { Configuration, AnalyticsApi } from "@onepostly/sdk";
const analyticsApi = new AnalyticsApi(
new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);
const response = await analyticsApi.getAnalytics({
post: "1699f415-7fb6-43f4-9d2a-c447491f32a8",
metrics: "views,reach,profile_views",
period: "day",
});
console.log(response);{
"analytics": {
"post": "1699f415-7fb6-43f4-9d2a-c447491f32a8",
"status": "ready",
"fetchedAt": "2026-08-25T10:00:00.000Z",
"subjects": [
{
"scope": "destination",
"subjectId": "d4e5f6a7-8b9c-4d0e-8f1a-2b3c4d5e6f7a",
"accountId": "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
"platform": "bluesky",
"externalPostId": "17895695668004550",
"status": "ready",
"metrics": {
"impressions": null,
"reach": null,
"likes": 123,
"comments": 12,
"shares": 4,
"saves": 2,
"plays": null,
"engagement": 0.14
},
"fetchedAt": "2026-08-25T10:00:00.000Z",
"expiresAt": "2026-09-01T10:00:00.000Z",
"error": null,
"externalUrl": "https://bsky.app/profile/you/post/17895695668004550"
}
]
}
}For day-by-day values, use the Daily Timeline.
Account Stats
Returns live counts for a connected account. On Bluesky, followerCount is the follower count, followingCount is the number of accounts it follows, and videoCount is the account's total number of posts. likesCount is always null.
import { Configuration, ConnectionsApi } from "@onepostly/sdk";
const connectionsApi = new ConnectionsApi(
new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);
const response = await connectionsApi.getConnectionStats({
id: "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
include: "messenger-profile,reviews",
limit: 20,
});
console.log(response);{
"accountId": "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
"platform": "bluesky",
"status": "ready",
"stats": {
"followerCount": 1234,
"followingCount": 56,
"likesCount": null,
"videoCount": 12
},
"fetchedAt": "2026-08-25T10:00:00.000Z"
}Recent Posts
GET /v1/connections/{id}/media lists the account's recent posts that carry images or video, with likes, replies and reposts for each. Reposts the account made are included, and the first page also includes posts the account published through Onepostly. views is always null. Pass the returned nextCursor as cursor to read the next page.
import { Configuration, ConnectionsApi } from "@onepostly/sdk";
const connectionsApi = new ConnectionsApi(
new Configuration({ apiKey: process.env.ONEPOSTLY_API_KEY })
);
const response = await connectionsApi.listConnectionMedia({
id: "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
limit: 20,
kind: "media",
audioType: "music",
});
console.log(response);{
"accountId": "a1b2c3d4-e5f6-4a7b-8c9d-e0f1a2b3c4d5",
"platform": "bluesky",
"items": [
{
"id": "7412345678901234567",
"title": "My trip",
"description": "Weekend recap #travel",
"coverUrl": "https://cdn.onepostly.com/media/cover.jpg",
"shareUrl": "https://www.tiktok.com/@you/video/7412345678901234567",
"createdAt": "2026-08-20T10:00:00.000Z",
"durationSec": 42,
"metrics": {
"likes": 123,
"comments": 12,
"shares": 4,
"views": 4567
}
}
],
"nextCursor": "20"
}Analytics Status
A post that Bluesky has not indexed yet reports pending with POST_NOT_FOUND until its counts appear. A post that was deleted on Bluesky reports the same code. The meaning of every status is in Analytics Status.
Errors
Post analytics codes appear in subjects[].error.code. Account stats and recent posts return failures in the error envelope.
| Code | Cause | Fix |
|---|---|---|
NOT_PUBLISHED | The Bluesky destination is not published yet | Read analytics after post.platform.published |
INVALID_EXTERNAL_ID | The post id is not an at:// URI | Pass the post's at:// URI |
POST_NOT_FOUND | Bluesky has not indexed the post yet, or it was deleted | Read analytics again in a few minutes; if the code stays, check that the post still exists |
ANALYTICS_PERMISSION | The App Password was revoked or deleted | Create a new App Password and reconnect the account |
TOKEN_INVALID | The App Password was revoked or deleted (account stats and recent posts) | Create a new App Password and reconnect the account |
RATE_LIMITED | Bluesky throttled the request | Call again later |
PLATFORM_UNAVAILABLE | Bluesky was unavailable | Call again later |
ANALYTICS_FAILED | Bluesky returned an error for this post | Read error.message for the Bluesky reason |
STATS_FAILED | Bluesky did not return the account profile | Call again; read the error message if it repeats |
LIST_FAILED | Bluesky did not return the account's posts | Call again; read the error message if it repeats |