Follower counts for the AT Protocol. Icarus reads every
app.bsky.graph.follow record on the network and keeps only what a
follower count needs. 🚀
Ask it how many accounts follow someone, and how many that someone follows:
curl 'https://icarus.atverkackt.de/xrpc/de.atverkackt.icarus.getProfile?actor=pfrazee.com'
{
"did": "did:plc:ragtjsm2j2vknwkz3zp4oxrd",
"handle": "pfrazee.com",
"followersCount": 191055,
"followsCount": 683
}
That is the whole API. One query, four fields. The service holds no posts, no likes, no profile text — only the shape of the graph.
The same query runs on two hosts. They read the network by different routes and answer the identical lexicon, so a client can ask either one.
| Host | Reads | Character |
|---|---|---|
icarus.atverkackt.de |
The Jetstream event archive and the live tail | Current to the second. A lost event stays lost. |
picon.atverkackt.de |
Whole repository snapshots from hubble | Self-correcting. A snapshot repairs whatever drifted. |
Icarus learns the graph from a stream of changes, so it is immediate but can miss an event it never received. Picon folds the complete state of a repository, so a count it reports is the count the repository actually holds. Where the two disagree, believe picon.
Return the follower count and the follow count of one account.
| Name | Type | Required | Meaning |
|---|---|---|---|
actor |
at-identifier |
yes | The DID or the handle of the account. |
Prefer a DID on a hot path. A query by DID never leaves the process. A query by handle makes an outbound DNS and HTTPS request whenever the handle is not already cached.
| Field | Type | Meaning |
|---|---|---|
did |
did |
The authoritative identifier of the account. Always present. |
handle |
handle |
The handle, or handle.invalid when the service has not seen
an identity event for the account. See below.
|
followersCount |
integer |
Follow records that point at this account. |
followsCount |
integer |
Follow records in the repository of this account. |
| Name | Meaning |
|---|---|
AccountNotFound |
The service holds no record of the account. |
Answers 200 with the body ok while the process
serves. It reports liveness only, and says nothing about how far the backfill
has reached.
Both numbers count follow records. The Bluesky AppView counts distinct accounts, so it ignores a second follow record naming an account the author already follows. A repository that holds duplicate follow records therefore reads higher here than it does on Bluesky. Neither number is wrong; they answer different questions.
An identity event only fires when a handle changes, so the service has
never seen a handle for most accounts and reports
handle.invalid for them. A query that names a handle returns that
verified handle. A query that names a DID returns whatever handle the account
claims, unverified.
Treat the DID as the identity and the handle as a label. The
did field is always authoritative.
A followsCount of zero can mean the account follows nobody, or
that the backfill has not reached its repository yet. The follower count fills
in gradually as the sweep folds other repositories; the follow count arrives
all at once, when that account's own repository is read.