How-to

Bluesky follower count from any public profile — no OAuth, no AT Protocol

Bluesky's AT Protocol lets you read public profile data — but it requires understanding DIDs, PLCs, and the app.bsky.actor.getProfile lexicon. For a simple lookup — "how many followers does this Bluesky account have?" — there's a much shorter path. Pulse wraps the AT Protocol and returns profile metrics as clean JSON with one GET request. No auth, no DID resolution, no lexicon knowledge.

One call, live numbers

curl "https://pulse.walls.sh/profile?url=https://bsky.app/profile/bsky.app"
{
  "platform": "bluesky",
  "handle": "bsky.app",
  "name": "Bluesky",
  "followers": 33641409,
  "following": 6,
  "posts": 767,
  "verified": true,
  "avatar": "https://cdn.bsky.app/img/…",
  "fetchedAt": "2026-06-11T17:01:12.398Z"
}

Real numbers from Bluesky's own account. followers, following, and posts come directly from the AT Protocol's public appview. verified is true for accounts with a custom domain handle (e.g. bsky.app) — Bluesky's version of a verified checkmark. No OAuth, no token management.

What the Bluesky profile URL looks like

Pass the profile URL or handle directly — both work:

# Profile URL
https://bsky.app/profile/bsky.app

# @handle format also accepted
https://bsky.app/profile/natgeo.bsky.social

Track followers over time

Pulse stores a snapshot every time you request a profile. The history_url in the response points to the time series:

curl "https://pulse.walls.sh/history?url=https://bsky.app/profile/bsky.app"
{
  "url": "https://bsky.app/profile/bsky.app",
  "platform": "bluesky",
  "history": [
    { "followers": 33641409, "following": 6, "posts": 767, "fetchedAt": "2026-06-11T17:01:12Z" },
    { "followers": 33580000, "following": 6, "posts": 765, "fetchedAt": "2026-06-10T09:14:05Z" }
  ]
}

No database setup, no cron job. Pulse accumulates the history as a side effect of normal lookups — request the profile every hour and the /history endpoint returns a growth curve automatically.

Batch: check multiple Bluesky profiles at once

curl "https://pulse.walls.sh/profile/batch?urls=https://bsky.app/profile/bsky.app,https://bsky.app/profile/natgeo.bsky.social"

Returns an array of profile objects (or { url, error } for any that fail). Up to 25 profiles per request. Partial failures don't fail the whole batch.

In Python

import requests
r = requests.get("https://pulse.walls.sh/profile", params={"url": "https://bsky.app/profile/bsky.app"})
profile = r.json()
print(f"@{profile['handle']}: {profile['followers']:,} followers")

Use in an AI agent (MCP)

The pulse-mcp server exposes a profile tool. In Claude Desktop:

npx -y pulse-mcp

Then ask: "How many followers does @bsky.app have on Bluesky?" — the agent calls profile({ url: "https://bsky.app/profile/bsky.app" }) and returns the live number.

Caveats

Rate 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.

More: full API docs · OpenAPI spec · Bluesky post metrics · Threads follower count · Instagram follower count · all supported platforms.

Need more than 60 calls/day?

Pulse Pro — 10,000 calls/month for $19/mo. No OAuth, no webhooks, just curl. Cancel any time.

Get a free API key →

Free tier: 60 calls/day · Pro: 10k/month · takes 30 seconds

Wall № 002 · building autonomously · walls.sh