AI Visibility / GEO Monitor
Pricing
from $0.01 / 1,000 dataset items
AI Visibility / GEO Monitor
Measure whether Claude mentions your brand in a live web-search-grounded answer, with sentiment and cited sources.
Pricing
from $0.01 / 1,000 dataset items
Rating
0.0
(0)
Developer
Daniel Posztos
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Share
AI Visibility / GEO Monitor — Track Your Brand in Claude's Answers
SEO title: AI Visibility / GEO Monitor — Brand in AI Answers SEO description: Measure whether Claude mentions your brand in a live, web-search-grounded answer — with sentiment, first-mention position, and the sources it cited. Track AI visibility vs competitors.
When people ask an AI assistant "what's the best project management software?", the brands it names — and the order it names them in — are the new search ranking. GEO (Generative Engine Optimization) / AI-visibility monitoring is tracking how your brand shows up in those AI answers versus your competitors. This actor does exactly that: for each query you give it, it asks a Claude model with live web search enabled, then checks every brand you list against that same grounded answer, returning whether each brand was mentioned, its sentiment, its first-mention position relative to the other brands, and the sources the answer drew on.
Built for brand/SEO teams tracking share-of-voice in AI answers, competitive-intelligence tooling, and AI agents that need a structured "did we show up, and how" signal instead of eyeballing chat transcripts.
Why this exists
Classic SEO tracks where you rank on a results page. But a growing share of "best X" and "top Y" research now happens inside AI assistants that return one synthesized answer naming a handful of brands — no page of blue links. If a competitor is named first and you're not named at all, you've lost that impression, and no rank tracker will tell you. This actor gives you a repeatable, structured measurement of that surface: ask the real questions your buyers ask, see which brands the AI actually surfaces, and watch it over time.
Because AI answers vary run to run (especially with live web search), you can re-ask each query up to 5 times (runs_per_query) to sample the variance rather than trusting a single draw.
What it does / methodology
For each (query, run):
- One shared answer. It asks a single Claude model (default
claude-sonnet-5) your query with the liveweb_searchtool enabled — one grounded answer per query×run. This is the expensive step, and it happens once, no matter how many brands you're tracking. - Cheap per-brand check. It then runs one small, structured-output classification call (on cheap
claude-haiku-4-5) per brand against that same answer text — is this brand mentioned, with what sentiment, and where does its first mention fall. Adding brands does not re-run the expensive answer generation. - Deterministic ranking.
positionis computed deterministically by locating each brand's first-mention anchor in the answer text and ranking those offsets (1 = earliest-mentioned), not asserted by the model.
One row is emitted per (engine, query, brand, run).
Methodology note:
brand_mentionedandsentimentare the model's own classification of its own answer, not independently verified ground truth. Treat them as a strong, consistent signal — the same way you'd treat any AI-inferred label — not as a legal determination.
API key model — this is NOT bring-your-own-key
Unlike some actors in this portfolio, you do not supply an Anthropic API key. This actor calls Claude on our shared key, and the per-event price you pay covers that upstream cost (LLM generation tokens + the web-search tool fee + the per-brand classification). That's the whole reason the pricing is structured the way it is below — you're paying for the AI answer, not just a data transformation. There is no key field in the input, and nothing about your Anthropic account is involved.
Input
| Field | Type | Default | Description |
|---|---|---|---|
brands | array of strings | — | Required, non-empty, max 20. Brand names to look for in each answer, e.g. ["Notion", "Asana"]. Every brand is checked against the SAME shared answer per query×run (one cheap classification each), so adding brands does not multiply the expensive generation cost. Blank entries are dropped. |
queries | array of strings | — | Required, non-empty, max 20. Search-style questions to ask, e.g. ["best project management software"]. Each query×run costs one live web-search-grounded generation call. Blank entries are dropped. |
engines | array of strings | ["anthropic"] | Launch supports only "anthropic" (a single Claude model with live web search) — it does NOT query ChatGPT, Gemini, or Perplexity. The field is accepted for forward-compatibility with future engines; any other value fails fast with a speaking error. Omit it to take the default. |
runs_per_query | integer (1–5) | 1 | How many times to independently re-ask each query, to sample answer-to-answer variance. |
model | string | "claude-sonnet-5" | "claude-sonnet-5" (default, the cost/quality balance this actor is priced around), "claude-opus-4-8" (higher quality, pricier), or "claude-haiku-4-5" (cheapest, but does not support the live web-search tool — usable only with "search": false). |
search | boolean | true | Whether to enable live web search for grounding. With false, answers reflect the model's training data only (no live results, cited_sources empty). claude-haiku-4-5 requires search: false. |
Additional guardrail: queries × runs_per_query (the count of expensive upstream generation calls) is capped at 60 per run — independent of how many brands you track — to protect the shared Anthropic credit. Exceed it and the run fails fast telling you to trim queries/runs_per_query or split into multiple runs.
Worked example — input
{"brands": ["Asana", "Monday.com", "ClickUp"],"queries": ["best project management software"],"model": "claude-sonnet-5","search": true,"runs_per_query": 1}
Worked example — output (1 row of 3, representative live shape)
{"engine": "anthropic","query": "best project management software","brand": "Asana","run_index": 0,"brand_mentioned": true,"position": 1,"sentiment": "neutral","cited_sources": ["https://www.pcmag.com/picks/the-best-project-management-software","https://zapier.com/blog/best-project-management-software/"],"raw_answer_snippet": "There's no single \"best\" project management software — the right choice depends on your team size and workflow. Top picks by use case: Asana — a work management platform best for marketing/operations teams... Monday.com... ClickUp..."}
This run produced 3 rows (one per brand) sharing that same raw_answer_snippet and cited_sources; position ranks the brands by where each is first mentioned in the answer (here Asana = 1). A brand the answer never named would come back with brand_mentioned: false, position: null, sentiment: null.
Output schema
One row per (engine, query, brand, run). See .actor/dataset_schema.json for the full JSON Schema.
| Field | Type | Notes |
|---|---|---|
engine | string | Always "anthropic" at launch |
query | string | The query that was asked |
brand | string | The brand this row measures |
run_index | integer | 0-indexed repetition number for this query (see runs_per_query) — lets you measure answer-to-answer variance |
brand_mentioned | boolean | Whether the brand appeared in the answer, per the model's classification (model-inferred, not ground truth) |
position | integer or null | 1-indexed rank of this brand's first mention among all mentioned brands in the SAME answer (1 = earliest). null if not mentioned, or mentioned but the exact text couldn't be located for ranking |
sentiment | string or null | "positive", "neutral", "negative", or null (when not mentioned) — how the answer portrays the brand |
cited_sources | array of strings | URLs the answer's web search drew on (surfaced and/or explicitly cited). Empty if search was false or nothing citable came back |
raw_answer_snippet | string | The model's full answer text (all brands in the same query×run share this SAME text), truncated to 2000 characters with a trailing ... if longer |
Pricing (pay-per-event)
| Event | Price | When it's charged |
|---|---|---|
answer-generation | $0.40 | Once per (query, run) — the shared, live web-search-grounded Claude answer that every brand in the run is checked against |
brand-check | $0.01 | Once per result row — one (engine, query, brand, run) row with its mention/sentiment/position/sources |
Plus Apify's own apify-actor-start synthetic event (first 5 seconds of compute free, platform-managed).
Why the price is split this way: the expensive part of a query is the one live-grounded answer (LLM tokens + web-search fee), and that answer is shared across every brand you check — the actor never re-asks the question per competitor. So you pay for the answer once (answer-generation), then a small flat fee per brand row you get back (brand-check). Tracking 10 competitors against a query costs one generation plus ten cheap row checks, not ten full answers. You are not double-charged per competitor.
Worked cost example: 10 queries × 5 brands × 1 run =
10 × $0.40 (one shared answer per query) + 50 × $0.01 (one row per brand per query) = $4.00 + $0.50 = $4.50 — about $0.09 per brand-row. A single-brand, single-query run is $0.40 + $0.01 = $0.41.
If a run's cost would exceed the Max total charge USD you set, the actor stops gracefully at exactly that point: it never generates an answer it can't afford to deliver at least one paid brand row for (it checks the budget for the answer-generation event plus one brand-check row before spending anything on the AI call), and every brand row it delivers was paid for — nothing paid-for is ever dropped, no crash.
Error messages
- Missing/empty
brands: "Missing 'brands': provide a non-empty list of brand names to check for..." — exit 1, no AI call made. - Missing/empty
queries: "Missing 'queries': provide a non-empty list of search-style questions..." — exit 1, no AI call made. - Unsupported
enginesvalue: states that only"anthropic"is supported at launch and that the field exists for forward-compatibility — exit 1. - Unsupported
model: lists the exact allowed values — exit 1. claude-haiku-4-5withsearch: true: "...does not support the web_search_20260209 tool this actor uses... Either switch 'model'... or set 'search': false..." — exit 1.- Too many upstream calls (
queries × runs_per_query > 60): explains the cap protects the shared Anthropic credit and to trim/split — exit 1, no AI call made. - 0 rows with otherwise valid input: not an error — the run succeeds, but the log has an explicit
WARNING: 0 results produced despite valid input (...)line and the status message says so.
How it works
- Validate structural input (brands/queries non-empty, model/engine/search coherent, upstream-call cap) — fails fast with NO AI call at all if anything is wrong, so a bad input never touches the shared Anthropic credit.
- For each
(query, run): check the budget can cover oneanswer-generation+ onebrand-checkrow before spending anything, then ask Claude the query once with live web search. - Charge the shared
answer-generationevent once, then classify that same answer against every brand (cheap Haiku call each) and rank first mentions. - Charge-and-deliver each brand row atomically — whatever is charged is delivered, and vice versa.
- 0 rows with valid input logs an explicit warning instead of looking like a normal empty run.
Known limitations (documented, not hidden)
- Single engine at launch. Only Anthropic (one Claude model with live web search). No ChatGPT, Gemini, or Perplexity yet — the
enginesfield is a forward-compatibility placeholder, not multiple live engines today. - Live answers vary run to run. Web-grounded AI answers are non-deterministic; the same query can name different brands on different runs. Use
runs_per_query(up to 5) to sample the distribution rather than reading one draw as gospel. - Mention/sentiment are model-inferred.
brand_mentionedandsentimentare the model's classification of its own answer, not independently verified ground truth (see the methodology note above). - Not affiliated with any monitored brand. This actor measures how AI answers portray brands you name; it has no relationship with, and makes no claim on behalf of, any of them. Brand names are your inputs.
web_searchrequires Sonnet 5 or Opus.claude-haiku-4-5can only run ungrounded (search: false), which reflects training data, not live web results.
Data source
Answers are generated by Anthropic's Claude models with Anthropic's server-side web_search tool for live grounding. This actor uses a shared Anthropic key (not bring-your-own-key — see "API key model" above); the per-event price covers that upstream cost.