AI Visibility Tracker: Share of Voice in ChatGPT & Claude avatar

AI Visibility Tracker: Share of Voice in ChatGPT & Claude

Pricing

from $6.00 / 1,000 answer analyzeds

Go to Apify Store
AI Visibility Tracker: Share of Voice in ChatGPT & Claude

AI Visibility Tracker: Share of Voice in ChatGPT & Claude

Brand, competitors and prompts in (your own LLM keys); mentions, rank, citations and share of voice per AI engine out. From $0.01 per answer.

Pricing

from $6.00 / 1,000 answer analyzeds

Rating

0.0

(0)

Developer

Creator Fusion

Creator Fusion

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

13 hours ago

Last modified

Security

Limited permissions

Share

This AI visibility tracker asks ChatGPT (OpenAI), Claude (Anthropic), Gemini and Perplexity your prompts with your own API keys, then tells you whether each engine mentions your brand, where it ranks against your competitors, whether it cites your site, and your share of voice.

You get one answer row per prompt x engine x sample, plus one share-of-voice report row per run.

Who it's for

  • Marketers and SEO/AEO teams tracking how AI search talks about their brand (generative engine optimization).
  • Agencies running 100+ prompts x 4 engines x several samples on a weekly Apify Schedule and comparing the CSVs.
  • AI agents (MCP) that need one call such as {"brand":"Notion"} and a report row back.

Sample output

Real rows from the offline demo run (test/smoke-input.json: brand Notion, competitors Coda and Obsidian, demoMode: true). Live rows have the same fields with "demo": false.

Answer row (one per prompt x engine x sample):

{
"rowType": "answer",
"demo": true,
"brand": "Notion",
"prompt": "What are the best alternatives to Notion?",
"engine": "openai",
"sample": 1,
"status": "ok",
"model": "gpt-5-mini",
"mentioned": true,
"mentionCount": 2,
"firstMentionRank": 1,
"shareOfVoice": 0.3333,
"brandCited": false,
"competitorMentions": {
"Coda": 2,
"Obsidian": 2
},
"competitorMentionsTotal": 4,
"citations": [
{
"url": "https://coda.io/?utm_source=openai",
"title": "Coda: the all-in-one doc",
"cited": true,
"position": 1
},
{
"url": "https://obsidian.md/?utm_source=openai",
"title": "Obsidian - Sharpen your thinking",
"cited": true,
"position": 2
},
{
"url": "https://www.notion.com/product",
"title": "Notion Product",
"cited": true,
"position": 3
},
{
"url": "https://zapier.com/blog/notion-alternatives/",
"title": "",
"cited": false,
"position": 1
},
{
"url": "https://www.reddit.com/r/productivity/comments/abc123/notion_alternatives/",
"title": "",
"cited": false,
"position": 2
}
],
"citationsCount": 3,
"citationUrls": "https://coda.io/?utm_source=openai | https://obsidian.md/?utm_source=openai | https://www.notion.com/product | https://zapier.com/blog/notion-alternatives/ | https://www.reddit.com/r/productivity/comments/abc123/notion_alternatives/",
"answerText": "Popular alternatives to Notion include Coda, Obsidian and Airtable. Coda is strong for docs-as-apps, while Obsidian suits local-first notes. Notion remains the most flexible all-in-one workspace for teams.",
"latencyMs": 0,
"checkedAt": "2026-11-06T15:18:00.413Z"
}

Report row (one per run, the last dataset item, also saved to the key-value store as REPORT):

{
"rowType": "report",
"status": "ok",
"demo": true,
"brand": "Notion",
"answersAnalyzed": 8,
"answersFailed": 0,
"overall": {
"mentionRate": 1,
"shareOfVoice": 0.3792,
"avgFirstMentionRank": 1,
"citationRate": null
},
"byEngine": {
"openai": {
"answers": 2,
"mentionRate": 1,
"shareOfVoice": 0.3333,
"avgFirstMentionRank": 1,
"citationRate": null
},
"anthropic": {
"answers": 2,
"mentionRate": 1,
"shareOfVoice": 0.55,
"avgFirstMentionRank": 1,
"citationRate": null
},
"gemini": {
"answers": 2,
"mentionRate": 1,
"shareOfVoice": 0.3667,
"avgFirstMentionRank": 1,
"citationRate": null
},
"perplexity": {
"answers": 2,
"mentionRate": 1,
"shareOfVoice": 0.2667,
"avgFirstMentionRank": 1,
"citationRate": null
}
},
"competitors": [
{
"name": "Coda",
"shareOfVoice": 0.2917,
"mentionRate": 0.875,
"mentions": 10
},
{
"name": "Obsidian",
"shareOfVoice": 0.3292,
"mentionRate": 1,
"mentions": 10
}
],
"enginesSkipped": [],
"enginesSkippedText": "",
"enginesDisabled": [],
"notes": [
"Demo mode: answers are bundled synthetic samples written about Notion, replayed without any network call. Mention metrics for other brands will be low. Nothing is charged.",
"citationRate is null because no brandDomain was provided."
],
"notesText": "Demo mode: answers are bundled synthetic samples written about Notion, replayed without any network call. Mention metrics for other brands will be low. Nothing is charged. | citationRate is null because no brandDomain was provided.",
"checkedAt": "2026-11-06T15:18:00.425Z"
}

