# Bluesky Mentions Monitor - Keyword & Brand Tracker (`monriah-studio/bluesky-mentions`) Actor

Track Bluesky posts that mention your brand, keywords or hashtags. Exact phrase, OR and -exclude queries, since-date, only-new alerts, author followers, engagement, language and sentiment. Official public API, no login.

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

## Pricing

from $2.00 / 1,000 bluesky posts

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/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 Mentions Monitor – Keyword & Brand Tracker

A 100-result test run with the default input (mentions of Apify and web scraping from the last 7 days) costs about $0.20 ($0.002 per result, plus a $0.00005 start fee). Apify's free plan includes monthly platform credit.

**Bluesky Mentions Monitor** tracks **Bluesky posts that mention your brand, product, competitors, keywords or hashtags** and turns them into a clean dataset. Each row has the **post URL and text (plus link-card title), author handle and display name, author follower count, likes, reposts, replies and quotes, language**, and a simple **sentiment tag**. Schedule it with **Only new posts since last run** to get a brand-mention alert feed for Slack, email, Google Sheets, Zapier, Make or n8n.

It uses Bluesky's **official public API** (`api.bsky.app`): **no login, no API key, no cookies, no proxy**.

### Why use this Bluesky monitor?

- **Brand monitoring built in.** Enter `Acme Inc`, `@acme.bsky.social` or `acme.com` and the Actor runs the right searches: exact phrase, `mentions:` and `domain:` (posts linking to your site). It then merges and dedupes the results.
- **Real query syntax:** `"exact phrase"`, `-exclude`, **`OR`** (each side is searched separately, then merged), plus Bluesky operators `from:`, `mentions:`, `domain:` and `lang:`.
- **Since-date filter** (absolute date or `24 hours` / `7 days`) is applied server-side where Bluesky allows it, and always client-side.
- **Only-new alerts:** cross-run dedupe, so scheduled runs return and bill only for posts you haven't seen.
- **Reach and engagement:** author followers, following and post counts (batched public `getProfiles`), likes, reposts, replies, quotes and an engagement total. Filter by `minLikes` or `minFollowers`.
- **Sentiment:** a transparent, rule-based `positive` / `negative` / `neutral` / `mixed` tag with a score.
- **Which query matched:** `matchedQueries`, `matchedBrands` and `matchedHashtags` on every row, so one run can track several brands.
- **Works on empty input.** Every field has a default, and `{}` runs a demo search in seconds.

### How to use it

1. Click **Try for free**.
2. Add **keyword queries**, **brands** (names, @handles, domains) and/or **hashtags**.
3. Set **Posted since** (default `7 days`), and optionally a **language** or **minimum followers**.
4. Click **Start**. Typical runs finish in under 30 seconds.
5. For alerts: create a **Schedule** (e.g. hourly), turn on **Only new posts since last run**, and add an integration or webhook.

### Input example

```json
{
  "queries": ["apify", "\"web scraping\" OR crawlee"],
  "brands": ["apify.com"],
  "hashtags": [],
  "excludeKeywords": [],
  "sinceDate": "7 days",
  "language": "",
  "sort": "latest",
  "maxResults": 100,
  "includeReplies": true,
  "minLikes": 0,
  "minFollowers": 0,
  "fetchAuthorProfiles": true,
  "onlyNewSinceLastRun": false
}
```

If `queries`, `brands` and `hashtags` are all empty, the Actor searches `apify` and `"web scraping"` from the last 7 days as a demo.

### Output example

