How to measure share of voice in ChatGPT
Pick a set of queries your buyers actually type, ask ChatGPT all of them, and count how many answers name you versus each competitor. Divide, and that's your share of voice. The arithmetic is trivial — the part that decides whether the number means anything is which queries you chose and whether you can run them again the same way next month. There is no official definition of share of voice for AI answers, which is why AgentGEO deliberately doesn't compute one. It returns the raw answers; the formula is code you write, audit and change when your definition changes. Here's how to build it, and what to be careful about.
The shortest honest answer: choose a fixed set of queries, fetch ChatGPT's answer for each one, count how many mention your brand and how many mention each competitor, then divide by the number of answers you actually got back. Share of voice is that percentage. There's no standard formula, so the one you pick — mention rate, citation share, first-position share — is part of the metric, and belongs next to the number.
The manual way (and why it stops working)
You can do this by hand today, for free. Write down ten questions a buyer might ask about your category. Ask ChatGPT each one. For every answer, note which brands appear. Put it in a spreadsheet: brands down the side, queries across the top, a tick in each cell. Count the ticks, divide by ten, and you have a share-of-voice table that is genuinely informative — probably more informative than the first dashboard you'd have paid for.
Then try to do it again in four weeks.
- It's ten queries because ten is what a human will tolerate. The query set gets truncated to what's bearable, not to what's representative, and the long tail — where challenger brands actually win — never gets measured.
- Answers vary between runs. One pass per query is a noisy sample. A brand that moves from 4/10 to 5/10 may have gained nothing at all, and with a hand-built table you have no way to tell.
- No history to diff. Unless you saved the answer text, you have the tick, not the evidence. When someone asks in the QBR why Northwind jumped, there's nothing to go back and read.
- Nobody re-does it identically. The second pass adds two queries that seemed interesting and drops one that felt redundant — which silently changes the denominator and makes the two numbers incomparable.
- It can't run unattended. A spreadsheet built by hand can't feed a weekly report, a client deliverable or an alert. It happens when someone remembers, which is to say it stops happening.
Do it with one API call
Each fetch is a single POST — the loop below is just this, once per query, with the answer coming back as JSON instead of a page you read:
curl -s https://api.agentgeo.org/v1/fetches \
-H "Authorization: Bearer ag_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"query": "best project management software for agencies", "surfaces": ["chatgpt"]}' \
| jq -r '.answers[0].answerText'Now the whole measurement. Run the query set, count mentions per brand, print the percentages — and note that the denominator is the number of answers actually delivered, not the number of queries you sent:
import requests
API = "https://api.agentgeo.org/v1/fetches"
HEADERS = {"Authorization": "Bearer ag_live_your_key_here"}
# The query set IS the metric. Freeze it, version it, publish it with the number.
QUERIES = [
"best project management software for agencies",
"project management tools for creative teams",
"agency resource planning software",
"best client work management platform",
"software to track billable hours at an agency",
]
BRANDS = ["Acme", "Northwind", "Contoso", "Globex"]
counts = {brand: 0 for brand in BRANDS}
measured = 0
for query in QUERIES:
resp = requests.post(
API,
json={"query": query, "surfaces": ["chatgpt"]},
headers=HEADERS,
timeout=200, # live surfaces are slow - requests wait up to 180s
)
resp.raise_for_status()
for answer in resp.json()["answers"]:
if answer.get("status") == "failed":
print(f"no record returned, excluded: {query}")
continue
measured += 1
text = (answer.get("answerText") or "").lower()
for brand in BRANDS:
if brand.lower() in text:
counts[brand] += 1
print(f"Mention rate across {measured} ChatGPT answers")
for brand, hits in sorted(counts.items(), key=lambda kv: -kv[1]):
share = hits / measured if measured else 0
print(f" {brand:<12} {hits}/{measured} {share:.0%}")That's mention rate — the simplest defensible definition. It isn't the only one, and the reason AgentGEO hands back raw answers rather than a score is that the right definition depends on what you're trying to prove:
| Definition | How you compute it from the records | What it's good for |
|---|---|---|
| Mention rate | Answers whose answerText contains the brand ÷ answers delivered. | Broad presence. The default, and the easiest to explain to a stakeholder. |
| Citation share | Your domain's appearances in sources[] ÷ all cited domains across the set. | Whether your pages earn the link, not just the name-check. Harder to game. |
| First-position share | Answers where you're the first brand named, or hold position: 1 in sources[]. | Whether you're the default recommendation rather than an also-ran in a list of eight. |
| Weighted mention rate | Mention rate with each query weighted by its commercial value to you. | Reporting to people who care about pipeline rather than coverage. |
A hardcoded BRANDS list can only measure the race you already believe you're in. Every month or so, read a handful of raw answers with your own eyes and look for names that keep appearing but aren't in the list — that's where a challenger shows up long before it shows up in your number. Then add it and note the date you did, because the shape of the table changed.
Let your agent do it
For an exploratory pass — before the definition is settled and worth committing to a script — install the MCP server and just ask:
claude mcp add agentgeo -- npx -y agentgeo-mcp --key ag_live_...Then hand it the query set in plain language:
Fetch chatgpt answers for these five queries: best project management software for agencies; project management tools for creative teams; agency resource planning software; best client work management platform; software to track billable hours at an agency. For each answer, list which of Acme, Northwind, Contoso and Globex are named, then give me a mention-rate table sorted high to low — and flag any other brand that showed up in three or more answers.
That last clause is the part a fixed script won't do for you: the agent reads the prose and can surface a competitor you never thought to count. Once the definition stabilizes, move it into the Python above so the number is computed the same way every time. The same server works in Cursor, Cline, Continue and any other MCP client.
Common problems
- A number without its query set and date isn't a measurement. "We have 38% share of voice in ChatGPT" is meaningless on its own — 38% of which twenty questions, asked when? Ship the query list and the date with every figure, and version the list in the repo next to the script.
- Changing the query set breaks the comparison. Add three easy queries you rank well for and your share jumps without anything improving. Freeze the set for the period you're comparing across; when you must change it, start a new series rather than continuing the old one.
- Substring matching over-counts. "Acme" matches inside "Acmegraph" and "Acme Insurance"; a two-letter brand will match almost everything. Require a word boundary, use the longest distinctive form of the name, or cross-check against the domain in
sources[]. - Every mention counts the same — until you make it not. Being listed eighth with a caveat scores identically to being the opening recommendation. If that bothers you, switch to first-position share or weight by rank; just say which one you used.
- Failed records shrink the sample quietly. A record that comes back
failedcosts zero credits but also contributes zero mentions. If you divide by the number of queries you sent rather than the answers you received, you understate everyone. Slow chatbot scrapes that exceed the 180-second budget returnfailedwith aproviderFields.snapshot_id— retry with that id and the same single surface to collect the finished answer.
Summary
For a one-off read on where you stand, ten queries and a spreadsheet will tell you most of the truth in an afternoon. When the number has to repeat — monthly, in a client report, next to a target — fetch the answers as data and put the formula in code you own, so you can audit it, change it deliberately, and say exactly what it measured and when. The formula is yours; the raw answers are the part worth not rebuilding.
Get a free API key → · Try a query without signing up → — Free tier, no credit card required.
Start for freeFrequently asked questions
- What is share of voice in ChatGPT?
- It's the share of AI answers about your category that mention your brand, relative to competitors. Unlike search share of voice there's no standard definition, so it can mean mention rate across a query set, share of cited sources, or share of first-position recommendations. Whichever you use, state it alongside the number — the definition is part of the metric.
- How do you calculate share of voice for AI answers?
- Fix a set of category queries, fetch ChatGPT's answer for each one, count the answers that name each brand, and divide by the number of answers actually delivered. In code that's a loop over the query list, a case-insensitive check of
answerTextper brand, and a percentage. AgentGEO returns the raw answers; the counting formula stays in your own code so you can audit and change it. - How many queries do I need to measure share of voice?
- Enough to cover how buyers actually phrase the problem — typically twenty to fifty for a category, not five. What matters more than the exact count is that the set is fixed between measurements and representative of real demand, because changing it changes the denominator and makes two periods incomparable.
- Does AgentGEO give me a share-of-voice score?
- No, deliberately. It's an answer-access layer: it returns the raw answer records, including
answerTextandsources[], and never ranks, scores sentiment or computes share of voice. The formula lives in your code, which means you can inspect it, defend it to a client, and change the definition without waiting for a vendor to agree. - How often should I re-measure share of voice in ChatGPT?
- Monthly is a reasonable cadence for reporting, weekly if you're actively shipping content and want faster feedback. Because answers vary between runs, treat single-run movements with suspicion — a trend across several measurements of the same frozen query set is far more trustworthy than any one number.
Keep reading