# Bluesky Scraper - Search, Profiles & Posts (`parsebird/bluesky-scraper`) Actor

Scrape Bluesky data: keyword post search, author feeds, profiles, followers, and follows. Filter by date, language, author, domain, hashtag, and engagement. Export JSON, CSV, Excel.

- **URL**: https://apify.com/parsebird/bluesky-scraper.md
- **Developed by:** [ParseBird](https://apify.com/parsebird) (community)
- **Categories:** Social media, Lead generation, News
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.10 / 1,000 record scrapeds

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/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 Scraper - Search, Profiles & Posts

Bluesky Scraper pulls structured data from [Bluesky](https://bsky.app): keyword post search, author feeds, profiles, followers, and follows — with date, language, author, domain, hashtag, and engagement filters, plus optional reply-thread collection.

<table><tr>
<td style="border-left:4px solid #1C1917;padding:12px 16px;font-weight:600">Search Bluesky posts or pull any account's feed, profile, followers, or follows — filter by date, language, author, mention, domain, or hashtag, then optionally collect reply threads and tag records with sentiment and topic labels.</td>
</tr></table>

##### Copy to your AI assistant

Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.

```
parsebird/bluesky-scraper on Apify. Call: ApifyClient("TOKEN").actor("parsebird/bluesky-scraper").call(run_input={"actionToPerform":"searchPosts","queries":["open source intelligence"],"maxItems":40}), then client.dataset(run["defaultDatasetId"]).list_items().items for results. Key inputs: actionToPerform (string, one of searchPosts|getAuthorFeed|getFollowers|getFollows|getProfile, default "searchPosts"), queries (array of keywords for searchPosts or Bluesky handles for the other actions), startUrls (array of {"url":...} objects — Bluesky search/post/profile/followers/follows pages), maxItems (integer cap on primary records), sortOrder (latest|top, searchPosts only), dateFrom/dateTo (YYYY-MM-DD), language/fromAuthor/mentionsAuthor/hashtags/domain/exactUrl (search query filters), minLikes/minReposts/minReplies (local engagement filters), includeReplies/includeReposts (booleans, default true), scrapeComments (boolean, adds reply records), maxComments (integer per source post), sentiment_analysis/content_analysis (booleans, add lexicon-based tags). Output rows have a "kind" field: post, comment, profile, follower, or follow. Full actor spec: GET https://api.apify.com/v2/acts/parsebird~bluesky-scraper (Bearer TOKEN). Get token: https://console.apify.com/account/integrations
```

### What is Bluesky Scraper?

Bluesky Scraper is an [Apify Actor](https://apify.com/actors) for extracting structured data from [Bluesky](https://bsky.app), the decentralized AT Protocol social network. It searches posts, and pulls author feeds, profiles, followers, and follows lists — for any public Bluesky account or keyword.

Use it as a **Bluesky API alternative**, a **Bluesky data scraper**, or a repeatable pipeline for social listening, brand monitoring, and audience research. Results download as JSON, CSV, Excel, XML, or HTML, or you can fetch them programmatically through the [Apify API](https://docs.apify.com/api/v2).

### What can Bluesky Scraper do?

- 🔎 **Search posts** by keyword, with `latest` or `top` sort order
- 📰 Pull any account's **author feed**, including reposts and replies
- 👤 Look up a **profile** — bio, avatar, banner, follower/follow/post counts
- 👥 Collect **followers** and **follows** lists for audience mapping
- 🎯 Filter search by **date range, language, author, mentions, domain, hashtag, or exact URL**
- 📊 Apply local **engagement filters** (minimum likes, reposts, replies) and exclude replies or reposts
- 💬 Optionally collect **reply threads** for any post as separate comment records
- 🏷️ Optionally tag records with lightweight **sentiment** and **content-category** labels
- 🔗 Scrape **direct Bluesky URLs** — search, post, profile, followers, and follows pages
- ⚙️ Run on demand, schedule recurring runs, or connect results to [Apify integrations](https://apify.com/integrations) like Google Sheets, Zapier, Make, and webhooks
- 📤 Export data in JSON, CSV, Excel, XML, RSS, or HTML from the Apify dataset

### What data can you extract from Bluesky?

| Field | Record kind | Description |
|-------|-------------|-------------|
| `text`, `createdAt`, `facets`, `embed` | post, comment | Post content, rich-text facets, and link/image/video embeds |
| `likeCount`, `repostCount`, `replyCount` | post, comment | Engagement counters |
| `reason` | post | Present when a feed record is a repost, with the reposting account |
| `sourcePostUri`, `commentDepth` | comment | Links a reply back to its source post and thread depth |
| `followersCount`, `followsCount`, `postsCount` | profile | Account-level stats |
| `associated`, `joinedViaStarterPack` | profile, follower, follow | Bluesky account metadata (lists, labeler status, starter pack) |
| `sentiment_score`, `sentiment_label` | post, comment | Lexicon-based sentiment tag (when `sentiment_analysis` is on) |
| `content_category_label`, `content_category_path` | post | Keyword-based topic tag (when `content_analysis` is on) |

### Input parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `actionToPerform` | string | No | `searchPosts` | One of `searchPosts`, `getAuthorFeed`, `getFollowers`, `getFollows`, `getProfile` |
| `queries` | array of strings | Depends\* | — | Keywords for `searchPosts`, or Bluesky handles for the other actions |
| `startUrls` | array of URLs | Depends\* | — | Bluesky search, post, profile, followers, or follows/following page URLs |
| `maxItems` | integer | No | — | Maximum primary records to collect across all queries |
| `sortOrder` | string | No | `latest` | `latest` or `top` — applies only to `searchPosts` |
| `dateFrom` / `dateTo` | string | No | — | `YYYY-MM-DD` UTC posting-date window |
| `language` | string | No | — | Language code appended as `lang:<code>` to search queries |
| `fromAuthor` | string | No | — | Handle/DID appended as `from:<handle>` to search queries |
| `mentionsAuthor` | string | No | — | Handle/DID appended as `mentions:<handle>` to search queries |
| `hashtags` | array of strings | No | — | Hashtags appended to search queries |
| `domain` | string | No | — | Linked domain appended as `domain:<domain>` |
| `exactUrl` | string | No | — | Exact shared URL appended as `url:<url>` |
| `minLikes` / `minReposts` / `minReplies` | integer | No | — | Local engagement filters |
| `includeReplies` | boolean | No | `true` | Off skips saved records that are replies |
| `includeReposts` | boolean | No | `true` | Off skips records returned because of a repost |
| `scrapeComments` | boolean | No | `false` | Also collects reply/comment records per post |
| `maxComments` | integer | No | `50000` | Max replies collected per source post |
| `sentiment_analysis` | boolean | No | `false` | Adds `sentiment_score`/`sentiment_label` |
| `content_analysis` | boolean | No | `false` | Adds `content_category_*` fields |

\*`queries` or `startUrls` — at least one is required.

**Example (keyword search with replies and enrichments):**

```json
{
  "actionToPerform": "searchPosts",
  "queries": ["open source intelligence", "threat intel"],
  "maxItems": 40,
  "sortOrder": "latest",
  "scrapeComments": true,
  "maxComments": 25,
  "sentiment_analysis": true,
  "content_analysis": true
}
```

**Example (language- and date-filtered market research):**

```json
{
  "actionToPerform": "searchPosts",
  "queries": ["science"],
  "language": "en",
  "dateFrom": "2026-04-01",
  "dateTo": "2026-04-24",
  "minLikes": 1,
  "includeReplies": false,
  "includeReposts": false,
  "maxItems": 15
}
```

**Example (direct Bluesky URLs):**

```json
{
  "startUrls": [
    { "url": "https://bsky.app/search?q=open%20source%20intelligence" },
    { "url": "https://bsky.app/profile/404media.co" },
    { "url": "https://bsky.app/profile/bsky.app/post/3kxyzexample" }
  ],
  "maxItems": 25,
  "scrapeComments": true,
  "maxComments": 10
}
```

### Output example

`post`:

```json
{
  "kind": "post",
  "query": "404media.co",
  "id": "3mk65zjpcpk25",
  "uri": "at://did:plc:pt47oe625rv5cnrkgvntwbiq/app.bsky.feed.post/3mk65zjpcpk25",
  "authorHandle": "samleecole.bsky.social",
  "authorDid": "did:plc:pt47oe625rv5cnrkgvntwbiq",
  "authorName": "Sam Cole",
  "text": "super interesting series of experiments here, where researchers cosplayed as a vulnerable user in various scenarios...",
  "createdAt": "2026-04-23T13:55:07.278Z",
  "languages": ["en"],
  "reason": {
    "type": "repost",
    "by": { "did": "did:plc:vcepp6trx4vpe5ourxso4tjl", "handle": "404media.co", "displayName": "404 Media" }
  },
  "embed": {
    "type": "external",
    "uri": "https://www.404media.co/delusion-using-chatgpt-gemini-claude-grok-safety-ai-psychosis-study/",
    "title": "Researchers Simulated a Delusional User to Test Chatbot Safety"
  },
  "replyCount": 3,
  "repostCount": 57,
  "likeCount": 189,
  "url": "https://bsky.app/profile/did:plc:pt47oe625rv5cnrkgvntwbiq/post/3mk65zjpcpk25",
  "content_category_label": "Artificial Intelligence",
  "content_category_path": ["Technology & Computing", "Artificial Intelligence"],
  "sentiment_score": 5,
  "sentiment_label": "positive"
}
```

`comment` (from `scrapeComments`):

```json
{
  "kind": "comment",
  "query": "404media.co",
  "id": "3mk66abcxyz2q",
  "authorHandle": "reply-user.bsky.social",
  "text": "This is a useful write-up. The thread adds a lot of context to the reporting.",
  "createdAt": "2026-04-23T14:02:11.000Z",
  "replyParentUri": "at://did:plc:pt47oe625rv5cnrkgvntwbiq/app.bsky.feed.post/3mk65zjpcpk25",
  "replyCount": 0,
  "repostCount": 1,
  "likeCount": 7,
  "url": "https://bsky.app/profile/did:plc:replyexample123/post/3mk66abcxyz2q",
  "sourcePostId": "3mk65zjpcpk25",
  "sourcePostAuthorHandle": "samleecole.bsky.social",
  "commentDepth": 1,
  "sentiment_score": 3,
  "sentiment_label": "positive"
}
```

`profile`:

```json
{
  "kind": "profile",
  "query": "404media.co",
  "id": "did:plc:vcepp6trx4vpe5ourxso4tjl",
  "authorHandle": "404media.co",
  "authorName": "404 Media",
  "text": "Independent journalism covering technology, media, and online culture.",
  "followersCount": 240914,
  "followsCount": 128,
  "postsCount": 5421,
  "createdAt": "2023-04-12T09:22:51.000Z",
  "url": "https://bsky.app/profile/404media.co"
}
```

`follower`:

```json
{
  "kind": "follower",
  "query": "404media.co",
  "id": "did:plc:followerexample123",
  "authorHandle": "analyst.bsky.social",
  "authorName": "Industry Analyst",
  "text": "Researching online communities, media systems, and platform behavior.",
  "createdAt": "2024-01-10T12:00:00.000Z",
  "url": "https://bsky.app/profile/analyst.bsky.social"
}
```

`getFollows` returns the same shape with `"kind": "follow"`. Download in JSON, HTML, CSV, or Excel from the dataset page, or fetch rows programmatically through the API.

### How to scrape Bluesky data

1. Open Bluesky Scraper on Apify and click **Try for free**.
2. Pick an `actionToPerform` (search posts, author feed, followers, follows, or profile).
3. Enter `queries` (keywords or handles) or `startUrls` (direct Bluesky links), and set `maxItems`.
4. Add optional filters — date range, language, author, hashtag, or minimum engagement.
5. Start the run and download results as JSON, CSV, Excel, HTML, XML, or RSS.
6. Automate it with [Apify scheduling](https://docs.apify.com/platform/schedules), [integrations](https://apify.com/integrations), or the [Apify API](https://docs.apify.com/api/v2).

### How to use the Bluesky API in Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("parsebird/bluesky-scraper").call(run_input={
    "actionToPerform": "searchPosts",
    "queries": ["open source intelligence"],
    "maxItems": 40,
    "sortOrder": "latest",
})

items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items[:2])
```

### How to use the Bluesky API in JavaScript

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('parsebird/bluesky-scraper').call({
    actionToPerform: 'getAuthorFeed',
    queries: ['404media.co'],
    maxItems: 30,
    scrapeComments: true,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Use cases

- **Social listening** — Track keyword or hashtag mentions with sentiment and topic tags
- **Brand monitoring** — Filter search by `fromAuthor`/`mentionsAuthor` to watch a brand's own posts and mentions
- **Audience research** — Pull an account's followers or follows for audience-overlap analysis
- **Thread analysis** — Collect reply threads under high-engagement posts
- **Content research** — Filter search results by date, language, or minimum engagement to find top posts

### How it works

1. Resolves each `queries` entry or `startUrls` link to an action (search, author feed, followers, follows, profile, or a direct post)
2. Builds Bluesky's advanced search query syntax (`lang:`, `from:`, `mentions:`, `domain:`, `url:`, `since:`, hashtags) for `searchPosts`
3. Calls Bluesky's public AT Protocol AppView endpoints and paginates results with cursors
4. Applies local filters — date window, minimum engagement, reply/repost exclusion — since not every filter has a server-side equivalent
5. Optionally walks each post's reply thread to collect comment records, and applies sentiment/content-category tagging
6. Pushes normalized rows to the dataset and stops once `maxItems` or your spending limit is reached

### How much does it cost to scrape Bluesky?

Bluesky Scraper uses pay-per-event pricing — you pay per row returned (posts, comments, profiles, followers, or follows), not per API call made internally.

| Event | Price per event | Price per 1,000 |
|-------|-----------------|-----------------|
| `record-scraped` | $0.0014 (Free) / $0.0013 (Bronze) / $0.0012 (Silver) / $0.0011 (Gold) | **$1.40 / $1.30 / $1.20 / $1.10** |

A 40-result keyword search costs a few cents. Comment collection adds one extra event per reply pulled. Apify's free trial credits cover typical test runs.

### Is it legal to scrape Bluesky data?

Bluesky Scraper extracts data from Bluesky's public AT Protocol AppView endpoints — the same read-only API Bluesky's own web and mobile clients use to render public posts, profiles, and follower lists. Scraping publicly accessible data is generally lawful, but you're responsible for how you use the results — always review [Bluesky's Terms of Service](https://bsky.social/about/support/tos) and Apify's guide on [the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/) before running large or automated workloads.

### Related ParseBird social and market data scrapers

| Actor | Best for |
|-------|----------|
| [Congress Stock Trades & Financial Disclosures](https://apify.com/parsebird/congress-stock-trades-scraper) | U.S. congressional stock trade disclosures |
| [Superinvestor Portfolio Scraper](https://apify.com/parsebird/dataroma-superinvestor-scraper) | Dataroma superinvestor holdings and allocations |
| [DexScreener Crypto Scraper](https://apify.com/parsebird/dexscreener-crypto-scraper) | Real-time DEX token prices, liquidity, and volume |

### FAQ

**Do I need a Bluesky account or API key?**
No. This actor uses Bluesky's public, unauthenticated AT Protocol AppView endpoints — the same ones bsky.app's own frontend calls for public data.

**Why does `includeReplies: false` still let me collect comments?**
`includeReplies` only filters saved post/feed records that are themselves replies. `scrapeComments` is a separate switch that walks a post's own reply thread and saves those as `comment` records — the two features are independent.

**Does `dateTo` restrict results server-side?**
`dateFrom` is sent to Bluesky as a `since:` search operator. `dateTo` is applied locally after fetching, since Bluesky's public search does not reliably support an upper-bound date operator.

**Why did my run return fewer posts than expected from `searchPosts`?**
Bluesky's public search endpoint applies its own bursty rate limiting independent of this actor. The actor automatically retries with backoff when that happens; a run that hits sustained rate limiting mid-query will log a warning and return what it collected before the limit cleared. Re-running usually succeeds.

**Are sentiment and content-category tags AI-generated?**
No — both are lightweight, deterministic lexicon/keyword heuristics computed in the actor, not calls to a trained ML or LLM model. They're useful for rough grouping and triage, not as ground truth.

**Can I schedule recurring runs?**
Yes. Use [Apify scheduling](https://docs.apify.com/platform/schedules) to run daily, hourly, or at any interval, then connect the dataset to integrations or webhooks.

**How do I report a problem or request a field?**
Open an issue from the Actor page in Apify Console and include the run ID, input, and action used.

# Actor input Schema

## `actionToPerform` (type: `string`):

Selects what to collect.

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

One or more input values to process. Use keywords for Search posts, and Bluesky handles for user-focused actions (Get author feed, Get followers, Get follows, Get profile).

## `startUrls` (type: `array`):

One or more Bluesky URLs to scrape directly. Supports search pages, post pages, profile pages, followers pages, and follows/following pages. Can be combined with Queries.

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

Maximum number of primary records to collect across all queries. Leave empty to collect as many matching records as are available.

## `sortOrder` (type: `string`):

Sort order for Search posts. This field applies only to keyword-based post search.

## `dateFrom` (type: `string`):

Optional posting date lower bound (YYYY-MM-DD, UTC). Adds a since: search operator and is also applied locally to post-like records.

## `dateTo` (type: `string`):

Optional posting date upper bound (YYYY-MM-DD, UTC). Applied locally to post-like records after fetching.

## `language` (type: `string`):

Optional language code (e.g. en, fr, ja). For post search, the actor appends lang:<code> to each query.

## `fromAuthor` (type: `string`):

Optional Bluesky handle or DID. For post search, the actor appends from:<handle> to each query.

## `mentionsAuthor` (type: `string`):

Optional Bluesky handle or DID. For post search, the actor appends mentions:<handle> to each query.

## `hashtags` (type: `array`):

Optional hashtags to append to post search queries. Values can be entered with or without #.

## `domain` (type: `string`):

Optional linked domain filter. For post search, the actor appends domain:<domain>.

## `exactUrl` (type: `string`):

Optional exact shared URL to append to post search queries.

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

Optional local engagement filter applied after Bluesky returns post-like records.

## `minReposts` (type: `integer`):

Optional local engagement filter applied after Bluesky returns post-like records.

## `minReplies` (type: `integer`):

Optional local engagement filter applied after Bluesky returns post-like records.

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

When off, skips saved post records that are replies to another post. This does not enable or disable thread reply scraping (see Scrape Comments below).

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

When off, skips feed/search records returned because they were reposted by another account.

## `scrapeComments` (type: `boolean`):

When enabled, the actor also collects replies for each post in Search posts and Get author feed runs, as separate comment records.

## `maxComments` (type: `integer`):

Maximum number of replies to collect per source post when Scrape Comments is enabled.

## `sentiment_analysis` (type: `boolean`):

Adds sentiment\_score and sentiment\_label to supported post and comment records, using a lightweight lexicon-based heuristic (not a trained ML model).

## `content_analysis` (type: `boolean`):

Adds content-category fields to supported post records for topic-oriented grouping and filtering, using a lightweight keyword-based heuristic (not a trained ML model).

## `proxy` (type: `object`):

Optional proxy override. Bluesky's public API is reachable directly, so proxy is disabled by default.

## Actor input object example

```json
{
  "actionToPerform": "searchPosts",
  "queries": [
    "bluesky"
  ],
  "startUrls": [],
  "maxItems": 10,
  "sortOrder": "latest",
  "dateFrom": "",
  "dateTo": "",
  "language": "",
  "fromAuthor": "",
  "mentionsAuthor": "",
  "hashtags": [],
  "domain": "",
  "exactUrl": "",
  "includeReplies": true,
  "includeReposts": true,
  "scrapeComments": false,
  "maxComments": 50,
  "sentiment_analysis": false,
  "content_analysis": false,
  "proxy": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (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 = {
    "actionToPerform": "searchPosts",
    "queries": [
        "bluesky"
    ],
    "startUrls": [],
    "maxItems": 10,
    "sortOrder": "latest",
    "hashtags": [],
    "maxComments": 50,
    "proxy": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("parsebird/bluesky-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 = {
    "actionToPerform": "searchPosts",
    "queries": ["bluesky"],
    "startUrls": [],
    "maxItems": 10,
    "sortOrder": "latest",
    "hashtags": [],
    "maxComments": 50,
    "proxy": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("parsebird/bluesky-scraper").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 '{
  "actionToPerform": "searchPosts",
  "queries": [
    "bluesky"
  ],
  "startUrls": [],
  "maxItems": 10,
  "sortOrder": "latest",
  "hashtags": [],
  "maxComments": 50,
  "proxy": {
    "useApifyProxy": false
  }
}' |
apify call parsebird/bluesky-scraper --silent --output-dataset

```

## MCP server setup

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

```

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/GnzvxUosjDZE4FtL9/builds/j3KpwSaBQfwsRqFrb/openapi.json
