# Bluesky Posts Scraper: Search, Profiles, Feeds & Lists (`luzivanlt/bluesky-posts-scraper`) Actor

Bluesky posts from searches, profiles, custom feeds, lists and post links, 100+ fields a post. $1.50 per 1,000 posts. Likes, reposts, replies, quotes, media. No account.

- **URL**: https://apify.com/luzivanlt/bluesky-posts-scraper.md
- **Developed by:** [Luzi](https://apify.com/luzivanlt) (community)
- **Categories:** Social media, Marketing, Lead generation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.05 / 1,000 posts

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

## Bluesky Posts Scraper: Search, Profiles, Feeds & Lists

Get Bluesky posts from searches, profiles, custom feeds, lists and single
post links, with more than 100 fields on every post: the text, the author,
likes, reposts, replies, quotes and saves, images, video and link cards, the
post it answers or quotes, who may reply, and the profile's own numbers on
every row of a profile. No Bluesky account needed.

Tested daily. Latest checks: Bluesky's own profile read whole, 907 of its
907 posts; 6,794 posts from two searches, a profile, a feed and a post in
under five minutes.

### What does this Actor do?

You give it search terms, links, or both. Each one is a source, and each
source gives you one row per post:

- **A search term** (`climate`, `"open source"`, `#photography`) or a
  search link (`https://bsky.app/search?q=climate`): the posts that match,
  newest first and back as far as Bluesky shows, or Bluesky's top posts.
  Narrow it to a language or to a stretch of dates.
- **A profile** (`https://bsky.app/profile/jay.bsky.team`, or just
  `jay.bsky.team`): its posts, newest first, back to its first post or your
  limit, with replies or without, and its reposts if you want them. Every row
  carries the profile's followers, bio and post count.
- **A custom feed** (`https://bsky.app/profile/bsky.app/feed/whats-hot`) or
  **a list** (`…/lists/…`): the posts it shows, in its own order, to its end.
- **A post link** (`https://bsky.app/profile/<handle>/post/<id>`): that one
  post.

### Why use it?

- **Every field Bluesky shows on a post.** Counts (likes, reposts, replies,
  quotes, saves), the author's verification and account date, each image with
  its alt text and size, video, link cards, hashtags, mentions and links, the
  post it replies to with its text, the post, feed, list or starter pack it
  quotes, and its reply settings.
- **Searches read far back.** A newest-first search keeps going past the
  first page, back through Bluesky's results, to your limit or your date.
- **Profiles, feeds and lists, not only search.** Follow accounts, read a
  custom feed the way its subscribers see it, or export a list's posts.
- **One price, no start fee.** You pay per post saved.

### How to use it

1. Type search terms into **Search terms**, and/or paste profiles, feeds,
   lists, posts or search links into **Profile, feed, list, post or search
   links**, one per line.
2. Optionally set **Max posts per search or link**, a date range, the search
   order and language, and which of a profile's posts to read.
3. Click **Start**. When the run ends, open the **Output** tab to view the
   posts or download them as JSON, CSV or Excel.

Run it with no input to see a sample: up to 20 posts for the search
`bluesky` and 20 from Bluesky's own profile, charged as usual.

### Input

| Field                                                       | What it does                                                                            | Default              |
| ----------------------------------------------------------- | --------------------------------------------------------------------------------------- | -------------------- |
| **Search terms** (`searchTerms`)                            | Words to search posts for; each term is one search                                      | empty                |
| **Profile, feed, list, post or search links** (`startUrls`) | Profiles (or handles), custom feeds, lists, single posts and search links               | empty                |
| **Max posts per search or link** (`maxPostsPerSource`)      | Stop each source after this many posts, from 1 to 100,000                               | `100`                |
| **Search order** (`sort`)                                   | `latest` (newest first, far back) or `top` (Bluesky's top posts, one page of up to 100) | `latest`             |
| **Language** (`language`)                                   | Keep only search results in this language (`en`, `de`, `ja`, …)                         | any                  |
| **Only posts newer than** (`onlyPostsNewerThan`)            | A date (`YYYY-MM-DD`, UTC) or a period (`7 days`, `3 months`)                           | any date             |
| **Only posts older than** (`onlyPostsOlderThan`)            | A date (`YYYY-MM-DD`, UTC); that day is left out                                        | up to now            |
| **Profile posts** (`profilePosts`)                          | `posts_with_replies`, `posts_no_replies`, `posts_with_media` or `posts_with_video`      | `posts_with_replies` |
| **Include reposts** (`includeReposts`)                      | Also save what a profile reposted, with who reposted it and when                        | off                  |

At least one search term or link is needed.

Example input:

```json
{
  "searchTerms": ["climate", "#photography"],
  "startUrls": [
    "https://bsky.app/profile/jay.bsky.team",
    "https://bsky.app/profile/bsky.app/feed/whats-hot"
  ],
  "maxPostsPerSource": 500,
  "onlyPostsNewerThan": "30 days",
  "language": "en"
}
```

### Output

One row per post. A sample row, shortened:

```json
{
  "post_id": "3lexampleid2a",
  "url": "https://bsky.app/profile/example.bsky.social/post/3lexampleid2a",
  "text": "A made-up post about #photography",
  "created_at": "2026-10-20T10:00:00.000Z",
  "author_handle": "example.bsky.social",
  "author_name": "Example Person",
  "like_count": 42,
  "repost_count": 5,
  "reply_count": 3,
  "quote_count": 1,
  "hashtags": ["photography"],
  "embed_type": "images",
  "images": [
    { "url": "https://cdn.example/full.jpg", "alt": "A lake at dawn", "width": 1200, "height": 800 }
  ],
  "source_type": "search",
  "source": "#photography"
}
```

Every field:

- `post_uri`: The post's permanent at:// address; the key each post is saved and charged once by.
- `post_id`: The post's id, the last part of its link.
- `cid`: The id of this version of the post's content.
- `url`: The post on bsky.app.
- `text`: The post's text.
- `created_at`: When the author posted it.
- `indexed_at`: When Bluesky first saw it.
- `langs`: The languages the author tagged it with.
- `labels`: Moderation labels on the post (e.g. porn, graphic-media).
- `self_labels`: Content warnings the author put on it.
- `author_did`: The author's permanent account id.
- `author_handle`: The author's handle, e.g. jay.bsky.team.
- `author_name`: The author's display name.
- `author_avatar`: The author's profile picture.
- `author_pronouns`: The pronouns on the author's profile, when set.
- `author_created_at`: When the author's account was made.
- `author_labels`: Labels on the author's account.
- `author_verified`: Whether Bluesky shows the author as verified.
- `author_is_trusted_verifier`: Whether the author may verify other accounts.
- `author_verified_by`: Who verified the author.
- `author_verified_at`: When the author was verified.
- `author_allows_messages`: Who may message the author: all, following or none.
- `author_allows_activity_subscriptions`: Who may subscribe to the author's new posts.
- `like_count`: Likes.
- `repost_count`: Reposts.
- `reply_count`: Replies.
- `quote_count`: Quote posts.
- `bookmark_count`: Saves.
- `is_reply`: Whether the post answers another post.
- `reply_to_uri`: The post it answers.
- `reply_to_url`: The post it answers, on bsky.app.
- `reply_to_author_handle`: Who wrote the post it answers (profiles, feeds and lists).
- `reply_to_text`: The text of the post it answers (profiles, feeds and lists).
- `thread_root_uri`: The first post of its thread.
- `thread_root_author_handle`: Who started the thread (profiles, feeds and lists).
- `thread_post_index`: Its place in the author's own thread, when Bluesky shows it.
- `thread_post_count`: How many posts the author's own thread has, when Bluesky shows it.
- `hashtags`: Its hashtags.
- `mentioned_dids`: The accounts it mentions, by DID.
- `links`: The links in its text.
- `has_media`: Whether it carries images or video of its own (a quoted post's media is in `quoted_media_urls`).
- `embed_type`: What it carries: images, video, link, quote or quote_with_media.
- `images`: Each image: url, thumbnail_url, alt, width, height, mime_type, size_bytes.
- `video_url`: The video's stream (an .m3u8 playlist).
- `video_thumbnail_url`: The video's still.
- `video_alt`: The video's alt text.
- `video_width`: In pixels.
- `video_height`: In pixels.
- `video_presentation`: How the video is shown, e.g. gif.
- `video_mime_type`: The uploaded file's type.
- `video_size_bytes`: The uploaded file's size in bytes.
- `link_card_url`: The page its link card points to.
- `link_card_title`: The card's title.
- `link_card_description`: The card's text.
- `link_card_thumbnail_url`: The card's picture.
- `quoted_type`: What it quotes: post, feed, list, starter_pack, labeler, not_found, blocked or detached.
- `quoted_uri`: The quoted record's address.
- `quoted_url`: The quoted post on bsky.app.
- `quoted_author_did`: Who wrote or made the quoted record.
- `quoted_author_handle`: Their handle.
- `quoted_author_name`: Their display name.
- `quoted_author_avatar`: Their picture.
- `quoted_labels`: Labels on the quoted post.
- `quoted_text`: The quoted post's text.
- `quoted_created_at`: When the quoted record was made.
- `quoted_langs`: The quoted post's languages.
- `quoted_like_count`: The quoted post's (or feed's) likes.
- `quoted_repost_count`: The quoted post's reposts.
- `quoted_reply_count`: The quoted post's replies.
- `quoted_quote_count`: The quoted post's quotes.
- `quoted_media_urls`: The quoted post's images and video.
- `quoted_name`: The quoted feed's, list's or starter pack's name.
- `quoted_description`: Its description.
- `quoted_list_purpose`: A quoted list's kind: curatelist, modlist or referencelist.
- `quoted_member_count`: How many accounts a quoted list holds.
- `quoted_joined_week_count`: People who joined through a quoted starter pack this week.
- `quoted_joined_all_time_count`: People who joined through it in all.
- `reply_restrictions`: Set when the author limited replies: mentioned, followers, following, list_members, or nobody.
- `reply_allowed_lists`: The lists whose members may reply.
- `hidden_reply_count`: Replies the author hid.
- `is_repost`: True when a profile reposted it (with Include reposts on, or in a feed that shows reposts).
- `reposted_by_did`: Who reposted it.
- `reposted_by_handle`: Their handle.
- `reposted_by_name`: Their display name.
- `reposted_by_avatar`: Their picture.
- `reposted_at`: When.
- `repost_uri`: The repost's own address.
- `source_type`: search, profile, feed, list or post.
- `source`: The search term or the link it came from.
- `search_result_count`: Bluesky's count of matches for the search, posts it does not show included.
- `profile_did`: The profile read (profile links only).
- `profile_handle`: Its handle.
- `profile_name`: Its display name.
- `profile_description`: Its bio.
- `profile_avatar`: Its picture.
- `profile_banner`: Its banner.
- `profile_created_at`: When it was made.
- `profile_followers_count`: Its followers.
- `profile_follows_count`: Accounts it follows.
- `profile_posts_count`: Its post count, replies included.
- `profile_lists_count`: Lists it made.
- `profile_feeds_count`: Custom feeds it made.
- `profile_starter_packs_count`: Starter packs it made.
- `profile_labels`: Labels on it.
- `profile_verified`: Whether Bluesky shows it as verified.
- `profile_pinned_post_uri`: The post it pinned.
- `profile_indexed_at`: When Bluesky last indexed it.
- `scraped_at`: When this run started.

A field Bluesky has no value for is `null` (an empty list is `null` too).
The `profile_…` fields are filled on rows read from a profile link, and empty
on others.

### How much does it cost?

No surcharges and no paid options; an item that fails is not charged.

You pay for what you get:

- **$1.50 per 1,000 posts** ($0.0015 a post). Each post is charged once per run.
- No start fee, and nothing per search or link.

So 500 posts from each of 4 sources cost $3. If you set a maximum cost for a
run, the Actor stops when it reaches it and keeps every post saved so far.

### How long does a run take?

About 1,500 posts a minute in all. In a test, 6,794 posts from five sources
took four and a half minutes, and a whole 907-post profile a minute and a
half.

### Good to know

- **Search shows what Bluesky shows a visitor.** Bluesky's own count of
  matches (`search_result_count`) also counts posts it does not show without
  an account, so a search can end below it. Top search is one page of up to
  100 posts.
- **A profile's post count includes its replies.** `profile_posts_count`
  matches what a whole read with **Profile posts** on its default returns;
  the other choices, a date range or your limit return fewer.
- **Feeds have their own order and end.** A feed such as What's Hot is read
  until it has nothing more to show, or until Bluesky stops serving more of
  it (about 1,500 to 1,900 posts for What's Hot), which may be well before
  its oldest post.
- **Only posts older than reads past newer posts on a profile, feed or
  list.** A search asks Bluesky for that stretch of time directly; a profile,
  feed or list is read from its newest post, and the newer ones are skipped,
  not saved or charged. Such a source reads at most about 200 posts for each
  post of your limit, so a profile with far more newer posts than that can
  end with none: set a higher limit, or search for the stretch instead.
- **One source that cannot be read does not stop the run.** A profile, feed
  or post that does not exist, or is not shown, ends with a message; the
  others carry on.
- **A post can turn up under two sources.** It is saved and charged once per
  run, on the first source that found it.
- **Counts move.** Likes, reposts and followers are the numbers at the
  moment the post was read.

Not included: the replies under a post, follower and following lists,
profile search, and posts that need a Bluesky account to see.

### More Actors from us

- [Airbnb Scraper: Every Stay, Past the 15-Page Limit](https://apify.com/luzivanlt/airbnb-listings-scraper): Every stay of an Airbnb search, past the 15 pages Airbnb shows, checked against its count.
- [Alibaba Products Scraper: Price Tiers & Suppliers](https://apify.com/luzivanlt/alibaba-products-scraper): Alibaba.com products by keyword or link, with price tiers in US dollars on every row.
- [AliExpress Product Scraper: Search Results & Prices](https://apify.com/luzivanlt/aliexpress-products-scraper): Every product of an AliExpress search to its last page, with exact sold counts and ratings.
- [Amazon Product Scraper: Search Results & Prices](https://apify.com/luzivanlt/amazon-products-scraper): Every product on Amazon's search pages to the last page, sponsored marked, with monthly sales.
- [App Store Reviews Scraper: All Reviews, Not 500](https://apify.com/luzivanlt/app-store-reviews-scraper): Every written App Store review of an app, not just the newest 500.
- [Woolworths Coles ALDI Scraper: AU Grocery Prices](https://apify.com/luzivanlt/au-supermarkets-scraper): Woolworths, Coles and ALDI products for any search in one run, every results page to the end.

### Use it from an AI agent or the API

One call starts a run and returns its items (Apify waits up to 300 seconds; for a
longer run, start it with `POST /v2/acts/…/runs` and read its dataset):

```text
POST https://api.apify.com/v2/acts/luzivanlt~bluesky-posts-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>
```

With the sample input as its JSON body:

```json
{
  "searchTerms": ["bluesky"],
  "startUrls": ["https://bsky.app/profile/bsky.app"],
  "maxPostsPerSource": 20,
  "sort": "latest",
  "profilePosts": "posts_with_replies",
  "includeReposts": false
}
```

Its inputs, in the order of the input form:

| Input                                                   | What it takes                                                                                                                                                                                                                                                                                                                                                                             | Default                |
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- |
| `searchTerms` (Search terms)                            | Words to search Bluesky posts for, as you would type them in Bluesky's search box, e.g. climate, "open source" or #photography.                                                                                                                                                                                                                                                           | —                      |
| `startUrls` (Profile, feed, list, post or search links) | Bluesky pages to read: a profile (https://bsky.app/profile/jay.bsky.team, or just the handle jay.bsky.team) gives its posts, newest first; a custom feed (https://bsky.app/profile/bsky.app/feed/whats-hot) or a list (…/lists/…) gives its posts in the feed's own order; a post link gives that one post; a search link (https://bsky.app/search?q=climate) is read like a search term. | —                      |
| `maxPostsPerSource` (Max posts per search or link)      | Stop reading a search, profile, feed or list after this many posts.                                                                                                                                                                                                                                                                                                                       | `100`                  |
| `sort` (Search order)                                   | Latest reads a search newest first and keeps going back through Bluesky's results, as far as Bluesky shows them, to your limit or your date.                                                                                                                                                                                                                                              | `"latest"`             |
| `language` (Language)                                   | Keep only search results in this language, written as a language code: en, de, ja, pt, es, pt-BR and so on.                                                                                                                                                                                                                                                                               | —                      |
| `onlyPostsNewerThan` (Only posts newer than)            | Keep only posts from this date on: a date (YYYY-MM-DD, UTC) or a period such as "7 days", "2 weeks", "3 months" or "1 year".                                                                                                                                                                                                                                                              | —                      |
| `onlyPostsOlderThan` (Only posts older than)            | Keep only posts from before this day (YYYY-MM-DD, UTC; the day itself is left out).                                                                                                                                                                                                                                                                                                       | —                      |
| `profilePosts` (Profile posts)                          | Which of a profile's posts to read: all of them, replies included (the default); posts without replies; only posts with images or video; or only posts with video.                                                                                                                                                                                                                        | `"posts_with_replies"` |
| `includeReposts` (Include reposts)                      | Also save the posts a profile reposted, each with who reposted it and when (reposted_by_handle, reposted_at).                                                                                                                                                                                                                                                                             | `false`                |

Apify's MCP server, `https://mcp.apify.com`, lists it as `luzivanlt/bluesky-posts-scraper`. To give an
AI agent this Actor as a tool, add the server to the agent's MCP config:

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

The client signs in with OAuth, or add `"headers": { "Authorization": "Bearer <APIFY_TOKEN>" }`.

Charged per post delivered; the sample input above costs at most $0.06.

### FAQ

**Do I need a Bluesky account?**
No. The Actor reads what anyone can see on Bluesky without signing in.

**Can I search for a hashtag?**
Yes: type it as a search term, such as `#photography`.

**Does it read the replies to a post?**
No, only the post itself (and, for a reply, the post it answers).

**Can I run it from my own code, on a schedule, or with other apps?**
Yes. Like any Apify Actor, you can start it through the Apify API, run it on a
schedule, and connect it to other apps with Apify's integrations and webhooks.

### Is it legal to scrape Bluesky?

This Actor reads only public posts that anyone can see. Posts and profiles
hold personal data, such as names, handles and pictures: check Bluesky's terms
and the laws that apply to you (such as the GDPR) before you use the data. If
you are unsure, ask a lawyer.

### Support

Found a problem or missing a feature? Open an issue on the **Issues** tab and
include the run's link.

***

This Actor is not affiliated with, endorsed by or sponsored by Bluesky.

# Changelog

This Actor's version history is a separate document: https://apify.com/luzivanlt/bluesky-posts-scraper/changelog.md

# Actor input Schema

## `searchTerms` (type: `array`):

Words to search Bluesky posts for, as you would type them in Bluesky's search box, e.g. climate, "open source" or #photography. Each term is one search. Leave empty to read only the links below.

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

Bluesky pages to read: a profile (https://bsky.app/profile/jay.bsky.team, or just the handle jay.bsky.team) gives its posts, newest first; a custom feed (https://bsky.app/profile/bsky.app/feed/whats-hot) or a list (…/lists/…) gives its posts in the feed's own order; a post link gives that one post; a search link (https://bsky.app/search?q=climate) is read like a search term. A link given twice is read once. Example: https://bsky.app/profile/bsky.app

## `maxPostsPerSource` (type: `integer`):

Stop reading a search, profile, feed or list after this many posts. From 1 to 100,000; 100 if left empty. You pay per post saved, so this caps each source's cost.

## `sort` (type: `string`):

Latest reads a search newest first and keeps going back through Bluesky's results, as far as Bluesky shows them, to your limit or your date. Top gives Bluesky's top posts for the search instead: one page of up to 100. Searches only. Example: latest

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

Keep only search results in this language, written as a language code: en, de, ja, pt, es, pt-BR and so on. Searches only; profiles, feeds and lists are not filtered. Leave empty for every language. Example: en

## `onlyPostsNewerThan` (type: `string`):

Keep only posts from this date on: a date (YYYY-MM-DD, UTC) or a period such as "7 days", "2 weeks", "3 months" or "1 year". A search and a profile stop reading once they pass it. Leave empty for any date. A single post link is always read. Example: 30 days

## `onlyPostsOlderThan` (type: `string`):

Keep only posts from before this day (YYYY-MM-DD, UTC; the day itself is left out). With the date above, a search reads one stretch of time. Leave empty for up to now. Example: 2026-10-01

## `profilePosts` (type: `string`):

Which of a profile's posts to read: all of them, replies included (the default); posts without replies; only posts with images or video; or only posts with video. Profiles only. Example: posts_no_replies

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

Also save the posts a profile reposted, each with who reposted it and when (reposted_by_handle, reposted_at). Off by default: a profile then gives only the posts it wrote itself. Profiles only.

## Actor input object example

```json
{
  "searchTerms": [
    "bluesky"
  ],
  "startUrls": [
    "https://bsky.app/profile/bsky.app"
  ],
  "maxPostsPerSource": 20,
  "sort": "latest",
  "profilePosts": "posts_with_replies",
  "includeReposts": false
}
```

# Actor output Schema

## `posts` (type: `string`):

Every post the run saved, one row per post.

## `allFields` (type: `string`):

The same rows with every field.

## `runReport` (type: `string`):

What happened to each input: items saved, nothing found, refused by the site, stopped at your limit, or the error.

# 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 = {
    "searchTerms": [
        "bluesky"
    ],
    "startUrls": [
        "https://bsky.app/profile/bsky.app"
    ],
    "maxPostsPerSource": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("luzivanlt/bluesky-posts-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 = {
    "searchTerms": ["bluesky"],
    "startUrls": ["https://bsky.app/profile/bsky.app"],
    "maxPostsPerSource": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("luzivanlt/bluesky-posts-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 '{
  "searchTerms": [
    "bluesky"
  ],
  "startUrls": [
    "https://bsky.app/profile/bsky.app"
  ],
  "maxPostsPerSource": 20
}' |
apify call luzivanlt/bluesky-posts-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,luzivanlt/bluesky-posts-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/pIfL2i6zuW43pT4ty/builds/611TNYpaTUsWjXBwf/openapi.json