A skipped engine (no API key) gives one row with "status": "skipped", "reason": "NO_KEY" and a message. A failed answer gives {"rowType":"answer","status":"error","input":{"prompt":"...","engine":"...","sample":1},"error":{"code":"...","message":"..."}} and is never charged. Error codes: INVALID_KEY, RATE_LIMITED, TIMEOUT, NETWORK, PROVIDER_ERROR, BAD_RESPONSE, EMPTY_ANSWER, BUDGET_EXHAUSTED.

What the metrics mean

  • mentionRate: answers that name the brand / answers analyzed.
  • shareOfVoice: per answer, brand mentions / (brand + competitor mentions); averaged over the samples of a prompt, then over prompts. Answers that name no tracked entity are left out of the average.
  • firstMentionRank / avgFirstMentionRank: 1 means the brand was the first tracked entity (brand or competitor) named in the answer.
  • brandCited / citationRate: a cited source is on your brandDomain (null rate if no brandDomain). citations lists cited sources first (cited: true), then sources the engine only retrieved (cited: false); citationsCount counts cited ones.

Output views

  • overview table: rowType, prompt, engine, sample, mentioned, firstMentionRank, shareOfVoice, citationsCount, status.
  • flat view (CSV / Google Sheets, no nested objects): rowType, status, demo, prompt, engine, model, sample, brand, mentioned, mentionCount, firstMentionRank, shareOfVoice, brandCited, competitorMentionsTotal, citationsCount, citationUrls, answerText (up to 2,000 characters), latencyMs, checkedAt, answersAnalyzed, answersFailed, overall.mentionRate, overall.shareOfVoice, overall.avgFirstMentionRank, overall.citationRate, enginesSkippedText, notesText, reason, error.code, error.message.
  • Download as JSON, CSV, Excel or HTML. The REPORT record is linked from the run's Output tab.

Pricing

Pay per event. Your own provider keys pay the LLM and web-search cost directly (roughly $0.01 to $0.014 per search call, depending on provider and model).

EventFREEBRONZESILVER and aboveWhen it fires
answer-analyzed$0.01$0.008$0.006Per successful live answer, after analysis
sov-report$0.10$0.08$0.06Once per run that has at least one successful live answer

Worked examples (Apify event charges only; provider cost is on your own keys):

  • Default prompts on all 4 engines, 1 sample ({"brand":"Notion"} plus keys): 3 x 4 x 1 = 12 answers. FREE: 12 x $0.01 + $0.10 = $0.22. SILVER: 12 x $0.006 + $0.06 = $0.132.
  • Agency weekly run, 50 prompts x 4 engines x 3 samples: 600 answers. FREE: $6.00 + $0.10 = $6.10. SILVER: $3.60 + $0.06 = $3.66.
  • Demo mode: $0.00.

Demo runs, skipped engines, error rows and BUDGET_EXHAUSTED rows are never charged. The actor checks your maximum total charge before every LLM call and stops cleanly when it is reached; the report row is still written.

Input

Only brand is required; every other field has a default, so an agent can call with one field: {"brand":"Notion"} (add keys or demoMode).

FieldTypeDefaultDescription
brandstring, requirednone (prefill Notion)Brand to track, e.g. Notion
brandAliasesstring[][]Other spellings; whole-word, case-insensitive match
brandDomainstringemptye.g. notion.so; enables brandCited and citationRate
competitorsstring[][]Name or Name|alias1|alias2
promptsstring[] (max 200)3 templates{brand} is replaced by your brand
enginesopenai, anthropic, gemini, perplexityall fourEngines without a key are skipped
samplesPerPromptinteger 1-51Repeat each prompt; answers vary run to run
modelsobject{} (defaults below)Model per engine, e.g. {"openai":"gpt-5-mini"}
openaiApiKey, anthropicApiKey, geminiApiKey, perplexityApiKeysecret stringsnoneYour provider keys (isSecret)
demoModebooleanfalseSample answers, no keys, no charges

Default prompts: What are the best alternatives to {brand}?, Is {brand} worth it in 2026?, What are the top tools like {brand}?. Default models: gpt-5-mini (OpenAI Responses API with web search), claude-sonnet-4-5 (web search tool, 3 uses), gemini-3-flash (Google Search grounding), sonar (Perplexity). A run is limited to 1,000 answers (prompts x engines x samples).

Keys are secret inputs. They are sent only to the provider, are never logged, never written to the dataset or key-value store, and provider error messages are redacted.

Live example:

{
"brand": "Notion",
"brandDomain": "notion.so",
"competitors": ["Coda", "Obsidian"],
"prompts": ["What are the best alternatives to {brand}?", "Which note-taking app should a startup use?"],
"engines": ["openai", "perplexity"],
"samplesPerPrompt": 3,
"openaiApiKey": "sk-proj-...",
"perplexityApiKey": "pplx-..."
}

Try it without keys

