AI Visibility Monitor - ChatGPT, Perplexity, Gemini, Claude
Pricing
from $25.00 / 1,000 visibility checks
AI Visibility Monitor - ChatGPT, Perplexity, Gemini, Claude
Monitor how visible your brand is in AI search answers (ChatGPT via OpenAI web search, Perplexity Sonar, Gemini grounding, Claude). Tracks mentions, list rank, sentiment, competitors and citations - with built-in run-over-run diff and webhook alerts.
AI Visibility Monitor — ChatGPT, Perplexity, Gemini, Claude
Tool card (for AI agents & quick evaluation)
What it does: Asks your customer-intent prompts (e.g. "best RSS monitoring tools") on up to four AI answer engines via their official APIs — OpenAI (ChatGPT-grade answers with web search), Perplexity Sonar, Gemini with Google Search grounding, and Claude with web search — then analyzes each answer for brand mentions, list rank, sentiment, competitor mentions, and cited domains. It diffs every result against the previous run and pushes an alert to your webhook when your visibility changes.
When to use:
- Track whether AI assistants recommend your brand/product — and at what rank — for the questions your buyers actually ask.
- Get a Slack/Discord/n8n alert the moment your brand appears in, drops out of, or moves within an AI answer.
- Watch which competitors AI engines recommend instead of you, and which domains they cite (your GEO/AEO target list).
Inputs:
brandTerms(brand + aliases),prompts(questions to ask),platforms(openai|perplexity|gemini|claude), per-platform API keys (BYOK, stored encrypted), optionalcompetitorTerms,webhookUrl+webhookFormat,language,maxChecksPerRun. Outputs: one dataset record per prompt × platform check plus a finalrun_summary; visibility changes are POSTed to the webhook.Key caveats: the first run only establishes a baseline (no alerts) — run it on a schedule. With no API keys configured it runs in a free demo mode with mock answers. "ChatGPT" data comes from OpenAI's official search-grounded Responses API, not from scraping the ChatGPT consumer UI.
Your customers stopped asking Google and started asking ChatGPT, Perplexity, Gemini, and Claude. This Actor tells you — on a schedule, with alerts — whether those AI answers mention you, where you rank, how you're framed, and who gets recommended instead.
Unlike one-shot "AI brand audit" tools, this is a monitor: it remembers the previous run, computes the diff, and pings your webhook only when something actually changed.
Why monitor AI visibility? (GEO / AEO in one paragraph)
An estimated majority of product research now touches an AI assistant before a search engine results page. When someone asks "what's the best invoicing tool for freelancers", the AI's answer is the new page one — and there are only ~5 slots. Generative Engine Optimization (GEO) / Answer Engine Optimization (AEO) starts with measurement: you can't improve your share of AI answers if you don't know your current rank, the sentiment around your mentions, or which sources the engines cite (those citations are exactly the sites where you need coverage). AI answers are also non-deterministic and drift over time — a one-off audit is stale within weeks, which is why continuous monitoring with change alerts beats a single report.
What it does
- Asks your prompts on each selected platform via official APIs only — no browser automation, no scraping, nothing that breaks when a UI changes:
- OpenAI — Responses API with the
web_searchtool (search-grounded, with citations) - Perplexity — Sonar API (citations built in)
- Google Gemini —
generateContentwith Google Search grounding - Anthropic Claude — Messages API with the web search tool
- OpenAI — Responses API with the
- Analyzes every answer: is any of your
brandTermsmentioned (case-insensitive, whole-word)? At which character position and — if the answer is a list — at which rank? Is the surrounding context positive / neutral / negative (fast rule-based scoring, no extra LLM cost)? WhichcompetitorTermsappear? Which domains are cited? - Diffs against the previous run (state persists in the Actor's key-value store): brand appeared, brand dropped, rank changed, competitor set changed.
- Alerts your webhook on every change — generic JSON for n8n / Make / Zapier, or ready-to-post Slack / Discord messages, with 2 automatic retries.
- Stays cheap and quiet when nothing changed — every check is still recorded, but you only get pinged on movement.
Failures are isolated per check, and a platform that fails 3 times in a row is skipped for the rest of the run (one bad API key never burns your whole run).
Input
{"brandTerms": ["Apify"],"competitorTerms": ["Zyte", "Bright Data"],"prompts": ["best web scraping and web automation platforms","how do I monitor a competitor's prices automatically"],"platforms": ["openai", "perplexity", "gemini", "claude"],"openaiApiKey": "sk-...","perplexityApiKey": "pplx-...","geminiApiKey": "AIza...","anthropicApiKey": "sk-ant-...","webhookUrl": "https://hooks.slack.com/services/T000/B000/XXXX","webhookFormat": "slack"}
- BYOK (bring your own keys): you only need keys for the platforms you select. All key fields are encrypted secrets. Model names are configurable per platform (
openaiModel,perplexityModel,geminiModel,anthropicModel) and default to the cheapest suitable tier. - No keys at all? The Actor runs in demo mode with clearly labeled mock answers (
demoMode: true) so you can see the full output shape for free. - Cost guardrail:
maxChecksPerRuncaps prompt × platform combinations per run (default 100, hard limit 500).
Output
One record per prompt × platform check:
{"recordType": "check","prompt": "best web scraping and web automation platforms","platform": "perplexity","model": "sonar","checkedAt": "2026-07-25T12:00:00+00:00","brandMentioned": true,"brandFirstPosition": 214,"brandRank": 2,"sentiment": "positive","competitorsMentioned": ["Bright Data"],"citations": ["https://example.com/top-scrapers"],"citationDomains": ["example.com"],"answerExcerpt": "There are several great options...","changes": [{ "changeType": "rank_changed", "previousRank": 1, "newRank": 2 }],"isBaseline": false,"demoMode": false,"webhookDelivered": true}
Change types: brand_appeared, brand_dropped, rank_changed, competitors_changed. Every run ends with a run_summary record (checksRun, changesDetected, checkErrors, ...), so the dataset is never empty and your schedules stay green.
Pricing (pay per event)
- Actor start — small flat fee per run.
- Visibility check — $0.025 per prompt × platform check (BYOK — you pay the AI platforms directly at their API rates, typically $0.005–$0.03/check). Demo-mode mock checks are free.
For comparison, the leading AI brand-monitoring Actor charges $0.08 per check with managed keys — with your own keys this Actor lands at roughly a third of that, and it's the one that also does the diffing and alerting for you. A typical setup (20 prompts × 3 platforms, weekly) costs about $6.50/month here vs. a $29/month floor for standalone AI-visibility SaaS.
Use via MCP / AI Agents
Any AI agent connected to Apify's hosted MCP server at mcp.apify.com (Claude, ChatGPT, Cursor, VS Code, or any MCP-compatible client) can discover and run this Actor:
- Discover it with the
search-actorstool (e.g. query "ai visibility brand monitor chatgpt perplexity"). - Inspect the input schema with
fetch-actor-details. - Run it with
call-actorusing the Actor IDglueworks/ai-visibility-monitor.
To pin this Actor as a dedicated tool in your MCP client, connect to:
https://mcp.apify.com/?tools=glueworks/ai-visibility-monitor
Minimal input for an agent call (demo mode, no keys needed):
{"brandTerms": ["Apify"],"prompts": ["best web scraping platforms"],"platforms": ["openai"]}
Notes for agents:
- Without
webhookUrl, changes are only written to the dataset — read them from there after the run finishes (changesarray per record). - The first run reports zero changes (baseline). Schedule the Actor (e.g. daily/weekly) against the same task so consecutive runs can diff.
- Provide an API key for every platform you select; platforms without a key are skipped with an error in
run_summary.checkErrors(unless no keys are set at all, which activates demo mode). brandRankis only set when the answer is a list (numbered/bulleted) and the brand appears in an item; a brand can bebrandMentioned: truewithbrandRank: nullin prose answers.
Setting it up as a monitor
- Fill in brand terms, prompts, platforms, keys, and your webhook.
- Create a Schedule in Apify Console (daily or weekly is plenty — AI answers drift over days, not minutes).
- State lives in a named, account-scoped key-value store (
glueworks-ai-visibility-state), which persists across runs, so consecutive scheduled runs only alert on changes. (Named stores belong to the account running the Actor — different Apify users never share one.) Within that store, state is filed under a per-config key (VISIBILITY-STATE-<hash of your brand/prompt/platform set>), so separate monitors run under one account keep their baselines isolated.
Prompt injection & untrusted data
The AI answers this Actor reads are untrusted — an attacker can plant
content on the web that a search-grounded model later quotes, and that answer
can contain injection payloads like "ignore previous instructions" or fake
<system> tags.
Why this Actor is structurally safe against it: those answers only ever
flow through rule-based parsers — regex mention/rank detection and a
marker-word sentiment scorer — and are never fed back into any LLM. There
is no second "reasoning" prompt for an injection to hijack, so a malicious
answer is treated as inert data, not instructions. (The pure analyze_answer
and parse_response functions are covered by tests/test_injection.py, which
pins this property so a future change can't silently reintroduce an
answer → LLM feedback loop.)
Untrusted answer text is also bounded before it leaves the Actor: only an
answerExcerpt (capped at 800 chars) is stored, and the webhook payload
never contains raw answer text — it carries only the operator's prompt, the
platform, and the structured change types.
Residual risk / what to watch for (agent-oriented): the analysis is
deterministic, so brand-mention, rank, sentiment, and competitor fields are
trustworthy signals — but citations/citationDomains and answerExcerpt are
verbatim untrusted content. If you pipe those into a downstream agent
(e.g. "summarize the excerpts" or "visit the cited domains"), apply your own
injection defenses there and don't auto-follow citation URLs with privileged
tools. The rule-based sentiment is intentionally simple and can be gamed by
keyword-stuffed content; treat it as a heuristic, not ground truth.
FAQ
Is this the real ChatGPT / Gemini answer a user would see? It's the closest thing available through official channels. "ChatGPT" results come from OpenAI's Responses API with the web_search tool — the same search-grounded model family, but not a scrape of the consumer chat UI (there is no official API for that, and scraping it breaks constantly and violates ToS). Perplexity's Sonar API is the closest to its consumer product. We state this openly because tools that promise "real UI answers" via browser automation are the ones that silently die.
Why did my first run send no alerts?
The first run per (prompt, platform) pair establishes a baseline. Alerts start from the second run. To re-baseline, delete the VISIBILITY-STATE-* record(s) from the named glueworks-ai-visibility-state key-value store.
How is sentiment determined? A fast rule-based scorer over the text window around your brand mention (positive/negative marker words). It's deliberately simple — transparent, free, and stable across runs — rather than burning extra LLM tokens per check.
What about Google AI Overviews? Not included: Google offers no official API for AI Overviews, and scraping SERPs violates our no-scraping rule. A BYOK integration via a third-party SERP API is under consideration — ask in the Issues tab if you need it.
Do you support managed keys (no BYOK)?
Not yet — this version is BYOK-only, which is also why the per-check price is low. A managed-key mode (no API keys to bring, higher per-check price) is planned; the managedMode input is reserved for it.
What if one platform's API fails mid-run?
Each check is isolated; a failing platform is retried on its next check and cut off after 3 consecutive failures. Everything that succeeded is still recorded, and failures appear in run_summary.checkErrors.
Which models are used? Can I change them?
Defaults are the cheapest search-capable tier of each platform (e.g. sonar, claude-haiku-4-5). Every model name is a plain input string — paste any newer/bigger model id without waiting for an Actor update.