# Bluesky Profile Feed Scraper (`fetch_cat/bluesky-profile-feed-scraper`) Actor

Extract public Bluesky profile metadata and recent posts from handles or DIDs.

- **URL**: https://apify.com/fetch\_cat/bluesky-profile-feed-scraper.md
- **Developed by:** [Hanna Nosova](https://apify.com/fetch_cat) (community)
- **Categories:** Social media, Marketing, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.03 / 1,000 result extracteds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Bluesky Profile Feed Scraper

Extract public Bluesky profile metadata and recent public author-feed posts from handles or DIDs.

### At a glance

- **Input:** Public Bluesky handles such as `bsky.app` or DIDs such as `did:plc:z72i7hdynmk6r22z27h6tvur`.
- **Output:** Profile rows and optional post rows with public text, URLs, timestamps, engagement counts, reply/repost flags, embeds, and labels.
- **Best for:** Social listening, account monitoring, public post archives, reporting datasets, and AI summarization inputs.
- **Pricing unit:** A start event per run plus one `result` event for each saved profile or post row.
- **Login required:** No. The Actor reads public Bluesky profile and author-feed data.

### Ready-to-run examples

- [Bluesky Brand Account Monitor](https://apify.com/fetch_cat/bluesky-profile-feed-scraper/examples/bluesky-brand-account-monitor): Track a small public brand account feed for reporting.
- [Export Public Posts from the Apify Bluesky Account](https://apify.com/fetch_cat/bluesky-profile-feed-scraper/examples/export-public-posts-from-the-apify-bluesky-account): Export a focused sample from `apify.com`.
- [Save Bluesky Public Profile Counts Without Posts](https://apify.com/fetch_cat/bluesky-profile-feed-scraper/examples/save-bluesky-public-profile-counts-without-posts): Set `maxPostsPerActor` to `0` for profile metrics only.
- [Collect Bluesky Posts for Media Monitoring](https://apify.com/fetch_cat/bluesky-profile-feed-scraper/examples/collect-bluesky-posts-for-media-monitoring): Save recent public posts for monitoring and summaries.

### What can it do?

Bluesky Profile Feed Scraper collects public account details and recent public posts from Bluesky.

Use it when you need a clean dataset of profile fields, post text, engagement counts, timestamps, labels, embeds, and canonical Bluesky URLs.

It accepts handles such as `bsky.app` and DIDs such as `did:plc:z72i7hdynmk6r22z27h6tvur`.

No Bluesky login is required for public profiles and public author feeds.

### Who is it for?

- **Marketing teams:** Monitor brand accounts and creator activity.
- **Social researchers:** Collect public post samples for trend analysis.
- **Developer relations teams:** Export public updates from ecosystem accounts.
- **Journalists:** Archive public posts from official organizations.
- **Data teams:** Feed profile and post records into warehouses, dashboards, or enrichment pipelines.

### Why use this actor?

- **Handle and DID support:** Use readable handles or stable decentralized identifiers.
- **Profile and post rows together:** Save account metadata and recent author-feed posts in one dataset.
- **Pagination support:** Collect more than the first page of recent author-feed posts.
- **Reply and repost controls:** Include or exclude replies and reposts depending on the workflow.
- **Public-data workflow:** Run without account credentials.
- **Lightweight collection:** Uses public HTTP API requests rather than a browser.

### Output fields

| Field | Description |
| --- | --- |
| `recordType` | `profile` or `post` |
| `inputActor` | Handle or DID from your input |
| `actorDid` | Profile DID |
| `actorHandle` | Current profile handle |
| `profileDisplayName` | Display name when available |
| `profileDescription` | Profile bio |
| `profileAvatar` | Avatar URL |
| `followersCount` | Public follower count |
| `followsCount` | Public following count |
| `postsCount` | Public post count |
| `uri` | AT Protocol post URI |
| `cid` | Post content ID |
| `url` | Browser URL for profile or post |
| `text` | Post text |
| `createdAt` | Post creation timestamp |
| `indexedAt` | Bluesky indexing timestamp |
| `replyCount` | Reply count |
| `repostCount` | Repost count |
| `likeCount` | Like count |
| `quoteCount` | Quote count |
| `bookmarkCount` | Bookmark count when returned |
| `authorHandle` | Post author handle |
| `authorDid` | Post author DID |
| `isReply` | Whether the post is a reply |
| `isRepost` | Whether the feed item is a repost |
| `replyParentUri` | Parent reply URI |
| `replyRootUri` | Root thread URI |
| `embed` | Embedded media/link object |
| `labels` | Public labels returned by Bluesky |

### Pricing

The actor uses pay-per-event pricing.

A small start event is charged once per run.

Each saved profile or post is charged as one result.

| Charge event | When it applies | Price |
| --- | --- | --- |
| `start` | Charged once when a run starts | `$0.005` per run |
| `result` FREE | Each saved profile or post row | `$0.000029973` per row |
| `result` BRONZE | Each saved profile or post row | `$0.000026063` per row, about `$0.026063` per 1,000 rows |
| `result` SILVER | Each saved profile or post row | `$0.000020329` per row |
| `result` GOLD | Each saved profile or post row | `$0.000015638` per row |
| `result` PLATINUM | Each saved profile or post row | `$0.000010425` per row |
| `result` DIAMOND | Each saved profile or post row | `$0.0000072977` per row |

### Example input

```json
{
  "actors": ["bsky.app"],
  "maxPostsPerActor": 25,
  "includeReplies": false,
  "includeReposts": false
}
```

### Input configuration

| Setting | JSON key | Type | Description |
| --- | --- | --- | --- |
| Handles or DIDs | `actors` | array | Public Bluesky handles or DIDs such as `bsky.app`, `apify.com`, or `did:plc:z72i7hdynmk6r22z27h6tvur`. |
| Maximum posts per account | `maxPostsPerActor` | integer | Maximum posts to save for each account after reply/repost filters are applied; use `0` for profile metadata only. |
| Include replies | `includeReplies` | boolean | Set to `true` to save replies in addition to top-level posts. |
| Include reposts | `includeReposts` | boolean | Set to `true` to save reposted feed items. |
| Delay between feed pages | `requestDelayMs` | integer | Optional delay in milliseconds between paginated API requests. |
| Run budget for testing | `maxRunSeconds` | integer | Optional 35–300 second budget for bounded partial-save testing. The final 30 seconds are reserved for saving progress and cleanup. |

### Output example

```json
{
  "recordType": "post",
  "inputActor": "bsky.app",
  "actorDid": "did:plc:z72i7hdynmk6r22z27h6tvur",
  "actorHandle": "bsky.app",
  "profileDisplayName": "Bluesky",
  "url": "https://bsky.app/profile/bsky.app/post/example",
  "text": "Public post text",
  "createdAt": "2026-06-25T19:03:39.125Z",
  "replyCount": 10,
  "repostCount": 20,
  "likeCount": 100,
  "authorHandle": "bsky.app",
  "authorDid": "did:plc:z72i7hdynmk6r22z27h6tvur",
  "isReply": false,
  "isRepost": false
}
```

### How to scrape Bluesky profiles

1. Open the actor.

2. Add one or more handles or DIDs.

3. Choose how many posts to collect per account.

4. Decide whether replies or reposts should be included.

5. Start the run.

6. Export the dataset as JSON, CSV, Excel, XML, or RSS from Apify.

### Tips for better results

- **Use handles for readability:** Use DIDs when you need stable account identifiers.
- **Start small:** Keep the first test run to one account and a low post limit.
- **Clean announcement feed:** Use `includeReplies: false` when you want only account-originated announcements.
- **Full feed context:** Use `includeReposts: true` when reposts matter to the analysis.
- **Monitor safely:** Run on a schedule and deduplicate downstream by `uri`.

### Common workflows

- **Official account exports:** Export recent posts from public organization accounts.
- **Product monitoring:** Track public announcements over time.
- **Creator watchlists:** Build small account lists for social reporting.
- **Profile enrichment:** Add public Bluesky profile metrics to CRM or research records.
- **Research archives:** Save public posts for review, summarization, or compliance workflows.

### Integrations

Send results to Google Sheets for lightweight reporting.

Use webhooks to notify Slack when a scheduled run finishes.

Load JSON output into BigQuery, Snowflake, or Postgres.

Connect the actor to n8n or Make for social-monitoring workflows.

Use Apify datasets as the source for downstream AI summarization.

### API usage

#### Node.js

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fetch_cat/bluesky-profile-feed-scraper').call({
  actors: ['bsky.app'],
  maxPostsPerActor: 25,
});
console.log(run.defaultDatasetId);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient('YOUR_APIFY_TOKEN')
run = client.actor('fetch_cat/bluesky-profile-feed-scraper').call(run_input={
    'actors': ['bsky.app'],
    'maxPostsPerActor': 25,
})
print(run['defaultDatasetId'])
```

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/fetch_cat~bluesky-profile-feed-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"actors":["bsky.app"],"maxPostsPerActor":25}'
```

### MCP and AI agents

You can use this actor from MCP-compatible tools through the official Apify MCP server.

Claude Code setup:

```bash
claude mcp add apify "https://mcp.apify.com?tools=fetch_cat/bluesky-profile-feed-scraper"
```

Claude Desktop JSON example:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=fetch_cat/bluesky-profile-feed-scraper"
    }
  }
}
```

Example prompts:

- "Run the Bluesky Profile Feed Scraper for `bsky.app` and summarize the last 20 posts."
- "Collect profile metrics for these Bluesky handles and return a table."
- "Find which recent posts from this account had the highest engagement."

### Scheduling

Schedule daily or hourly runs for monitoring public accounts.

Use low limits for frequent runs.

Use a larger limit for initial backfills.

Deduplicate downstream by `uri` for posts and `actorDid` for profiles.

### Limits

- **Public data only:** Only public Bluesky data is returned.
- **Unavailable accounts are skipped:** Private, renamed, deleted, or temporarily unavailable accounts cannot be collected.
- **Deleted posts can disappear:** Future runs may no longer return posts removed upstream.
- **Large lists take longer:** Each profile has its own paginated feed.
- **Partial success is possible:** The Actor skips invalid accounts when at least one valid account is provided.

### Legality and responsible use

This actor collects publicly available data.

You are responsible for using the results lawfully and respecting applicable privacy, copyright, platform, and data-protection rules.

Do not use scraped data for spam, harassment, impersonation, or prohibited profiling.

If you store personal data, apply appropriate retention and deletion policies.

### Troubleshooting

#### Why did a handle return no records?

The handle may be invalid, renamed, deleted, or temporarily unavailable.

Try the current handle in a browser or use the account DID.

#### Why are replies missing?

Replies are excluded by default.

Set `includeReplies` to `true` to collect replies.

#### Why are reposts missing?

Reposts are excluded by default.

Set `includeReposts` to `true` to collect repost feed items.

#### Why is the post count lower than requested?

Filters are applied after reading author-feed pages.

If an account mostly posts replies or reposts and those are excluded, fewer records may be saved.

### FAQ

#### Does this require a Bluesky account?

No. It works with public profile and author-feed data.

#### Can I scrape multiple accounts?

Yes. Add multiple handles or DIDs to the `actors` array.

#### Can I get only profile metadata?

Yes. Set `maxPostsPerActor` to `0`.

#### Can I monitor accounts over time?

Yes. Schedule the actor and deduplicate posts by `uri`.

#### Does it return images and embeds?

It returns the public embed object when Bluesky includes it in the feed response.

### Related actors

- [YouTube Channel Videos Scraper](https://apify.com/fetch_cat/youtube-channel-videos-scraper)
- [YouTube Channel Details Scraper](https://apify.com/fetch_cat/youtube-channel-details-scraper)
- [Threads Profile & Posts Scraper](https://apify.com/fetch_cat/threads-profile-posts-scraper)
- [Reddit Scraper](https://apify.com/fetch_cat/reddit-scraper)
- [Product Hunt Scraper](https://apify.com/fetch_cat/product-hunt-scraper)

#### 0.1

- Initial version with configurable inputs and structured results.

### Support

If a run fails, include the run ID, input, and expected account handles when asking for help.

Small reproducible examples are the fastest way to diagnose invalid handles, missing records, or changed upstream behavior.

# Actor input Schema

## `actors` (type: `array`):

Public Bluesky handles or decentralized identifiers to scrape. Examples: bsky.app, apify.com, did:plc:z72i7hdynmk6r22z27h6tvur

## `maxPostsPerActor` (type: `integer`):

How many author-feed posts to save for each account after reply/repost filters are applied.

## `includeReplies` (type: `boolean`):

Save replies in addition to top-level posts.

## `includeReposts` (type: `boolean`):

Save reposted posts that appear in the author feed.

## `requestDelayMs` (type: `integer`):

Optional delay between paginated API requests. Increase if you are collecting many posts from many accounts.

## `maxRunSeconds` (type: `integer`):

Optional lower run budget used to test bounded partial saves. The Actor keeps the last 30 seconds for saving progress and cleanup.

## Actor input object example

```json
{
  "actors": [
    "bsky.app"
  ],
  "maxPostsPerActor": 20,
  "includeReplies": false,
  "includeReposts": false,
  "requestDelayMs": 150
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "actors": [
        "bsky.app"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fetch_cat/bluesky-profile-feed-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "actors": ["bsky.app"] }

# Run the Actor and wait for it to finish
run = client.actor("fetch_cat/bluesky-profile-feed-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "actors": [
    "bsky.app"
  ]
}' |
apify call fetch_cat/bluesky-profile-feed-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=fetch_cat/bluesky-profile-feed-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/BTTs2hz5AhbmtHSeY/builds/94Qs8oRwQtAMZpA0A/openapi.json
