SFOLN

Catalogue / Social media data

Brand Monitoring – X, Reddit, News & Bluesky

sfoln/brand-mentions-monitor · Social media, News, Automation On request

Monitor brand mentions on X (Twitter), Reddit, Google News, the web, Bluesky, Hacker News and your RSS feeds in one run: one row per mention with text, URL, author, date, engagement, language and sentiment, plus a per-brand summary. $1 per 1,000 mentions + $0.01 per brand.

About

What it does

Brand Monitoring – X, Reddit, News & Bluesky tracks who is talking about your brand, product or keyword across seven channels in one run: X (Twitter) posts, Reddit posts, Google News articles, Google web results, Bluesky posts, Hacker News stories and comments, and the RSS/Atom feeds you list. Every mention becomes one normalized row (source, title/text, URL, author, publish date, engagement) with its language and sentiment; the same mention found by two sources is delivered once. Each brand also gets a summary row: counts per source, sentiment split, volume by day, top domains and repeat authors. With onlyNew, scheduled runs deliver (and charge) only mentions you have not received before. Built for PR and comms teams, social listening, competitor tracking, reputation alerts and agency reporting.

Price

Price per delivered record

EventPricePer 1,000Charged for
Brand mention
brand-mention
$0.001$1 / 1,000Charged once per mention row delivered (an X post, Reddit post, news article, web page, Bluesky post, Hacker News story or comment, or feed item mentioning the brand).
Brand monitor query
brand-monitor-query
$0.01$10 / 1,000Charged once per brand whose sources were queried; covers the per-call minimums of the first page of each paid source (also when nothing is found).

Apify free plan: up to 10 items per run. Paid plans have no per-run cap; set maxTotalChargeUsd to cap spend.

Run

Call it from code, an agent or the Console

This API is private on Apify for now. Email us and we will publish it for you, usually within two working days. The calls below work once it is public. contact@sfoln.com

curl · synchronous run, rows in the response
curl -X POST "https://api.apify.com/v2/actors/sfoln~brand-mentions-monitor/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"brands":["Apify"]}'
mcp.json · hosted Apify MCP server
{
  "mcpServers": {
    "apify": {
      "type": "http",
      "url": "https://mcp.apify.com?tools=sfoln/brand-mentions-monitor"
    }
  }
}
asynchronous run · for large batches
POST https://api.apify.com/v2/actors/sfoln~brand-mentions-monitor/runs?maxTotalChargeUsd=1
GET  https://api.apify.com/v2/actor-runs/{runId}            # until status is SUCCEEDED
GET  https://api.apify.com/v2/datasets/{defaultDatasetId}/items?format=json

Authenticate with an Apify API token. MCP clients can instead sign in with OAuth when prompted. Example prompt for an agent: Find this week's mentions of the brand "Apify" on X, Reddit, Google News, the web, Bluesky and Hacker News, and summarize what people are saying and how positive it is.

Input

Input fields

List brand names or keywords. Each brand produces one row per mention found plus one summary row.

FieldTypeDefaultMeaning
brands *arrayrequiredBrands or keywords
Brand names or keywords, one per line. Multi-word names are searched as exact phrases; advanced search syntax (quotes, OR, -word) is passed through as written. Accounts on the Apify free plan can process up to 10 brands per run.
sourcesarray["x","reddit","news","web","bluesky","hackernews"]Sources
Where to look: x (X / Twitter posts), reddit (Reddit posts), news (Google News), web (Google web results), bluesky (Bluesky posts), hackernews (Hacker News stories and comments), rss (the feeds listed below). Default: all but rss; rss is added whenever feeds are given.
feedsarray—RSS / Atom feeds
Feed URLs (RSS, Atom, JSON Feed) or website / newsletter URLs whose feed is discovered automatically (up to 20). Their items that mention the brand become mentions (source rss). Each feed is read once per run for all brands.
onlyNewbooleanfalseOnly new mentions
Deliver (and charge) only mentions that earlier runs did not deliver for the same brand. Built for schedules: the first run returns the current mentions, later runs only what is new. The memory lives in a key-value store named brand-mentions-monitor-memory in your account (30 days).
maxPerSourceinteger20Max mentions per source
Upper limit of mentions per brand and source (10–100), newest / most relevant first. Range 10–100.
timeRangestring"week"Time range
Only mentions from the last day, week, month or year (any = no limit). One of "day", "week", "month", "year", "any".
countrystring"us"Country (news & web)
2-letter country code for Google News and web results (gl), e.g. us, gb, de.
languagestring"en"Language (news & web)
Interface language for Google News and web results (hl), e.g. en, de.
excludeDomainsarray—Exclude domains
Domains to leave out (e.g. your own site: apify.com). Applied to all sources and as -site: filters on web search; posts are never dropped for their own platform's domain (x.com, reddit.com, bsky.app, news.ycombinator.com: use Sources to leave a platform out).
excludeRetweetsbooleantrueExclude reposts on X
Skip plain reposts (retweets) in X results.
maxItemsinteger100Max brands
Safety cap on how many brands are processed in this run; the rest are ignored and counted in the OUTPUT record. Range 1–500.
concurrencyinteger2Concurrency
Brands processed in parallel (1–4). Sources of one brand are always queried in parallel. Range 1–4.
itemTimeoutSecsinteger600Per-brand timeout (seconds)
Time limit per brand; paging stops early when it is near. Range 120–1800.
includeRawbooleanfalseInclude raw upstream response
Attach the unmodified upstream item (tweet, Reddit post, search result, Bluesky post, Hacker News hit or feed item) to each mention row under `raw`.
Example input
{
  "brands": [
    "Apify"
  ]
}