```json
{
  "postUrl": "https://bsky.app/profile/ranovam.bsky.social/post/3myap7aoson2r",
  "text": "Flarum Forum Scraper\n\nSearch or monitor any Flarum-powered forum — not social media. Clean discussion JSON with replies, participants, dates, canonical URLs. Free to start, API & MCP ready.\n\nhttps://apify.com/enezli/flarum-scraper\n\nDisclosure: our tool, a paid Apify actor.",
  "linkTitle": null,
  "linkDescription": null,
  "createdAt": "2026-10-19T18:00:34.708Z",
  "authorHandle": "@ranovam.bsky.social",
  "authorDisplayName": "Ranova",
  "authorFollowers": 8,
  "authorFollowing": 1,
  "authorPostsCount": 33,
  "authorProfileUrl": "https://bsky.app/profile/ranovam.bsky.social",
  "authorDid": "did:plc:x7fuip3nnerzvlr6g7naebvi",
  "likeCount": 0,
  "repostCount": 0,
  "replyCount": 0,
  "quoteCount": 0,
  "engagementTotal": 0,
  "language": "en",
  "languages": ["en"],
  "sentiment": "positive",
  "sentimentScore": 1,
  "matchedQueries": ["apify"],
  "matchedBrands": ["apify.com"],
  "matchedHashtags": [],
  "hashtags": [],
  "mentions": [],
  "links": ["https://apify.com/enezli/flarum-scraper"],
  "isReply": false,
  "replyToUri": null,
  "isQuote": false,
  "hasMedia": true,
  "postUri": "at://did:plc:x7fuip3nnerzvlr6g7naebvi/app.bsky.feed.post/3myap7aoson2r",
  "isNew": null,
  "scrapedAt": "2026-10-19T19:23:58.441Z"
}
```

The key-value record `SUMMARY` lists each search that was run, posts fetched, duplicates merged, sentiment counts and **`cappedQueries`** (searches that had more matches than could be returned).

### Limits of the public API (please read)

- **At most 100 posts per search per run.** Without a login, Bluesky's public AppView serves only the **first page** of search results (up to 100 posts). Requesting the next page returns HTTP 403, so this Actor does **not** paginate and doesn't try to work around the limit.
- In practice: for niche brands and keywords, 100 posts usually covers days or weeks. For big terms, narrow the search (`sinceDate`, `language`, exact phrases, `-exclusions`) and/or **schedule frequent runs with Only new posts** so that, over time, you capture everything. `SUMMARY.cappedQueries` tells you which searches hit the cap.
- Each `OR` branch and each brand variant is a separate search with its own 100-post window, so splitting a query widens coverage.
- Bluesky rejects `since:` on searches that contain only operators (`#tag`, `domain:`, `mentions:`). For those, the Actor fetches the newest 100 and filters dates itself.
- Engagement and follower counts are snapshots taken at scrape time. Sentiment is lexicon-based, so sarcasm and slang can be misread. Use it for triage, not as ground truth.
- Only public posts are returned. Deleted posts disappear from search. Not affiliated with Bluesky Social PBC.

### Pricing

Pay per result: **$2.00 per 1,000 posts delivered** (`result` event). Duplicates, filtered-out posts and posts skipped by *Only new posts* are **not charged**.

### Use from an AI agent

