# Bluesky Community Finder: Starter Packs & Feeds (`datagrit/bluesky-community-finder`) Actor

Find Bluesky starter packs, custom feeds and curated lists by topic, with join counts, feed likes and full member lists with follower counts.

- **URL**: https://apify.com/datagrit/bluesky-community-finder.md
- **Developed by:** [datagrit](https://apify.com/datagrit) (community)
- **Categories:** Social media, Marketing
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### What does Bluesky Community Finder do?

Bluesky Community Finder builds a catalog of the communities on Bluesky: starter packs, custom feeds and curated lists. Search by topic or point it at specific accounts, and every starter pack, feed or list comes back as one clean row with its creator, dates, size and popularity. Starter packs carry all-time and weekly join counts and the member count. Feeds carry likes and, if you ask for it, a live check of whether the feed is still online and valid. Lists carry their purpose (curate, moderation or reference) and member count. Turn on members and every pack or list is followed by one row per account, with followers, follows, posts and verification status. It reads Bluesky's public API, needs no login or API key, and exports to JSON, CSV or Excel.

### Who is it for?

- **Community managers and marketers** looking for the starter packs and feeds that already gather an audience around a topic, and for the people inside them.
- **Creators and publishers** checking where their niche lives on Bluesky and which packs are still gaining joins.
- **Researchers and analysts** mapping topic communities, comparing how many people join packs and like feeds.
- **Developers and data teams** who need a scheduled, deduplicated feed of new packs, feeds and lists for a dashboard or an alert.

### Example output

A starter pack row:

```json
{
  "type": "starterPack",
  "url": "https://bsky.app/starter-pack/emilyliu.me/3kvq2t2ctis2z",
  "name": "Bluesky for Journalists",
  "description": "Recommended feeds and users for journalists / news!",
  "creatorHandle": "emilyliu.me",
  "createdAt": "2024-06-25T05:30:27.442Z",
  "joinedAllTimeCount": 37,
  "joinedWeekCount": 0,
  "memberCount": 52,
  "feedCount": 3,
  "query": "journalists",
  "found": true
}
```

A member row:

```json
{
  "type": "member",
  "handle": "dylanfreedman.nytimes.com",
  "displayName": "Dylan Freedman",
  "communityName": "Bluesky for Journalists",
  "followersCount": 12453,
  "followsCount": 334,
  "postsCount": 441,
  "isVerified": false,
  "found": true
}
```

The `type` field tells the row kinds apart, so one dataset can be filtered into packs, feeds, lists and members.

### Pricing

You pay per result row: each starter pack, feed, list or member returned is one result, and the price per result is set on the Actor page and shown before you run it. The free example with empty input is not charged. There are no charges for rows that were filtered out or skipped as already seen, and a search that finds nothing returns a single status row with `found: false` that is not billed. Set a maximum charge per run in the Apify console to cap spending; the Actor stops cleanly when it is reached.

### How to use it

1. Choose what to find: starter packs, custom feeds, or lists.
2. Add search terms (for example `journalists` or `science`) or account handles such as `bsky.app`. Starter packs and feeds can be searched by topic. Lists cannot be searched by topic, so use handles for them.
3. Narrow the results with the filters below, and switch on members if you want the accounts inside each pack or list.
4. Set the maximum number of communities and run the Actor.

If you leave search terms and handles empty, the Actor runs a small free example (up to 10 results, not charged) so you can see the output before you configure anything; the status message says so.

#### Filters

- **Name or description contains**: keep results matching any of your words.
- **Minimum joins** (starter packs): people who joined through the pack, all time.
- **Minimum members** (starter packs and lists): accounts inside the community.
- **Minimum likes** (feeds).
- **Created after**: packs use their creation date, feeds and lists the date Bluesky indexed them.
- **List type** (lists): curate, moderation or reference.
- **Check feed health** and **Only feeds that are online** (feeds): one extra request per feed to confirm it still answers and returns valid posts.
- **Only communities not seen before**: skip anything an earlier run with the same search terms, handles and filters already returned, so a scheduled run delivers only new packs and feeds.

A filter that does not apply to the chosen type is listed in the status message instead of failing silently.

#### Members

With **Include members**, each starter pack or list is followed by up to your chosen number of member rows. **Add follower counts to members** looks up followers, follows, posts and verification for every member. Member rows are separate results and are billed like any other row; the limit on communities does not cap them, so set the maximum members per community to match your budget.

### Good to know

- Bluesky's public API returns member counts for starter packs only from the detail of each pack, so the Actor makes one extra request per pack. Feeds and lists carry their counts in the listing.
- The status message at the end of every run reports how many member counts, feed health checks and member profiles were actually retrieved. If Bluesky stops returning one of them for every record, the run fails instead of filling the field with zeros. Member lists that Bluesky no longer serves are skipped and counted (`Member lists unavailable`), and the run fails only when none can be read; the same applies to listing fields such as join, like and member counts and to member records in an unexpected shape.
- Accounts that were deactivated after being added to a list keep their member row, with follower counts set to null.
- Only public data is read. Private accounts, direct messages and anything behind a login are out of reach.

### FAQ

**Does it need a Bluesky account?** No. It uses the public API without login.

**Can I search lists by topic?** Bluesky has no search for lists. Give the handles of the accounts whose lists you want.

**How do I get only new packs each day?** Schedule the Actor with the same input and switch on "Only communities not seen before".

**Something looks wrong in the data.** Open an issue on the Actor page with the input you used and the run link.

### Related Actors

Use it together with other datagrit Actors that work on public creator and audience data: the Substack Newsletter Sponsorship Prospect Finder to find newsletters and sponsors in the same niche, the YouTube Transcript Scraper - Channels & Playlists to study what creators in a community talk about, and the Google News Monitor - Full Text & Real URLs to follow the news around a topic you mapped on Bluesky.

# Changelog

This Actor's version history is a separate document: https://apify.com/datagrit/bluesky-community-finder/changelog.md

# Actor input Schema

## `mode` (type: `string`):

Starter packs: curated follow-packs you can search by topic. Feeds: custom feed generators you can search by topic. Lists: curated, moderation or reference lists published by the accounts in Handles.

## `queries` (type: `array`):

Topics to search, for example journalists, science or birds. Each term is searched separately. Works for starter packs and feeds. Lists cannot be searched by topic: use Handles. Leave Search terms and Handles empty to get a free example of up to 10 results.

## `handles` (type: `array`):

Bluesky handles, for example bsky.app, or profile URLs such as https://bsky.app/profile/bsky.app. Returns the starter packs, feeds or lists that these accounts created, depending on the mode.

## `maxItems` (type: `integer`):

Stop after this many starter packs, feeds or lists in total across all search terms and handles. Member rows are not counted here; they come on top when Include members is on.

## `textContains` (type: `array`):

Keep only results whose name or description contains at least one of these words (case-insensitive).

## `minJoinedAllTime` (type: `integer`):

Starter packs only: keep packs that at least this many people joined through, all time. Ignored for feeds and lists.

## `minMembers` (type: `integer`):

Starter packs and lists only: keep communities with at least this many accounts. Ignored for feeds.

## `minLikes` (type: `integer`):

Feeds only: keep feeds with at least this many likes. Ignored for starter packs and lists.

## `publishedAfter` (type: `string`):

Keep communities created or first indexed on or after this date, for example 2025-06-01. Starter packs use their creation date; feeds and lists use the date Bluesky indexed them.

## `listPurpose` (type: `string`):

Lists only: curate lists group accounts worth following, mod lists are moderation lists, reference lists are general collections. Ignored for starter packs and feeds.

## `checkFeedHealth` (type: `boolean`):

Feeds only: ask Bluesky whether each feed is online and valid, one extra request per feed. Without it, isOnline and isValid stay null.

## `onlyOnlineFeeds` (type: `boolean`):

Feeds only: drop feeds that are offline or invalid. Turns on the health check automatically.

## `includeMembers` (type: `boolean`):

Starter packs and lists only: add one row per member account after each community. Each member row is a separate billed result.

## `maxMembersPerCommunity` (type: `integer`):

Cap on member rows per starter pack or list when Include members is on.

## `includeMemberStats` (type: `boolean`):

When Include members is on, look up followers, follows, posts and verification for every member (one request per 25 members).

## `onlyNewSinceLastRun` (type: `boolean`):

Skip starter packs, feeds and lists already returned by an earlier run with the same search terms, handles and filters. Only delivered results are remembered.

## `proxyConfiguration` (type: `object`):

Optional proxy. Bluesky's public API needs none; leave disabled unless you have a reason.

## Actor input object example

```json
{
  "mode": "starterPacks",
  "queries": [
    "journalists"
  ],
  "maxItems": 20,
  "minJoinedAllTime": 0,
  "minMembers": 0,
  "minLikes": 0,
  "listPurpose": "any",
  "checkFeedHealth": false,
  "onlyOnlineFeeds": false,
  "includeMembers": false,
  "maxMembersPerCommunity": 100,
  "includeMemberStats": true,
  "onlyNewSinceLastRun": false,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All extracted records as a dataset.

# 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 = {
    "queries": [
        "journalists"
    ],
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("datagrit/bluesky-community-finder").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 = {
    "queries": ["journalists"],
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("datagrit/bluesky-community-finder").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "queries": [
    "journalists"
  ],
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call datagrit/bluesky-community-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datagrit/bluesky-community-finder"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/dlWK1f8KwiiB73ihH/builds/D2WEOnwQmhfeKj9Tx/openapi.json