Output

One record per input item

Records land in the run's dataset; a synchronous call returns them directly. Each has a status (ok is charged; everything else is free) and a charged flag. The run's OUTPUT record totals items and charges.

FieldTypeMeaning
inputstring | objectInput
The input item this record corresponds to.
statusstringStatus
ok (mention row charged brand-mention; summary row charged brand-monitor-query) | error (all sources failed or nothing could be queried; not charged) | skipped_budget | skipped_free_plan e.g. "ok"
chargedbooleanCharged
Whether this record incurred a pay-per-event charge.
chargedEventstringCharged event
Pay-per-event event charged for this record.
sourcestringSource
Mention rows: platform (x | reddit | news | web | bluesky | hackernews | rss). Summary rows: multi-source.
fetchedAtstringFetched at
ISO timestamp.
errorobjectError
code / message when status is not ok (or a partial failure).
warningsarrayWarnings
Non-fatal notes (partial data, stopped early, free-plan caps).
recordTypestringRecord type
mention (one per mention found) or summary (one per brand).
brandstring | nullBrand
Brand / keyword the row belongs to.
providerstring | nullProvider
Mention rows: upstream (twitterapi, scrapecreators, serper, bluesky, hackernews, feeds).
positioninteger | nullPosition
Mention rows: 1-based position within its source for this brand.
mentionIdstring | nullMention id
X post id, Reddit post id, Bluesky at:// URI, Hacker News item id or feed item guid.
titlestring | nullTitle
Reddit post title, news headline, web page title, Hacker News story title (for comments: the story they belong to) or feed item title.
textstring | nullText
Post text (X, Bluesky), self-text (Reddit), comment or story text (Hacker News), snippet (news / web) or feed summary / snippet around the brand (RSS); ≤ 1000 chars.
urlstring | nullURL
Link to the mention.
domainstring | nullDomain
x.com, reddit.com, bsky.app, news.ycombinator.com or the publishing site.
authorstring | nullAuthor
X handle, Reddit username, Bluesky handle, Hacker News user, news publisher or feed item author.
authorNamestring | nullAuthor name
X or Bluesky display name.
authorFollowersinteger | nullAuthor followers
X author's followers.
publishedAtstring | nullPublished
ISO timestamp.
publishedAtIsEstimateboolean | nullDate is estimate
True when derived from a relative label ("3 hours ago").
languagestring | nullLanguage
ISO 639-1 language of the mention: the platform's own tag when it has one, else detected from the text.
communitystring | nullCommunity
Subreddit (Reddit) or Hacker News item type (story, comment, ask_hn, show_hn, launch_hn, tell_hn).
rankinteger | nullRank
Position in Google News / web results.
engagementobject | nullEngagement
{ likes, reposts, replies, quotes, views } (X, Bluesky) or { score, comments } (Reddit, Hacker News).
engagementTotalinteger | nullEngagement total
likes + reposts + replies + quotes (X, Bluesky) or score + comments (Reddit, Hacker News); null for news, web and RSS.
sentimentstring | nullSentiment
Mention rows: positive | neutral | negative (VADER, English text); null for other languages.
sentimentScorenumber | nullSentiment score
Mention rows: VADER compound score from -1 (most negative) to 1 (most positive).
feedUrlstring | nullFeed URL
RSS mentions: the feed the item came from.
feedTitlestring | nullFeed title
RSS mentions: the feed's title.
sourcesarraySources
Summary rows: sources queried.
timeRangestring | nullTime range
Summary rows: day | week | month | year | any.
totalMentionsinteger | nullTotal mentions
Summary rows: mention rows delivered for the brand.
mentionsBySourceobject | nullMentions by source
Summary rows: { x, reddit, news, web, bluesky, hackernews, rss } counts.
topDomainsarrayTop domains
Summary rows: up to 10 { domain, count }.
topAuthorsarrayRepeat authors
Summary rows: up to 10 { author, source, count } with more than one mention.
newestMentionAtstring | nullNewest mention
Summary rows: ISO.
oldestMentionAtstring | nullOldest mention
Summary rows: ISO.
totalEngagementinteger | nullTotal engagement
Summary rows: sum of engagementTotal.
sourceStatusobject | nullSource status
Summary rows: per source ok | error | skipped.
stopReasonsobject | nullStop reasons
Summary rows: why paging stopped per source (limit, end, budget, deadline, caught_up, error…).
sentimentCountsobject | nullSentiment counts
Summary rows: { positive, neutral, negative, unscored } mentions (unscored: not English).
averageSentimentnumber | nullAverage sentiment
Summary rows: mean sentiment score of the scored mentions (-1 … 1).
sentimentBySourceobject | nullSentiment by source
Summary rows: sentiment counts per source with mentions.
volumeByDayarray | nullVolume by day
Summary rows: [{ date, count }] by UTC publish day, oldest first.
topLanguagesarray | nullTop languages
Summary rows: up to 5 [{ language, count }].
duplicatesSkippedinteger | nullDuplicates skipped
Summary rows: mentions found again (same canonical URL) by another source or page; not charged.
nearDuplicatesSkippedinteger | nullNear-duplicates skipped
Summary rows: the same article under another URL from another source (news, web, RSS); not charged.
unrelatedSkippedinteger | nullUnrelated hits skipped
Summary rows: Bluesky / Hacker News hits whose text does not contain the brand; not charged.
onlyNewboolean | nullOnly new
Summary rows: true when onlyNew was on.
firstRunboolean | nullFirst run
Summary rows (onlyNew): no earlier run had remembered this brand.
alreadyDeliveredSkippedinteger | nullAlready delivered
Summary rows (onlyNew): mentions met that an earlier run delivered (not charged; newest-first sources stop at the first one).
rawobject | nullRaw
Mention rows with includeRaw: the unmodified upstream item.
Example record
{
  "input": "Apify",
  "recordType": "mention",
  "brand": "Apify",
  "source": "bluesky",
  "provider": "bluesky",
  "position": 1,
  "mentionId": "at://did:plc:example1/app.bsky.feed.post/3m1abcdxyz",
  "title": null,
  "text": "Moved our price monitoring to Apify last week and it has been fantastic so far.",
  "url": "https://bsky.app/profile/dataops-team1.bsky.social/post/3m1abcdxyz",
  "domain": "bsky.app",
  "author": "dataops-team1.bsky.social",
  "authorName": "Data Ops Team 1",
  "authorFollowers": null,
  "publishedAt": "2026-10-14T05:00:00.000Z",
  "publishedAtIsEstimate": false,
  "language": "en",
  "community": null,
  "rank": null,
  "engagement": {
    "likes": 14,
    "reposts": 3,
    "replies": 2,
    "quotes": 1,
    "views": null,
    "score": null,
    "comments": null
  },
  "engagementTotal": 20,
  "sentiment": "positive",
  "sentimentScore": 0.5574,
  "feedUrl": null,
  "feedTitle": null,
  "status": "ok",
  "charged": true,
  "chargedEvent": "brand-mention",
  "fetchedAt": "2026-10-14T10:00:02.000Z"
}

FAQ

Questions

How do I get only new mentions on a schedule?
Turn on onlyNew and schedule the Actor (for example daily). The first run returns the current mentions; later runs deliver and charge only mentions that no earlier run delivered for the same brand.
How is sentiment calculated?
Locally with VADER, a lexicon built for English social-media text, so there is no AI fee. English mentions get positive, neutral or negative and a score from -1 to 1; other languages get null (their language is still detected).
Can I monitor blogs and newsletters?
Yes: list their RSS/Atom feeds or website URLs in feeds. Every item that mentions the brand in its title, summary or content becomes a mention with source rss.

Machine-readable

This page for agents