You can give this Actor to an AI agent as a tool through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) (`https://mcp.apify.com`), from Claude, Cursor, VS Code and other MCP clients. Add the server with only this Actor loaded:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=monriah-studio/bluesky-mentions"
    }
  }
}
```

On first connection your browser opens to sign in to Apify (OAuth). Or add `"headers": { "Authorization": "Bearer <APIFY_TOKEN>" }` to use your API token instead. Then ask your agent something like "Find Bluesky posts mentioning Apify from the last week".

You can also call it directly via the [Apify API](https://docs.apify.com/api/v2), for example to run it and get the results in one request:

```bash
curl -X POST "https://api.apify.com/v2/acts/monriah-studio~bluesky-mentions/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "queries": ["apify"],
  "sinceDate": "7 days",
  "maxResults": 50
}'
```

### More actors from MonRiah Studio

- [Greenhouse, Lever, Ashby & Workday Jobs Scraper](https://apify.com/monriah-studio/ats-hiring-signals): open roles and hiring signals from 6 ATS job boards, with change detection.
- [SEC Form 4 Insider Trading Scraper](https://apify.com/monriah-studio/sec-form4-insider-trades): insider trading data from official SEC EDGAR Form 4 filings.
- [RSS Feed Scraper & Monitor](https://apify.com/monriah-studio/rss-feed-monitor): RSS to JSON for any RSS or Atom feed, with new-item change detection.
- [Journalist Requests Scraper](https://apify.com/monriah-studio/journalist-requests): live #journorequest and PR source requests from Bluesky and Mastodon, a HARO alternative.
- [Grants.gov Funding Opportunities Scraper](https://apify.com/monriah-studio/grants-gov-opportunities): federal grant opportunities from the official Grants.gov API, with award amounts, deadlines, eligibility and new-grant alerts.

# Actor input Schema

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

Bluesky search queries, one per line. Supports `"exact phrase"`, `-excludedword`, `OR` (each side is searched separately and merged), and Bluesky operators `from:handle`, `mentions:handle`, `domain:example.com`, `lang:en`. Terms on one line are ANDed. If queries, brands and hashtags are all empty, the Actor searches `apify` and `"web scraping"` as a demo.

## `brands` (type: `array`):

Brand names, Bluesky handles or domains. A name becomes an exact-phrase search; `@handle` adds `mentions:handle`; a domain like `apify.com` adds `domain:apify.com` (posts linking to it).

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

Hashtags to track, with or without #.

## `excludeKeywords` (type: `array`):

Drop posts containing any of these words (case-insensitive). Single words are also excluded server-side.

## `sinceDate` (type: `string`):

Only posts on or after this date: `YYYY-MM-DD` or relative like `24 hours`, `3 days`. Leave empty for no limit (newest 100 per search).

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

Optional language code such as `en`, `de`, `ja`. Empty = all languages.

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

Bluesky search ordering, also used to sort the output.

## `maxResults` (type: `integer`):

Maximum posts returned across all searches. You pay only for posts delivered.

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

Include posts that are replies in a thread.

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

Skip posts with fewer likes.

## `minFollowers` (type: `integer`):

Skip posts from authors with fewer followers (needs author profiles).

## `fetchAuthorProfiles` (type: `boolean`):

Look up follower, following and post counts for each author (public getProfiles API, 25 authors per call).

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

For scheduled alerts: return only posts not delivered by earlier runs that used the same state store.

## `stateStoreName` (type: `string`):

Named key-value store for 'Only new posts'. Use a different name for each monitor.

## Actor input object example

```json
{
  "queries": [
    "apify",
    "\"web scraping\" OR crawlee"
  ],
  "brands": [
    "apify.com"
  ],
  "hashtags": [],
  "excludeKeywords": [],
  "sinceDate": "7 days",
  "language": "",
  "sort": "latest",
  "maxResults": 100,
  "includeReplies": true,
  "minLikes": 0,
  "minFollowers": 0,
  "fetchAuthorProfiles": true,
  "onlyNewSinceLastRun": false,
  "stateStoreName": "bluesky-mentions-state"
}
```

# Actor output Schema

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

All posts delivered by this run.

## `summary` (type: `string`):

JSON record SUMMARY: searches run, posts fetched, duplicates, capped searches, sentiment counts.

# 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": [
        "apify",
        "\"web scraping\" OR crawlee"
    ],
    "brands": [
        "apify.com"
    ],
    "hashtags": [],
    "sinceDate": "7 days",
    "maxResults": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("monriah-studio/bluesky-mentions").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": [
        "apify",
        "\"web scraping\" OR crawlee",
    ],
    "brands": ["apify.com"],
    "hashtags": [],
    "sinceDate": "7 days",
    "maxResults": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("monriah-studio/bluesky-mentions").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": [
    "apify",
    "\\"web scraping\\" OR crawlee"
  ],
  "brands": [
    "apify.com"
  ],
  "hashtags": [],
  "sinceDate": "7 days",
  "maxResults": 100
}' |
apify call monriah-studio/bluesky-mentions --silent --output-dataset

```

## MCP server setup

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

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/LTENMFiNDofelDyTL/builds/csl7qPNcQLB9cMSMu/openapi.json
