Web and domains
Bluesky Monitor: Posts, Hashtags and Followers as JSON
Bluesky runs on the open AT Protocol, and its public API answers without a login. This Actor reads it in six modes (post search, profiles, author feeds, followers, following and account search) and writes every result as a flat record, so you can follow keywords, hashtags or accounts on a schedule.
Bluesky Monitor & Scraper — Posts, Keywords, Followers. Pay per result; see the Store page for current pricing.
The source and its limits
The data comes from Bluesky's public, unauthenticated AT Protocol API: the public.api.bsky.app AppView, with its origin api.bsky.app as a fallback for post search. These are the same public endpoints the Bluesky app uses. No login, API key, proxies or browser.
| Mode | Queries are | Returns |
|---|---|---|
searchPosts | Keywords, hashtags, phrases and search operators | Matching posts |
authorFeed | Handles, DIDs or profile URLs | The accounts' posts |
profiles | Handles, DIDs or profile URLs | Profiles with follower, following and post counts |
followers, following | Handles, DIDs or profile URLs | Follower or following lists |
searchActors | Search terms | Matching accounts |
Limits worth knowing
- Post search returns at most 100 posts per query per run. From datacenter networks the public host refuses post search, and the origin host serves only the first page of results without a login. Use
since, narrower queries, several queries, or the new-since-last-run mode on a schedule to keep up. - Requests are limited to about two per second. One request returns up to 100 posts or followers, so 10,000 followers take about a minute.
- Follower records do not include per-follower counts; run
profileson the handles you care about. - Posts and profiles whose authors opted out of logged-out visibility may be missing, as they are on the public web.
Fields you get
| Field | What it holds |
|---|---|
type, query | post, profile, follower or following, and the query that found it |
text, createdAt, langs | Post content and time |
likeCount, repostCount, replyCount, quoteCount | Engagement counts |
authorHandle, authorDisplayName, authorDid | Post author |
hasImages, hasVideo, embedUrls, externalUrl | Media and links |
isReply, isRepost, quotedPostUrl | Thread context |
postUrl, uri | Link to the post on bsky.app and its AT URI |
handle, displayName, description, followersCount, followsCount, postsCount | On profile records |
subjectHandle | On follower records: the account you asked about |
Example output
One post record from searchPosts (from the Actor's README; shortened):
{
"type": "post",
"query": "apify",
"uri": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3l6oveex3ii2l",
"authorHandle": "bsky.app",
"authorDisplayName": "Bluesky",
"text": "We shipped a new Apify integration today! Try the open API: https://docs.bsky.app",
"createdAt": "2026-10-15T18:02:11.482Z",
"likeCount": 310,
"repostCount": 40,
"replyCount": 12,
"quoteCount": 5,
"langs": [
"en"
],
"hasImages": true,
"hasVideo": false,
"isReply": false,
"isRepost": false,
"postUrl": "https://bsky.app/profile/bsky.app/post/3l6oveex3ii2l",
"fetchedAt": "2026-10-16T12:40:32.064Z"
}
Use cases
Brand and keyword mentions
Run searchPosts with sort: "latest" and onlyNewSinceLastRun on a schedule, and send each run's new posts to a webhook.
Follower growth
Run followers with the new-since-last-run mode to get only new followers of an account on each run.
Account research
Run profiles on a list of handles for follower, following and post counts in one table.
How to run it
You need an Apify account and its API token (Console → Settings → API & Integrations). Each run is billed per result to your account; set a maximum total charge for the run to cap spend.
With curl
The sync endpoint starts a run, waits up to 300 seconds and returns the dataset items. New Bluesky posts mentioning a keyword since the last run, newest first:
export APIFY_TOKEN=<your Apify API token>
curl -sS -X POST \
"https://api.apify.com/v2/acts/owlabee~bluesky-monitor/run-sync-get-dataset-items" \
-H "Authorization: Bearer ${APIFY_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"mode": "searchPosts",
"queries": [
"apify"
],
"maxResults": 50,
"sort": "latest",
"onlyNewSinceLastRun": true,
"stateStoreName": "bluesky-keyword-brand-mention-monitor"
}'
From an AI agent (MCP)
Apify hosts an MCP server. This config exposes only this Actor to the agent:
{
"mcpServers": {
"owlabee-bluesky-monitor": {
"url": "https://mcp.apify.com/?tools=owlabee/bluesky-monitor",
"headers": {
"Authorization": "Bearer ${APIFY_TOKEN}"
}
}
}
}
Then ask, for example: Find the latest Bluesky posts with the hashtag #opensource and list the authors, text and like counts.
Python, Node.js and more examples
Runnable curl.sh, python.py, node.mjs and mcp.json files for this Actor are in examples/bluesky-monitor on GitHub.
FAQ
Does it need a Bluesky login or API key?
No. It uses Bluesky's public, unauthenticated API endpoints.
Can I search hashtags or exact phrases?
Yes. #opensource, "exact phrase" and operators such as from:handle, lang:en or domain:example.com are passed to Bluesky's search.
How does new-since-last-run work?
Per mode and query, the Actor stores the keys of records it already emitted (the most recent 10,000) and stops paging when it reaches known records. Profiles are re-emitted only when something changed, listed in changedFields.
Why do I get at most 100 posts for a search?
Post search from datacenter networks returns only the first page of results without a login. Split broad topics into several queries or narrow them with since.
What happens with a bad handle?
It produces an error item such as PROFILE_NOT_FOUND and the rest of the run continues.