Tutorials
Bluesky profile in curl
One authenticated call to /api/v1/bluesky/profile?handle=bsky.app, the response it returned, and the line that reads one field out of it.
What you need
curl ships with macOS and most Linux distributions, and with Windows 10 and later. There is nothing to install.
The call
curl -H "Authorization: Bearer $HH_KEY" \
"https://honesthook.com/api/v1/bluesky/profile?handle=bsky.app"
What came back
{
"success": true,
"platform": "bluesky",
"endpoint": "bluesky/profile",
"data": {
"author": {
"id": "did:plc:z72i7hdynmk6r22z27h6tvur",
"handle": "bsky.app",
"name": "Bluesky",
"followers": 35065417,
"following": 15,
"posts_count": 864,
"verified": false,
"is_private": null
}
},
"error": null,
"cached": false
}
Recorded response, captured 27 Sep 2026. A live call returns the value at the moment you ask, not this one.
Every field in that capture
| In curl | Type in this capture |
|---|
.success | boolean |
.platform | string |
.endpoint | string |
.data.author.id | string |
.data.author.handle | string |
.data.author.name | string |
.data.author.followers | number |
.data.author.following | number |
.data.author.posts_count | number |
.data.author.verified | boolean |
.data.author.is_private | null |
.error | null |
.cached | boolean |
A field we cannot read comes back null, never 0. A zero would be a claim about the account; null is a fact about our collection.
Reading one field
curl -H "Authorization: Bearer $HH_KEY" \
"https://honesthook.com/api/v1/bluesky/profile?handle=bsky.app" \
| jq -r '.data.author.followers'
jq is a separate tool — it is not part of curl. Without it the command above prints the whole envelope, which is the block below.
Bluesky's AT Protocol is public and documented, and this is the cheapest read of the set. As with GitHub, the interesting part is not access — it is identity.
The handle is not the identity
On Bluesky a handle is a domain name pointed at an account. It can be changed, released and taken by someone else. The thing that does not move is the DID, and that is what this endpoint returns as id.
If you are storing Bluesky accounts, store the DID. A table keyed on handles will quietly follow the wrong account the first time somebody renames, and nothing will error.
What you are calling
One authenticated GET to our endpoint, with your key in an Authorization header. The handle in the example is the one that produced the recorded response below, and the response carries its DID.
What comes back is the same envelope as every other platform here, so the client you wrote for one reads this one too.
Before you copy the block
Keep the key in an environment variable — all three examples read HH_KEY.
Then read the field list. Bluesky has no private profile at all, so that field is null rather than false — absent is not the same as negative, and this envelope keeps the two apart.