> **For coding agents and LLMs:** This is one Social Fetch marketing page (markdown export). For API orientation start with [`/llms.txt`](https://www.socialfetch.dev/llms.txt); for auth and crawl rules use [`/agents.txt`](https://www.socialfetch.dev/agents.txt); for every operation use [`/llms-endpoints.txt`](https://www.socialfetch.dev/llms-endpoints.txt).

## This page

- **On-site (HTML):** <https://www.socialfetch.dev/platforms/bluesky>
- **Markdown (.mdx) URL:** <https://www.socialfetch.dev/platforms/bluesky.mdx>

---

# Bluesky scraper API. Skip the firehose.

Profiles, posts and post lookups by URL over plain REST, for when you need the data, not a relay. Same key as X and Threads.

- No App Password
- Plain REST

Bluesky runs on AT Protocol — you can resolve handles, talk to a PDS, or subscribe to the firehose yourself. Social Fetch covers three scheduled lookups on the same key as TikTok and X: profile by handle, paginated posts, and one post by bsky.app URL.

Every response uses `{ data, meta }` with `data.lookupStatus`, `meta.requestId`, and `meta.creditsCharged`. Use AT Protocol for Bluesky-native apps, relays, and writes. Use Social Fetch for public read lookups without App Passwords or a firehose consumer.

## What you can get

- Profile cards by handle — custom domains and `*.bsky.social`, with DID as `platformUserId`.
- Follower, following, and post counts on the profile metrics object.
- Paginated public posts for a handle (`nextCursor` / `hasMore`).
- Single post by bsky.app URL — text, author, likes/reposts/replies/quotes.
- Normalized embeds (link cards, images, video, quoted records) when present.
- Top-level reply samples on the post-by-URL route when the lookup includes them.
- Same API key and envelope as Instagram, X, and the rest of the catalog.

## Bluesky endpoints

| Endpoint | Request | Credits | Docs |
| --- | --- | --- | --- |
| Profile | GET /v1/bluesky/profiles/{handle} | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/bluesky/profiles/handle/get) |
| Profile posts | GET /v1/bluesky/profiles/{handle}/posts | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/bluesky/profiles/handle/posts/get) |
| Post | GET /v1/bluesky/posts | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/bluesky/posts/get) |

## How to start

1. **Create an API key.** Sign up at Social Fetch and copy a key (`sfk_…`). New accounts get 100 free credits — enough to resolve a handle, page one feed, and fetch one post URL against live data.
2. **Resolve the handle first.** Call `GET /v1/bluesky/profiles/{handle}` with `x-api-key`. Pass the handle with or without `@`. Branch on `data.lookupStatus` before you spend credits on posts; store the DID from `data.profile.platformUserId` as your stable Bluesky id.
3. **Pick feed vs URL.** Page recent posts with `GET /v1/bluesky/profiles/{handle}/posts` (pass `cursor` from `data.page.nextCursor`). When you already have a bsky.app permalink, use `GET /v1/bluesky/posts?url=…` instead. Log `meta.requestId` and bill against `meta.creditsCharged`.

## Pricing

Documented Bluesky routes charge 1 credit per successful completed lookup. Confirm on each operation page and with `meta.creditsCharged` — that field is the billing source of truth. Credits never expire on pay-as-you-go packs. Free signup credits apply.

## Compared with the official API

AT Protocol and Bluesky APIs (AppView, PDS XRPC, firehose/Jetstream) are the native stack for clients, relays, and writes. Social Fetch wraps public read lookups on one REST key — no App Password, no firehose consumer, no creator OAuth.

## FAQ

### Is there a Bluesky scraper API that works without an App Password?

Yes. Social Fetch Bluesky routes read public profile and post data. You authenticate to Social Fetch with an API key (`x-api-key`). You do not create a Bluesky App Password or open an AT Protocol session as the user whose public data you are fetching.

### How is Social Fetch different from the Bluesky firehose or AT Protocol DIY?

The firehose streams network events for real-time indexing. AT Protocol XRPC handles Bluesky-native apps and writes. Social Fetch is point lookup: handle or post URL in, structured JSON out, same envelope as TikTok and X. Not a relay, firehose subscription, or PDS client.

### What Bluesky data does Social Fetch cover?

Three marketplace operations: `GET /v1/bluesky/profiles/{handle}` (profile card and metrics), `GET /v1/bluesky/profiles/{handle}/posts` (paginated public feed), and `GET /v1/bluesky/posts` (one post by public URL, including embed and reply samples when returned). Exact schemas live under `/docs/api` and on this hub's endpoint list.

### Do custom domain Bluesky handles work?

Yes. Pass the handle as used on Bluesky — `*.bsky.social` or a custom domain — with or without a leading `@`. On a found profile, `data.profile.platformUserId` is the DID, which is the stable identifier if the handle later changes.

### Profile card vs profile posts vs post-by-URL — which route?

Use the profile route for identity and aggregate counts. Use profile posts to page a handle's recent public feed. Use post-by-URL when you already have a bsky.app permalink from an alert, CRM, or paste. They are separate operations; confirm a handle with the profile GET before treating an empty feed as "no posts."

### How much does the Bluesky API cost?

You buy credit packs (or use the 100 free signup credits). Documented Bluesky lookups are 1 credit each on success. Always trust `meta.creditsCharged` on the response. There is no required monthly subscription for pay-as-you-go packs.

### Does Social Fetch return Bluesky DIDs, embeds, and reply counts?

On found profile lookups, the DID is `data.profile.platformUserId`, with followers/following/posts under `data.metrics`. On post routes, rows can include AT URI id, cid, text, author card, likes/reposts/replies/quotes, and a normalized `embed` when present. The post-by-URL route may also return top-level `replies`. Treat empty reply arrays as "none returned," not proof the thread has zero replies on Bluesky.

### Can I access private or gated Bluesky content?

No. Only publicly visible profiles and posts. Missing or inaccessible targets resolve through `data.lookupStatus` (for example `not_found`) rather than inventing empty public cards.

### Is scraping Bluesky data legal?

Social Fetch returns publicly visible data. You are responsible for how you use it under Bluesky's terms, AT Protocol norms, applicable law, and your own compliance review. We do not give legal advice.

### Can I use the Bluesky API in production with agents or MCP?

Yes. Routes are synchronous REST with typed lookup outcomes, request IDs, and credit metering. The same operations appear as MCP tools and can be reached via Ask (`POST /v1/ask`) when you want plain-English routing before pinning a typed path. Production cron should call the explicit Bluesky GETs with an API key.

## Related

- [Bluesky Profile API](https://www.socialfetch.dev/platforms/bluesky/profiles-handle): Handle → card, DID, and follower metrics (`GET /v1/bluesky/profiles/{handle}`).
- [Bluesky profile posts API](https://www.socialfetch.dev/platforms/bluesky/profiles-handle-posts): Page a handle's public feed with cursor pagination.
- [Bluesky Post API](https://www.socialfetch.dev/platforms/bluesky/posts): Single post by bsky.app URL — text, embeds, engagement, replies.
- [Ask in plain English](https://www.socialfetch.dev/ask): Route a natural-language Bluesky question to the matching marketplace operation.
- [Hosted MCP](https://www.socialfetch.dev/mcp): Call Bluesky tools from Cursor or Claude with the same credit metering as REST.
