Bluesky API: Get profile
Looks up a public Bluesky profile by handle or profile link, including bio, audience counts and join date. A bare name first checks its .bsky.social handle, then the top relevant people-search result.
Unofficial. Not affiliated with or endorsed by Bluesky.
Inputs
Values from the run on Oct 23, 2026, shown under Output.
- Username, required
username Account handle with or without @, a Bluesky profile link, or a bare name such as nytimes.
nytimes
Input as JSON
{ "username": "nytimes"}Output
{ "bio": "We seek the truth and help people understand the world. Not a subscriber? Your first month is now free in our app. https://nytimes.onelink.me/Xpht/zbx4nci9" , "did": "did:plc:eclio37ymobqex2ncko63h4r", "handle": "@nytimes.com", "followers": 1353269, "following": 123, "joined_date": "2023-06-05", "display_name": "The New York Times", "profile_link": "https://bsky.app/profile/nytimes.com" , "number_of_posts": 44611, "avatar_image_link": "https://cdn.bsky.app/img/avatar/plain/did:plc:eclio37ymobqex2ncko63h4r/bafkreidvvqj5jymmpaeklwkpq6gi532el447mjy2yultuukypzqm5ohfju" }Code
curl https://api.fous.com/v1/runs \ -H "Authorization: Bearer $FOUS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"method":"bsky.app/get_profile","input":{"username":"nytimes"}}' # Save as fous.py, then run: python3 fous.pyimport json, os, timefrom urllib.error import HTTPErrorfrom urllib.request import Request, urlopenAPI = "https://api.fous.com/v1/runs" KEY = os.environ["FOUS_API_KEY"]HEADERS = { "Authorization": f"Bearer {KEY}", "Content-Type": "application/json" ,}def call(url, body=None): data = json.dumps(body).encode() if body else None request = Request(url, data, HEADERS) try: with urlopen(request, timeout=120) as r: return r.status, json.load(r) except HTTPError as error: message = json.load(error)["error"]["message"] raise RuntimeError(message) from errorstatus, run = call(API, { "method": "bsky.app/get_profile" , "input": { "username": "nytimes" }})# 202: still going after 30 s. Ask again until it ends.while status == 202: time.sleep(2) status, run = call(f"{API}/{run['id']}")print(json.dumps(run["data"], indent=2))// Save as fous.mjs, then run: node fous.mjsconst api = "https://api.fous.com/v1/runs" ;const headers = { Authorization: `Bearer ${process.env.FOUS_API_KEY}`, "Content-Type": "application/json" ,};let response = await fetch(api, { method: "POST", headers, body: JSON.stringify({ "method": "bsky.app/get_profile" , "input": { "username": "nytimes" } }), signal: AbortSignal.timeout(120_000),});let run = await response.json();// 202: still going after 30 s. Ask again until it ends.while (response.status === 202) { await new Promise((done) => setTimeout(done, 2_000)); response = await fetch(`${api}/${run.id}`, { headers }); run = await response.json();}if (!response.ok) throw new Error(run.error.message);console.log(run.data);# Connect your agent to Fous once, over MCP (Streamable HTTP):# https://api.fous.com/mcp# Set FOUS_API_KEY first: create a key at https://app.fous.com/keys.# Claude Codeclaude mcp add \ --scope user \ --transport http fous https://api.fous.com/mcp \ --header "Authorization: Bearer ${FOUS_API_KEY:?Set FOUS_API_KEY to your Fous API key}"# Codexcodex mcp add fous \ --url https://api.fous.com/mcp \ --bearer-token-env-var FOUS_API_KEY# Cursor, VS Code, Windsurf, Cline and morenpx -y add-mcp https://api.fous.com/mcp -g -n fous \ --header "Authorization: Bearer ${FOUS_API_KEY:?Set FOUS_API_KEY to your Fous API key}"# Then ask your agent:# "Use Fous to run bsky.app/get_profile# with {"username":"nytimes"}"Over HTTP, the answer’s data holds the output. A run still going after 30 seconds answers 202 with its id: ask GET /v1/runs/{id} until it ends.
Schema
Input schema
{ "type": "object", "required": [ "username" ], "properties": { "username": { "type": "string", "examples": [ "nytimes" ], "description": "Account handle with or without @, a Bluesky profile link, or a bare name such as nytimes." } }}Output schema
{ "type": "object", "required": [ "handle", "display_name", "bio", "followers", "following", "number_of_posts", "joined_date", "avatar_image_link", "profile_link", "did" ], "properties": { "bio": { "type": [ "string", "null" ], "description": "Profile biography." }, "did": { "type": "string", "description": "The account's decentralized identifier.", "x-fous-developer": true }, "handle": { "type": "string", "description": "Account handle, with @." }, "followers": { "type": [ "integer", "null" ], "description": "Number of followers." }, "following": { "type": [ "integer", "null" ], "description": "Number of accounts followed." }, "joined_date": { "type": [ "string", "null" ], "format": "date", "description": "Date the public profile was created, YYYY-MM-DD." }, "display_name": { "type": [ "string", "null" ], "description": "Name displayed on the profile." }, "profile_link": { "type": "string", "description": "Link to the Bluesky profile." }, "number_of_posts": { "type": [ "integer", "null" ], "description": "Number of posts." }, "avatar_image_link": { "type": [ "string", "null" ], "description": "Link to the profile avatar image." } }, "additionalProperties": false}- Price
- 1 credit per completed run (1¢ with pay as you go); failed runs are free.
- Method
bsky.app/get_profile- Returns
- handle, display name, bio, followers, following, post count, joined date, avatar link, profile link, DID
Use it from your agent
Give your agent this line. It reads SKILL.md, gets a Fous API key and connects the Fous MCP server. Its run then takes the method bsky.app/get_profile with the inputs above.
Ask your agent
- Can you pull up the Bluesky profile for @nytimes and tell me how many followers it has?
- I want to see the bio and join date for the bsky.social account jack.
- Look up the Bluesky profile at https://bsky.app/profile/bsky.app and give me its DID and post count.
- What's the display name and following count for the handle @atproto.bsky.social?
- Find the Bluesky account for a person named Maria Lopez and show me her avatar and profile link.
See more
All Bluesky methodsLists an account's latest public Bluesky posts, newest first. Replies and reposts are left out unless requested; a repost's time is when the account reposted it.
bsky.app/list_recent_postsSearches public Bluesky posts for words, optionally ordered by latest or top and filtered by date, author or language. Search indexing may lag behind new posts.
bsky.app/search_postsGets the public X profile for a username or profile link, including counts, verification, images and account details. Does not include posts or a timeline.
x.com/get_profileGets a public Mastodon profile by handle or profile link, with its bio, counts, dates and profile fields. Major servers are read directly. Other servers are looked up through mastodon.social, and their home-server account ID is not available.
mastodon.social/get_profileGets a TikTok creator's public profile and totals (followers, following, likes, videos) from a username, @handle or profile link. Profiles not visible to public visitors cannot be returned.
tiktok.com/get_profileLooks up public Instagram account totals, engagement and grade on Social Blade by handle or profile link. Daily history and 30-day follower change need a Social Blade sign-in, so they are not returned.
socialblade.com/get_instagram_statsGets a public Threads profile by username or profile link, with bio, followers, verification, picture and bio links. Private profiles are not returned.
threads.com/get_profileGets a TikTok creator's Social Blade profile totals, grade when shown, 30-day follower and like changes, and up to 14 days of daily totals, from a TikTok handle or a TikTok or Social Blade profile link. Counts reflect Social Blade's recorded and sometimes rounded figures.
socialblade.com/get_tiktok_stats