# Brand Mentions Monitor — Web Mentions & Sentiment (`cheapapi/brand-mentions-monitor`) Actor

Track brand mentions on news, blogs, forums & shops with sentiment, emotions, domain rank & monthly trend. Only-new mode for schedules.

- **URL**: https://apify.com/cheapapi/brand-mentions-monitor.md
- **Developed by:** [CheapAPI](https://apify.com/cheapapi) (community)
- **Categories:** SEO tools, Marketing, News
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event + usage

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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

## Brand Mentions Monitor — Web Mentions & Sentiment

**Find web pages that mention your brand, with sentiment, emotions and site authority for each mention.** The Actor searches news sites, blogs, forums, online shops and organization websites. You get one row per mention, plus a free summary with a sentiment breakdown, top domains and a monthly trend. Turn on **Only new mentions** and schedule it to get just the new mentions each day or week. You don't need an API key or login.

> **What it covers:** the open web — news sites, blogs, forums and message boards, online shops, review and product pages, and organization websites. **It does not cover Instagram, TikTok, X (Twitter), Facebook or other social networks.** For those, use a platform-specific scraper next to this Actor.

### Why this Actor

- **Price from $0.20 per 1,000 mentions** (Gold, Platinum and Diamond plans) plus $0.033 per search of up to 1,000 mentions. On the Free plan, 100 mentions cost $0.27. On Gold and Platinum we cost less than every Google News Actor in the comparison below. On Free and Bronze (and for some of them on Silver or Diamond) several news-only scrapers are cheaper than this Actor — but they cover Google News only, without sentiment or emotion scores. Apify platform usage is billed separately by Apify (at the default 256 MB a small run typically uses about $0.001–$0.005).
- **47 fields per mention**: URL, domain, title, snippet, publication date (with a `dateBest` fallback to the discovery date), language, country, sentiment (positive/negative/neutral scores), six emotion scores, page type, topic categories, domain rank, page rank and spam score.
- **Few requests for large runs**: one search returns up to 1,000 mentions, and you can get up to 20,000 mentions per keyword and up to 50 keywords per run.
- **Built for monitoring**: "Only new mentions" remembers what you already received, so repeats are never charged as mentions (a run with nothing new costs $0.0303 per keyword for the search).
- **Free summary** for every keyword: sentiment shares, net sentiment, average emotions, top domains, countries, languages, page types and trend by month.
- **Keyword-based on purpose**: a mention is text on a page, so you track a brand, product or phrase. To watch specific websites, add them under **Only these domains**; to exclude your own site, use **Exclude domains**.

### Compared with alternatives

Typical run: **1,000 results for one brand**. Prices are for the whole run.

| Option | What it covers | Blogs, forums & shops | Sentiment & emotion scores | Free | Bronze | Silver | Gold | Platinum | Diamond |
|---|---|---|---|---|---|---|---|---|---|
| Most-used Google News scraper on the Store (~2,650 users) | Google News articles | ✗ | ✗ | $5.09 | $5.09 | $5.09 | $5.09 | $5.09 | $5.09 |
| Fast pay-per-event Google News scraper (~2,100 users) | Google News articles | ✗ | ✗ | $4.00 | $4.00 | $3.75 | $1.00 | $1.00 | $1.00 |
| Tiered pay-per-result Google News scraper (~550 users) | Google News articles | ✗ | ✗ | **$2.31** | **$2.01** | $1.57 | $1.21 | $0.81 | $0.57 |
| Low-cost pay-per-result Google News scraper (~480 users) | Google News articles | ✗ | ✗ | **$2.01** | **$1.68** | **$1.34** | $1.01 | $1.01 | $1.01 |
| Cheapest per-result Google News monitoring Actor (~100 users) | Google News articles | ✗ | ✗ | **$1.01** | **$0.67** | **$0.57** | $0.47 | $0.29 | **$0.14** |
| Most-used social-media sentiment Actor (~2,650 users) | Comments on one profile's Facebook, Instagram and TikTok posts | ✗ | ✓ (sentiment) | $4.00 | $3.35 | $2.70 | $2.05 | $1.40 | $0.75 |
| **This Actor** | News, blogs, forums, shops, review and organization pages | ✓ | ✓ (3 sentiment + 6 emotion scores) | $2.43 | $2.03 | $1.53 | **$0.23** | **$0.23** | $0.23 |

Prices from public Apify Store listings, checked September 2026 (per-result price plus any start fee; the listings of these six Actors do not show platform usage charged to the user). For this Actor, Apify platform usage is billed separately by Apify on top of the price shown (at the default 256 MB a small run typically uses about $0.001–$0.005, so a 1,000-mention run stays around $0.23–$0.24 on Gold). On Apify, Platinum and Diamond plans pay this Actor's Gold price. Features are taken from each listing's description.

Honest notes: several news-only Google News scrapers cost less than this Actor on the Free and Bronze plans (the ~100-user Actor $1.01 vs $2.43 and $0.67 vs $2.03; the ~480-user one $2.01 vs $2.43 and $1.68 vs $2.03; the ~550-user one $2.31 vs $2.43 and $2.01 vs $2.03). Some are also cheaper on Silver (the ~100-user Actor $0.57 and the ~480-user one $1.34 vs our $1.53) and on Diamond (the ~100-user Actor $0.14 vs our $0.23). This Actor is the cheapest option in the table on Gold and Platinum, even after adding a few tenths of a cent of platform usage, and against the two most-used Google News scrapers and the social-media sentiment Actor it is cheaper on every plan. It is also the only option in the table that covers the wider web (blogs, forums, shops, organization sites) with sentiment and emotion scores for every mention. Pick a Google News Actor if news headlines are all you need. Here you also get blogs, forums, shops and organization sites, a sentiment and emotion score for every mention, domain and page rank, spam score, a free summary, and an "Only new mentions" mode where repeats are never charged as mentions. Brand-monitoring SaaS subscriptions add social networks, dashboards and built-in alerts, but charge a monthly fee whether or not there are new mentions.

### Not included

- **Social network posts** (Instagram, TikTok, X, Facebook): our index covers the open web.
- **YouTube videos and comments**: use [YouTube Search Scraper](https://apify.com/cheapapi/youtube-search-scraper) to find videos about your brand and [YouTube Comments Scraper](https://apify.com/cheapapi/youtube-comments-scraper) for their comments.
- **Brand mentions in AI answers** (ChatGPT, Perplexity, Google AI Overviews): use [AI Search Visibility Tracker](https://apify.com/cheapapi/ai-search-visibility-tracker).
- **Links to your site without a text mention**, or tracking a URL: mentions are found by text. For pages that link to a URL or domain, use [Backlink Checker](https://apify.com/cheapapi/backlink-checker).
- **Google search rankings** for your brand: use [Google SERP Scraper](https://apify.com/cheapapi/google-serp-scraper).
- **Pages behind a login, full page text and author contact details**: you get the text block around the mention, not the whole page, and no personal contact data.

### What data you get

| Field | Type | Example |
|---|---|---|
| `rowType` | string | `mention` (or `summary` for the summary row) |
| `keyword` | string | `Logitech` |
| `url` | string | `https://www.vikingdirekt.ch/de/logitech-…-p-7160985` |
| `domain` / `mainDomain` | string | `www.vikingdirekt.ch` / `vikingdirekt.ch` |
| `title` | string | `Logitech M185 Maus Kabellos Blau…` |
| `sectionTitle` / `previousSectionTitle` | string | `null` / `Beschreibung` |
| `snippet` | string | `Keine Verzögerungen oder Ausfälle… Logitech` |
| `highlightedText` | string | matched words inside the snippet, when available |
| `author` | string | `null` |
| `datePublished` | ISO date | `2025-03-14T08:00:00.000Z` (null when the page has no date) |
| `dateBest` | ISO date | `2025-03-14T08:00:00.000Z` — the publication date, or `discoveredAt` when the page has none (rarely null) |
| `discoveredAt` | ISO date | `2026-08-26T09:50:52.000Z` (when our crawler found the page) |
| `groupDate` | ISO date | `2023-02-24T09:03:53.000Z` (when this text block was first recorded) |
| `language` / `country` | string | `de` / `CH` |
| `sentiment` | string | `negative` (label with the highest score) |
| `positiveScore` / `negativeScore` / `neutralScore` | number 0–1 | `0.0109` / `0.9711` / `0.018` |
| `emotionAnger`, `emotionHappiness`, `emotionLove`, `emotionSadness`, `emotionShare`, `emotionFun` | number 0–1 | `0.579` |
| `pageType` / `pageTypes` | string / array | `ecommerce` / `["ecommerce"]` (news, blogs, message-boards, ecommerce, organization) |
| `pageCategories` / `textCategories` | array | `["Computers & Consumer Electronics", "Consumer Electronics"]` |
| `pageCategoryCodes` / `textCategoryCodes` | array | `[10019, 10167]` |
| `domainRank` / `pageRank` | number | `504` / `63` (shown on the 0–1000 scale; 0–100 by default) |
| `spamScore` | number 0–100 | `0` |
| `contentQualityScore` | number 0–100 | `100` |
| `relevanceScore` | number | `64538.832` |
| `contentType`, `headingLevel`, `snippetLength`, `semanticLocation` | mixed | `page_content`, `1`, `122`, `main` |
| `rating`, `socialMetrics` | array | on-page rating, social counts when available |
| `id` | string | stable row id: same keyword + same mention → same id in every run (summary rows too) |
| `mentionId` | string | stable id of the mention (same page + same text) |
| `scrapedAt` | ISO date | `2026-09-28T15:56:44.509Z` |

For each keyword you also get one **summary row** (`rowType: "summary"`), which is also saved as `SUMMARY` in the key-value store:
`mentionsDelivered`, `totalMatchingMentions` (all matches in the index), `sentimentCounts`, `positiveShare` / `negativeShare` / `neutralShare`, `netSentiment` (−1 to 1), `averageScores`, `averageEmotions`, `topDomains`, `uniqueDomains`, `countries`, `languages`, `pageTypes`, `trendByMonth` and `mentionsWithoutDate`. With the optional web-wide statistics, it also includes `webWide`.

### How to use

1. Open the Actor in Apify Console and go to the **Input** tab.
2. Under **Brands or keywords**, enter one or more brands, products or phrases.
3. Optional: set a date range, languages and countries, and turn on **Only new mentions**.
4. Click **Start**. Mentions show up in the **Output** tab. You can export them as JSON, CSV or Excel.
5. For ongoing monitoring, open **Schedules** and run the Actor daily or weekly with "Only new mentions" turned on.

Input you can paste:

```json
{
    "keywords": ["Logitech", "logitech mx master"],
    "maxMentions": 200,
    "dateFrom": "30 days",
    "languages": ["en", "de"],
    "countries": ["US", "GB", "DE"],
    "onlyNewMentions": true
}
```

**API (curl)**

```bash
curl -X POST "https://api.apify.com/v2/acts/cheapapi~brand-mentions-monitor/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"keywords":["Logitech"],"maxMentions":100,"dateFrom":"30 days"}'
```

**JavaScript (apify-client)**

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

const client = new ApifyClient({ token: '<YOUR_TOKEN>' });
const run = await client.actor('cheapapi/brand-mentions-monitor').call({
    keywords: ['Logitech'],
    maxMentions: 100,
    onlyNewMentions: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const mentions = items.filter((i) => i.rowType === 'mention');
console.log(mentions.length, 'new mentions');
```

**Python (apify-client)**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_TOKEN>")
run = client.actor("cheapapi/brand-mentions-monitor").call(run_input={
    "keywords": ["Logitech"],
    "maxMentions": 100,
    "sentiment": "negative",
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    if item["rowType"] == "mention":
        print(item["negativeScore"], item["url"])
```

### Use cases

- **Brand monitoring and PR**: get a daily feed of new articles, blog posts and forum threads that mention your brand.
- **Crisis detection**: filter by negative sentiment or anger, and alert your team through a webhook.
- **Competitor tracking**: monitor competitor brands and compare share of voice, sentiment and top domains.
- **Link building and outreach**: find sites that mention you without linking to you. Filter by domain rank and spam score.
- **Market research**: see which countries, languages and page types talk about a product, and how that changes over the months.
- **Influencer and media lists**: find the domains that write about a topic most often.

### Advanced options

| Option | Default | Meaning |
|---|---|---|
| Exact phrase | on | Multi-word keywords are matched as an exact phrase. Turn it off to match the words in any order. |
| Match only in | anywhere | Require the keyword in the text snippet, section title, page title or previous section title. |
| Page types | all | News, blogs, forums & message boards, online shops, organizations. |
| Results per domain | all mentions | "One mention per domain" returns only the best mention from each site. |
| Sort by | relevance | Newest or oldest published, recently discovered, most positive or negative, highest domain rank, page rank or content quality. With "Only new mentions", the default is "recently discovered". |
| Date range applies to | publication date | Or discovery date (every page has one; many pages have no publication date). |
| Only these domains / Exclude domains | – | Include or exclude websites. Subdomains are included. |
| Rank scale | 0–100 | Or 0–1000 for finer ranks. Used in the output and in the rank filters. |
| Min/Max domain rank, Min/Max page rank | – | Authority ranges. |
| Max spam score | – | Skip spammy sites (0–100). |
| Min content quality | – | Only well-written text blocks (0–100). |
| Sentiment + minimum probability | any, 0.4 | Only positive, negative or neutral mentions. |
| Emotion + minimum probability | any, 0.4 | Only mentions that express anger, happiness, love, sadness, share or fun. |
| Monitor name | – | Shares one "only new" memory across runs, even if you change filters. |
| Start the memory over | off | Forget what was delivered before and treat everything as new. |
| Add web-wide statistics | off | Paid add-on. Adds totals for all matching mentions (sentiment and emotion counts, top domains, countries, languages, categories) and a day, week or month trend. |
| Trend grouping | month | Day, week or month. Up to 400 time buckets. |
| Top list size | 10 | Length of the top lists (1–20). |
| Sentiment threshold / Emotion threshold | 0.4 / 0.4 | Minimum probability for a mention to count in the web-wide statistics. |
| Custom filters (JSON) | – | Your own filter expression, combined with AND, e.g. `[["domain_rank", ">", 300], "or", ["country", "=", "US"]]`. The input form lists all fields and operators. |
| Custom sort | – | Up to 3 rules like `domain_rank,desc`. Overrides "Sort by". |

You can combine up to 8 filter conditions in one run. Languages, countries, included domains and excluded domains count as one condition each. A date range counts as two, and "Only new mentions" uses one.

### Output example

```json
{
    "id": "36E4sBBW_vzvpOZ3WQ9e",
    "rowType": "mention",
    "keyword": "Logitech",
    "mentionId": "P5YX9tlWXIWSTyPx",
    "url": "https://www.vikingdirekt.ch/de/logitech-kabellose-ergonomische-maus-beidhandig-m185-blau-p-7160985",
    "domain": "www.vikingdirekt.ch",
    "mainDomain": "vikingdirekt.ch",
    "title": "Logitech M185 Maus Kabellos Blau, Schwarz Geeignet Für Linkshänder",
    "sectionTitle": null,
    "previousSectionTitle": "Beschreibung",
    "snippet": "Keine Verzögerungen oder Ausfälle. Der winzige kabellose Empfänger garantiert Ihnen eine zuverlässige Verbindung. Logitech",
    "highlightedText": null,
    "author": null,
    "datePublished": null,
    "dateBest": "2026-08-26T09:50:52.000Z",
    "discoveredAt": "2026-08-26T09:50:52.000Z",
    "groupDate": "2023-02-24T09:03:53.000Z",
    "language": "de",
    "country": "CH",
    "sentiment": "negative",
    "positiveScore": 0.0109,
    "negativeScore": 0.9711,
    "neutralScore": 0.018,
    "emotionAnger": 0.579,
    "emotionHappiness": 0.073,
    "emotionLove": 0.057,
    "emotionSadness": 0.1667,
    "emotionShare": 0.0606,
    "emotionFun": 0.0638,
    "pageType": "ecommerce",
    "pageTypes": [
        "ecommerce"
    ],
    "pageCategories": [
        "Arts & Entertainment",
        "Computers & Consumer Electronics",
        "Consumer Electronics",
        "Internet & Telecom",
        "Internet"
    ],
    "pageCategoryCodes": [
        10013,
        10019,
        10167,
        10007,
        13418
    ],
    "textCategories": [
        "Computers & Consumer Electronics",
        "Consumer Electronics",
        "Consumer Electronic Accessories",
        "Family & Community",
        "Community Service & Social Organizations",
        "Consumer Resources",
        "Product Reviews & Price Comparisons",
        "Business & Industrial"
    ],
    "textCategoryCodes": [
        10019,
        10167,
        10872,
        10002,
        10028,
        10222,
        13813,
        10004
    ],
    "contentType": "page_content",
    "headingLevel": 1,
    "snippetLength": 122,
    "contentQualityScore": 100,
    "semanticLocation": "main",
    "domainRank": 504,
    "pageRank": 63,
    "spamScore": 0,
    "relevanceScore": 64538.832,
    "rating": [
        {
            "name": null,
            "ratingValue": 5,
            "maxRatingValue": 5,
            "ratingCount": 1,
            "relativeRating": 1
        }
    ],
    "socialMetrics": [],
    "scrapedAt": "2026-09-28T15:56:44.509Z"
}
```

Summary row (shortened):

```json
{
    "id": "_dLcl1d6cwZ5z7IDAXlI",
    "rowType": "summary",
    "keyword": "Logitech",
    "onlyNewMentions": false,
    "mentionsDelivered": 10,
    "totalMatchingMentions": 6053151,
    "sentimentCounts": { "positive": 0, "negative": 9, "neutral": 1, "unknown": 0 },
    "positiveShare": 0,
    "negativeShare": 0.9,
    "neutralShare": 0.1,
    "netSentiment": -0.9,
    "averageEmotions": { "anger": 0.5732, "happiness": 0.0854, "love": 0.0358, "sadness": 0.1534, "share": 0.0787, "fun": 0.0737 },
    "topDomains": [{ "domain": "sentihub.com", "mentions": 5 }, { "domain": "viking.de", "mentions": 2 }],
    "uniqueDomains": 5,
    "trendByMonth": [{ "month": "2021-09", "mentions": 2, "positive": 0, "negative": 2, "neutral": 0 }]
}
```

### Pricing

**Apify Free plan:** Apify does not pay developers for usage on its Free plan, so on the Free plan this Actor can be used for up to **$0.25 of results per calendar month** — enough to try it on a small input. When the allowance is used up, the run ends with a clear message (not an error). Any paid Apify plan removes the limit; prices are the same.

Pay per event. Mentions are charged only when delivered, and the summary row is always free. Every search is paid for by us whether or not it finds something, so a search that delivers nothing costs a small fixed fee instead of the normal search price (see the last three rows). There is no start fee and no subscription. Apify platform usage is billed separately by Apify (at the default 256 MB a small run typically uses about $0.001–$0.005); the prices and examples on this page are event fees only.

| Event | Free | Bronze | Silver | Gold, Platinum, Diamond |
|---|---|---|---|---|
| Mentions search (per keyword, per up to 1,000 mentions) | $0.033 | $0.033 | $0.033 | $0.033 |
| Mention (per delivered mention) | $0.0024 | $0.002 | $0.0015 | $0.0002 |
| Web-wide statistics (optional, per keyword) | $0.08 | $0.08 | $0.08 | $0.08 |
| Search without delivered mentions (nothing matches, nothing new, or no answer) | $0.0303 | $0.0303 | $0.0303 | $0.0303 |
| Fetched mention not delivered (already delivered before, duplicate, or over your max cost) | $0.0001 | $0.0001 | $0.0001 | $0.0001 |
| Web-wide statistics without data (optional add-on on, lookup returned nothing) | $0.0786 | $0.0786 | $0.0786 | $0.0786 |

A search is charged either "Mentions search" (at least one mention delivered) or "Search without delivered mentions", never both. With default settings (no "Only new mentions") the two search check fees are practically never charged, except $0.0303 for a keyword that matches nothing.

Worked examples:

- **100 mentions of one brand** costs $0.033 + 100 × $0.0024 = **$0.27** on the Free plan, or **$0.053** on Gold.
- **1,000 mentions** costs $0.033 + 1,000 × $0.0015 = **$1.53** on Silver, or **$0.23** on Gold.
- **Daily monitoring of 3 brands** with about 20 new mentions each and about 10 repeats skipped per brand costs 3 × ($0.033 + 20 × $0.002 + 10 × $0.0001) = **$0.22 per day** on Bronze. A day without anything new costs 3 × ($0.0303 + 10 × $0.0001) = **$0.094**.
- **A keyword that matches nothing** (for example a typo or too many filters) costs **$0.0303**. With web-wide statistics on, the statistics are then skipped for free.

Set **Maximum cost per run** in the run options, and the Actor stops before it goes over your limit.

### Integrations

- **Scheduling**: run daily or weekly with "Only new mentions" turned on to get a steady feed of new mentions.
- **Webhooks**: trigger Slack, email or your own endpoint when a run finishes. See the Slack alert example below for negative mentions.
- **Make and Zapier**: use the Apify apps to send new mentions to Google Sheets, Airtable, Notion, a CRM or a chat channel.
- **Google Sheets**: export the dataset directly, or append it after each scheduled run.
- **API and MCP**: call the Actor from your own code with the `run-sync-get-dataset-items` endpoint, or let an AI agent run it through the Apify MCP server.
- **Export formats**: download the dataset as JSON, CSV, Excel, XML, HTML or RSS.

#### Slack alert for negative mentions

Schedule the Actor with "Only new mentions" on, then add a webhook for the event **Run succeeded** that points to a small function of yours (for example a Make or Zapier scenario, a Cloudflare Worker or a Google Cloud Function). The function reads the run's dataset and posts negative mentions to a Slack incoming webhook:

```js
// Called by the Apify webhook ("Run succeeded"); the default payload includes resource.defaultDatasetId.
export default async function handler(req) {
    const { resource } = await req.json();
    const url = `https://api.apify.com/v2/datasets/${resource.defaultDatasetId}/items?clean=true&token=${process.env.APIFY_TOKEN}`;
    const items = await (await fetch(url)).json();
    const negative = items.filter((i) => i.rowType === 'mention' && i.sentiment === 'negative' && i.negativeScore >= 0.7);
    if (!negative.length) return new Response('nothing to report');
    const lines = negative.slice(0, 20).map((m) => `• *${m.keyword}* (${m.mainDomain}, rank ${m.domainRank}): <${m.url}|${m.title || m.url}>`);
    await fetch(process.env.SLACK_WEBHOOK_URL, {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({ text: `${negative.length} new negative mention(s)\n${lines.join('\n')}` }),
    });
    return new Response('sent');
}
```

Tip: if you only need the alert feed, set **Sentiment** to "negative" (`"sentiment": "negative"`) in the scheduled input. Then only negative mentions are delivered and charged, and the function above just formats them.

### FAQ

**Is there a limit on the Apify Free plan?** Yes: up to $0.25 of this Actor's results per calendar month, enough to try it. Apify pays developers nothing for Free-plan usage while our data costs are real, so this keeps the Actor sustainable. Runs that reach the allowance stop cleanly and keep everything collected so far; the allowance resets on the 1st of the month. Any paid Apify plan has no limit.

**Is it legal?**
The Actor returns publicly available information from public web pages: URL, title, a short text snippet and computed scores. It collects no personal accounts or private data. Make sure your use of the data complies with the laws and terms that apply to you.

**How fresh is the data?**
Our crawler visits pages continuously. Each mention has `discoveredAt` (when the page was fetched) and, when the page provides one, `datePublished`. How quickly a new page appears depends on the site: large, often-updated sites are usually picked up sooner than small ones. Use `discoveredAt` to see when each page was found, or `dateBest` for one date column that is almost never empty (publication date when the page has one, otherwise the discovery date).

**Why did I get fewer results than "totalMatchingMentions"?**
`maxMentions` limits how many mentions you get per keyword (the default is 100). Filters, "one mention per domain" and a date range also narrow the results. With "Only new mentions", mentions you already received are skipped. Your maximum cost per run can also stop the Actor early.

**Why do I enter keywords and not URLs?**
A mention is a piece of text on a web page, and the index is searched by text. So you track a brand, product or phrase, not a URL. To watch particular websites, enter the keyword and add the sites under **Only these domains** (subdomains are included). To find pages that link to your URL, use [Backlink Checker](https://apify.com/cheapapi/backlink-checker).

**What happens if a run fails halfway through a keyword?**
Mentions saved before the problem stay in the dataset, and you pay only for those (plus, if a search got no answer, "Search without delivered mentions" and $0.0001 per requested mention, because that search may already have been paid for). They are also remembered in "Only new mentions" mode, so the next run does not deliver or charge them again. The summary row for that keyword covers the saved mentions.

**How does "Only new mentions" work?**
The Actor keeps a small memory in your Apify account (a key-value store named `brand-mentions-monitor-state`). The memory is kept per keyword and filter combination, or per "Monitor name" if you set one. On the next run, the Actor searches only pages discovered since shortly before the last complete run and skips mentions it already delivered. New mentions are charged as usual; each skipped repeat costs $0.0001, and a keyword with nothing new costs $0.0303 for its search.

**How is sentiment calculated?**
Each text block that mentions your keyword gets a probability for positive, negative and neutral. It also gets six emotion probabilities: anger, happiness, love, sadness, share and fun. `sentiment` is the label with the highest probability. The scores describe the text around the mention, which is not always about your brand. For example, a negative product review of a competitor on the same page can affect it.

**What is the difference between the free summary and web-wide statistics?**
The free summary is calculated from the mentions you received. Web-wide statistics (a paid add-on) count **all** matching mentions in the index, which can be millions for a big brand, and add a trend over time.

**How do I control what a run costs, and is platform usage included?**
Set **Max mentions per keyword** and, in the run options, **Maximum cost per run**. The Actor checks the remaining budget before every search (assuming the most that search could cost) and stops before it would go over it. The summary row is never charged. Apify platform usage (compute) is not included in these fees; Apify bills it separately. At the default 256 MB memory a small run typically uses about $0.001–$0.005; very large runs use more. Each run's usage is shown in Apify Console.

**Why was I charged $0.0303, $0.0001 or $0.0786?**
Every search is paid for, whether or not it finds something. When a search delivers no mention — nothing matches your keyword and filters, everything it found was delivered in an earlier run ("Only new mentions"), or it got no answer although it may already have been paid for — it costs $0.0303 instead of the normal $0.033 search fee. Each mention a search returned but that is not delivered (already delivered before, a duplicate, or over your maximum cost) costs $0.0001. With default settings you will practically never see these fees. **$0.0786 ("Web-wide statistics without data")**: web-wide statistics were on, the lookup was made, but it returned no data (no matching page in the period, or no answer arrived). The lookup is paid for either way. If the mentions search already found no matching page at all, the statistics are skipped and nothing is charged.

**Where do I get help?**
Open an issue in the Actor's **Issues** tab in Apify Console. Include the run link and describe what you expected.

### Limitations

- Social networks (Instagram, TikTok, X, Facebook and similar) are not covered.
- Coverage depends on our web index. Very new pages, pages behind a login and pages that block crawlers may be missing.
- Many pages have no publication date. When you filter by publication date, those pages are left out. Use "Date range applies to: discovery date" if you want to include them.
- Sentiment is computed per text block by a model. It can misread sarcasm, mixed opinions or text that is not about your brand.
- A search returns at most 1,000 mentions. Larger runs page through the results, and each page is one search event. The limit is 20,000 mentions per keyword per run.
- Up to 8 filter conditions can be combined per run.
- In "Only new mentions" mode, if a run stops at "Max mentions" or at your cost limit, the next run can still pick up the remaining mentions. When many new mentions arrive continuously, raise "Max mentions" so no mentions are skipped.

### Privacy and personal data

The Actor returns information from public web pages: URLs, titles, short text blocks and computed scores. An `author` name is included only when the page publishes one. It does not collect contact details, logins or private content. If you store or process names found in the results, you are responsible for complying with GDPR and other data-protection laws that apply to you.

# Actor input Schema

## `keywords` (type: `array`):

Brand names, product names or phrases to monitor, one per line (up to 50). Phrases with spaces are matched exactly (turn off "Exact phrase" below to match the words anywhere). Matching is case-insensitive. A keyword whose search delivers no mention (nothing matches, or nothing new) is charged one "Search without delivered mentions" ($0.0303), because the search is paid for either way.

## `maxMentions` (type: `integer`):

How many mentions to deliver per keyword (1–20,000). Each 1,000 mentions are one search.

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

Only mentions published on or after this date. Use 2025-01-31 or a relative period like "30 days", "6 months" or "1 year". Pages without a known publication date are left out when a date range is set (see "Date range applies to").

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

Only mentions published on or before this date (inclusive). Same formats as "From date".

## `languages` (type: `array`):

Only mentions written in these languages, as ISO codes (en, de, es, fr, tr, …). Empty = all languages.

## `countries` (type: `array`):

Only mentions from websites in these countries, as ISO codes (US, GB, DE, TR, …) or English names. Empty = all countries.

## `onlyNewMentions` (type: `boolean`):

Remember what was already delivered and return only mentions that are new since the previous run with the same keyword and filters. The first run returns everything (up to the maximum). Repeats are never charged as mentions, but each search is paid for: a run where nothing is new costs $0.0303 per keyword ("Search without delivered mentions"), and every returned mention that is skipped as already delivered costs $0.0001 ("Fetched mention not delivered").

## `exactPhrase` (type: `boolean`):

Match multi-word keywords as an exact phrase ("apple watch"). Turn off to find pages with the words in any order. You can also put your own quotes around a keyword.

## `matchInFields` (type: `array`):

Require the keyword in specific parts of the page. Empty = anywhere in the indexed text.

## `pageTypes` (type: `array`):

Only these kinds of websites. Empty = all.

## `searchMode` (type: `string`):

"All mentions" returns every matching text block. "One per domain" returns only the best mention from each website — useful to see how many different sites talk about you.

## `sortBy` (type: `string`):

Order of the results. With "Only new mentions" the default is "Recently discovered".

## `dateField` (type: `string`):

"Publication date" uses the date the page was published (pages without a known date are excluded). "Discovery date" uses when the page was found by our crawler — every page has one.

## `includeDomains` (type: `array`):

Only mentions on these websites (e.g. reddit.com, nytimes.com). Subdomains are included.

## `excludeDomains` (type: `array`):

Skip mentions on these websites, e.g. your own site.

## `rankScale` (type: `string`):

Scale for domain rank and page rank, in the output and in the rank filters below.

## `minDomainRank` (type: `integer`):

Only websites with at least this authority (on the rank scale above).

## `maxDomainRank` (type: `integer`):

Only websites with at most this authority.

## `minPageRank` (type: `integer`):

Only pages with at least this authority (on the rank scale above).

## `maxPageRank` (type: `integer`):

Only pages with at most this authority.

## `maxSpamScore` (type: `integer`):

Skip websites with a higher spam score (0–100). Try 30 to remove most low-quality sites.

## `minContentQuality` (type: `integer`):

Only text blocks with at least this content quality score (0–100).

## `sentiment` (type: `string`):

Only mentions with this sentiment (probability at least "Minimum sentiment probability").

## `sentimentMinScore` (type: `number`):

0–1, used with "Sentiment". A mention counts as positive/negative/neutral when that probability is at least this value. Default 0.4.

## `emotion` (type: `string`):

Only mentions expressing this emotion (probability at least "Minimum emotion probability").

## `emotionMinScore` (type: `number`):

0–1, used with "Emotion". A mention counts toward the emotion when that probability is at least this value. Default 0.4.

## `monitorId` (type: `string`):

Optional name for the "Only new mentions" memory (e.g. "acme-weekly"). Runs with the same name share one memory per keyword, even if you change filters. Empty = one memory per keyword + filter combination.

## `resetMonitor` (type: `boolean`):

Forget previously delivered mentions for this run's keywords and treat everything as new.

## `webWideStats` (type: `boolean`):

Adds to each keyword's summary: the total number of matching mentions on the whole web with sentiment and emotion counts, top domains, countries, languages, categories and a trend over time — not just for the mentions you downloaded. $0.08 once per keyword when data is returned; $0.0786 when the lookup was made but returned no data (skipped for free when the mentions search already found no matching page). The free summary of delivered mentions is always included.

## `trendGrouping` (type: `string`):

Time buckets of the web-wide trend. The trend covers the date range above, or the last 12 months (max 400 buckets).

## `topListSize` (type: `integer`):

How many top domains, categories, countries etc. the web-wide statistics list (1–20). Also the length of the top-domain list in the free summary.

## `positiveThreshold` (type: `number`):

0–1. Minimum probability for a mention to count as positive/negative/neutral in the web-wide statistics. Default 0.4.

## `emotionThreshold` (type: `number`):

0–1. Minimum probability for a mention to count toward an emotion in the web-wide statistics. Default 0.4.

## `customFilters` (type: `array`):

Expert filter expression added to the filters above with AND. Format: \[field, operator, value] or \[\[…], "and"/"or", \[…]]. Fields: url, domain, main\_domain, country, language, url\_rank, spam\_score, domain\_rank, score, fetch\_time, page\_types, page\_category, content\_info.title, content\_info.main\_title, content\_info.snippet, content\_info.author, content\_info.content\_type, content\_info.date\_published, content\_info.content\_quality\_score, content\_info.level, content\_info.text\_category, content\_info.connotation\_types.positive|negative|neutral, content\_info.sentiment\_connotations.anger|happiness|love|sadness|share|fun. Operators: =, <>, <, <=, >, >=, in, not\_in, like, not\_like, regex, not\_regex, match, not\_match, has, has\_not. Dates look like "2025-01-31 00:00:00 +00:00". Max 8 conditions in total.

## `customSort` (type: `array`):

Up to 3 sort rules like "domain\_rank,desc" or "content\_info.date\_published,desc". Overrides "Sort by".

## Actor input object example

```json
{
  "keywords": [
    "Logitech"
  ],
  "maxMentions": 100,
  "onlyNewMentions": false,
  "exactPhrase": true,
  "searchMode": "all",
  "dateField": "published",
  "rankScale": "0-100",
  "sentiment": "any",
  "sentimentMinScore": 0.4,
  "emotion": "any",
  "emotionMinScore": 0.4,
  "resetMonitor": false,
  "webWideStats": false,
  "trendGrouping": "month",
  "topListSize": 10,
  "positiveThreshold": 0.4,
  "emotionThreshold": 0.4
}
```

# Actor output Schema

## `mentions` (type: `string`):

No description

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

No description

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

No description

## `runSummary` (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 = {
    "keywords": [
        "Logitech"
    ],
    "maxMentions": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("cheapapi/brand-mentions-monitor").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 = {
    "keywords": ["Logitech"],
    "maxMentions": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("cheapapi/brand-mentions-monitor").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 '{
  "keywords": [
    "Logitech"
  ],
  "maxMentions": 100
}' |
apify call cheapapi/brand-mentions-monitor --silent --output-dataset

```

## MCP server setup

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

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/qInpJnAyx60DeHC2L/builds/zJz9UkTbILgzDoIbo/openapi.json