Set demoMode to true. The actor replays bundled sample answers (2 prompts x your selected engines, written about Notion) with no keys, no network calls and no charges. Rows carry demo: true.

{
"brand": "Notion",
"competitors": ["Coda", "Obsidian"],
"demoMode": true
}

With no keys and no demo mode, every selected engine gets one skipped row (reason: "NO_KEY") and the report shows answersAnalyzed: 0 with a note. Nothing is charged.

Concurrency is 8 calls overall and 3 per engine; each call has a 90 second timeout and 429/5xx responses are retried. A 401 on a key produces one INVALID_KEY row and disables that engine for the rest of the run.

Use with AI agents (MCP)

Add this server to Claude, Cursor or any MCP client:

https://mcp.apify.com?tools=apricot_blackberry/ai-answer-visibility-tracker

Example call-actor input (free demo; for live answers add openaiApiKey and the other keys inside input):

{
"actor": "apricot_blackberry/ai-answer-visibility-tracker",
"input": {
"brand": "Notion",
"competitors": [
"Coda",
"Obsidian"
],
"demoMode": true
},
"callOptions": {
"maxTotalChargeUsd": 1
}
}

Read the last dataset item (rowType: "report") or the REPORT record for the summary. Always set maxTotalChargeUsd as a run option (never inside input); the default prompts on four engines cost at most $0.22 in events, so maxTotalChargeUsd: 1 is a safe cap.

API

Run it synchronously and get the dataset items back (maxTotalChargeUsd is a query parameter, not input):

curl -X POST "https://api.apify.com/v2/acts/apricot_blackberry~ai-answer-visibility-tracker/run-sync-get-dataset-items?maxTotalChargeUsd=1" \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"brand":"Notion","competitors":["Coda","Obsidian"],"engines":["openai"],"openaiApiKey":"'"$OPENAI_API_KEY"'"}'

JavaScript (apify-client):

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('apricot_blackberry/ai-answer-visibility-tracker').call(
{ brand: 'Notion', competitors: ['Coda', 'Obsidian'], engines: ['openai'], openaiApiKey: process.env.OPENAI_API_KEY },
{ maxTotalChargeUsd: 1 },
);
const report = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('REPORT');
console.log(report.value.overall);

Python (apify-client):

import os
from decimal import Decimal
from apify_client import ApifyClient
client = ApifyClient(token=os.environ["APIFY_TOKEN"])
run = client.actor("apricot_blackberry/ai-answer-visibility-tracker").call(
run_input={"brand": "Notion", "competitors": ["Coda", "Obsidian"], "engines": ["openai"], "openaiApiKey": os.environ["OPENAI_API_KEY"]},
max_total_charge_usd=Decimal("1"),
)
report = client.key_value_store(run["defaultKeyValueStoreId"]).get_record("REPORT")
print(report["value"]["overall"])

For CSV, read https://api.apify.com/v2/datasets/<datasetId>/items?view=flat&format=csv. There is no Standby endpoint: runs take 20 to 90 seconds, so use run-sync or a normal run.

n8n, Make and Zapier

In n8n, use the Apify node (Run actor and get dataset items) with the input above, then a Google Sheets node (Append rows) mapped to the flat columns. Filter on rowType = report to keep one summary row per run. Put the provider keys in n8n credentials, not in the workflow text. Make and Zapier work the same way with their Apify modules.

Schedules: use an Apify Schedule for weekly tracking. Every run is stateless, so compare the datasets or CSVs between runs.

FAQ

Why do I need my own keys? You pay the AI providers at cost, and this actor only charges for the analysis ($0.01 per answer at the FREE tier), so pricing stays low and we never hold your usage.

Why sample more than once? AI answers vary between identical calls. Three samples per prompt give a steadier share of voice and mention rate.

Can I try it without keys? Yes, set demoMode to true. Demo runs are free.

Does it show what the ChatGPT app shows? Not exactly. It uses the official provider APIs with web search, not the consumer apps, so answers can differ from chatgpt.com or Google AI Overviews.

Can I track trends over time? Each run is a snapshot. Schedule it weekly and compare the report rows; the actor does not store history itself.

Limits

  • Official provider APIs only (no scraping of chatgpt.com, AI Overviews or AI Mode); API answers can differ from what the consumer apps show.
  • Matching uses aliases and whole-word, case-insensitive matching on Unicode-normalized text. A brand that is also a common word (for example "Apple") cannot be told apart from the other meaning; add specific aliases.
  • Gemini returns redirect links for sources; citations keep the redirect URL and the source domain from the title is used for brandCited.
  • Default model IDs and the provider web-search tool versions are unverified at release time; override them with models if a provider renames a model.
  • Perplexity citation fields (search_results vs citations) are read with a fallback and may change.
  • No sentiment, no trend storage, no Standby endpoint in this version.
  • Up to 200 prompts, 25 competitors, 25 brand aliases, 5 samples and 1,000 answers per run.

Support

Built by Creator Fusion LLC (Creator Fusion Labs). Questions and bug reports: contact@creatorfusion.net, or open an issue on the Actor's Issues tab.