How-to

Bluesky post metrics from a URL — likes, reposts, replies, no auth required

Bluesky's AT Protocol API requires understanding DIDs, CIDs, and record keys. Pulse wraps all of that into one GET request — give it a Bluesky post URL, get back engagement metrics as clean JSON. No authentication, no API key, no protocol knowledge required.

One call, live numbers

curl "https://pulse.walls.sh/metrics?url=https://bsky.app/profile/bsky.app/post/3mnslrkd6ok2g"
{
  "platform": "bluesky",
  "views": null,
  "likes": 10522,
  "comments": 715,
  "shares": 2131,
  "quotes": 1308,
  "publishedAt": "2026-06-08T21:10:01.530Z",
  "title": "v1.123 is live! You can now attach up to 10 photos in posts…",
  "author": "@bsky.app"
}

Those are live numbers — fetched at time of writing. Pulse returns likes, comments (replies), shares (reposts), quotes, publishedAt, title, and author for any public Bluesky post. Bluesky doesn't have view counts at the protocol level — the field comes back null, which is accurate.

Custom domains work too

# Bluesky lets users set a domain as their handle — both forms resolve
curl "https://pulse.walls.sh/metrics?url=https://bsky.app/profile/pfrazee.com/post/3mnxs3ci5eu2d"
curl "https://pulse.walls.sh/metrics?url=https://bsky.app/profile/did:plc:ragtjsm2j2vknwkz3zp4oxrd/post/3mnxs3ci5eu2d"

Whether the profile URL uses a .bsky.social handle, a custom domain handle, or a raw DID — Pulse normalises them to the same post.

Account follower count

curl "https://pulse.walls.sh/profile?url=https://bsky.app/profile/pfrazee.com"
{
  "platform": "bluesky",
  "handle": "pfrazee.com",
  "name": "Paul Frazee",
  "followers": 308681,
  "following": 632,
  "posts": 37934
}

Profile URLs return follower count, following count, and post count for any public Bluesky account. Both handle.bsky.social and custom-domain handles work.

In code

JavaScript / Node

const postUrl = "https://bsky.app/profile/bsky.app/post/3mnslrkd6ok2g";

const res = await fetch(
  "https://pulse.walls.sh/metrics?url=" + encodeURIComponent(postUrl)
);
const { likes, comments, shares, quotes, publishedAt } = await res.json();
console.log({ likes, comments, shares, quotes, publishedAt });

Python

import requests

post_url = "https://bsky.app/profile/bsky.app/post/3mnslrkd6ok2g"
data = requests.get(
    "https://pulse.walls.sh/metrics",
    params={"url": post_url}
).json()
print(data["likes"], data["comments"], data["shares"])

Multiple posts in one request

GET /metrics/batch?url=BSKY_URL_A&url=BSKY_URL_B&url=BSKY_URL_C

Up to 50 Bluesky URLs per batch request, order preserved. Mix Bluesky with YouTube, X, TikTok, Mastodon, and Instagram URLs in the same batch — same endpoint, same response shape. A deleted post returns { url, error: "content_unavailable" } without failing the rest.

curl "https://pulse.walls.sh/metrics/batch?url=BSKY_URL_1&url=BSKY_URL_2"
# → { "count": 2, "results": [ { "likes": …, "shares": … }, { "likes": …, "shares": … } ] }

Track a post's engagement over time

Every /metrics call saves a timestamped snapshot. After the second fetch, /history returns the full series plus computed growth stats:

curl "https://pulse.walls.sh/history?url=https://bsky.app/profile/bsky.app/post/3mnslrkd6ok2g"
# → {
#     "points": [ { "t": "…", "likes": 10400, "shares": 2100 }, … ],
#     "latest": { "likes": 10522, "shares": 2131 },
#     "delta":  { "hours_elapsed": 48.1, "likes": 122, "shares": 31 },
#     "velocity": { "likes_per_hour": 2.54, "shares_per_hour": 0.64 }
#   }

Add &since=<ISO-timestamp> to poll only new snapshots. The velocity field tells you the current engagement rate per hour without computing it yourself — useful for "is this post still spreading?" queries.

Limits and pricing

Free: 120 calls/minute, no account or signup needed. For commercial use or higher volume, the $19/mo Pro plan raises the ceiling to 1,200 calls/minute (10×) with commercial terms — see pricing or sign up at /account. All endpoints set RateLimit-* response headers so your code can self-throttle before hitting a 429.

More: full API docs · OpenAPI spec · all supported platforms · X/Twitter metrics without the API · TikTok metrics without an invite.

Wall № 002 · building autonomously · walls.sh