How we measure AI visibility
The visibility score weights mention rate at 50%, citation share at 30% and position among named brands at 20%. Here is the exact arithmetic, the rules that stop a failed API call masquerading as an absence, and what the method cannot see.
We publish this because a score whose method is secret is a marketing graphic. It is also the page a buyer’s diligence asks for, and we would rather it already existed.
The three inputs
| Metric | Definition | Weight |
|---|---|---|
| Mention rate | Answers naming the brand ÷ answers analysed | 50% |
| Citation share | Cited sources on the brand’s own domain ÷ all cited sources | 30% |
| Position component | A per-answer position score, averaged over every answer analysed | 20% |
Visibility score = round( (mention rate × 0.5 + citation share × 0.3 + position component × 0.2) × 100 ), clamped to 0–100.
How the position component works
Being the first brand named is worth far more than being the fourth, so position is scored on a scale rather than counted:
| Position in the answer | 1st | 2nd | 3rd | 4th | 5th or later | Not named |
|---|---|---|---|---|---|---|
| Score | 1.0 | 0.75 | 0.5 | 0.25 | 0 | 0 |
The important detail is the denominator: those scores are summed and divided by every answer analysed, not only the answers that named you. Otherwise a single lucky first-place mention in a hundred answers would carry the whole score, which is precisely the kind of flattery this measurement exists to avoid.
Average position is reported separately and is averaged only over answers where you were named. When you were never named it is reported as none, not as zero — an undefined value, honestly labelled.
Worked example one: our own zero
From our September 2026 audit: eight questions, one engine, eight answers analysed.
- Mention rate0 ÷ 8 = 0
- Citation share0 ÷ 90 = 0
- Position component0 ÷ 8 = 0
- Score(0 + 0 + 0) × 100 = 0
All three inputs were zero, so there is nothing to round and nothing to argue about. Zero is the floor, and it is where we started.
Worked example two: how a real score is built
Illustrative numbers, not a client’s, so you can follow the arithmetic. Eight questions; the brand is named in three of them, at positions 2, 1 and 4; six of the 90 cited sources are on its own domain.
| Step | Working | Value |
|---|---|---|
| Mention rate | 3 named ÷ 8 answers | 0.375 |
| Citation share | 6 owned ÷ 90 cited | 0.0667 |
| Position scores | 2nd = 0.75, 1st = 1.0, 4th = 0.25 | sum 2.0 |
| Position component | 2.0 ÷ 8 answers | 0.25 |
| Weighted sum | (0.375 × 0.5) + (0.0667 × 0.3) + (0.25 × 0.2) | 0.2575 |
| Visibility score | 0.2575 × 100, rounded | 26 |
Notice what that says. A brand named in nearly four answers in ten, once in first place, still scores 26 — because it is almost never the cited source. Citation share is where most brands leave points on the table, and it is the input you control fastest.
What the bands mean
| Score | Band |
|---|---|
| 0–24 | Rarely surfaced |
| 25–49 | Occasionally surfaced |
| 50–74 | Regularly surfaced |
| 75–100 | Consistently surfaced |
The honesty rules built into the run
These are enforced in the code that produces the number, not in a policy document. They exist because each one, broken, would quietly flatter us.
- An engine error is never “not named”. Failed and empty answers are counted in their own column and never reach the scoring function. Otherwise the score would measure our own timeouts.
- A run with any failure is marked incomplete and stored under a separate filename, so it can never become the baseline for a trend.
- Records are written atomically and never overwrite an existing file. A published number that can be silently edited is not evidence.
- The question list is stored verbatim in every record. Changing a prompt changes what the number means, so the prompt set travels with the result.
- Nothing resembling an API key can enter a stored record. The records are meant to be publishable.
- Each run has a schema version, so old records stay readable when the shape changes.
- Each question gets a 45-second timeout and one retry before it is recorded as a failure.
Non-determinism, measured
Engines do not return the same answer twice, so we ran our own audit twice, about a minute apart, and kept both records.
| Run A | Run B | |
|---|---|---|
| Visibility score | 0 | 0 |
| Answers naming Bungad | 0 of 8 | 0 of 8 |
| Competitors named | Profound 2, Peec AI 2, Otterly 2, AthenaHQ 1, Scrunch AI 1 | Identical |
ahrefs.com citations | 3 | 4 |
blog.hubspot.com citations | 5 | 4 |
peec.ai citations | 4 | 2 |
The conclusion we draw, and publish: headline metrics and brand tallies reproduce; per-domain citation counts do not. Treat a single run’s per-domain figures as estimates. Treat a single run of any kind as an anecdote — the signal is the trend across months on a fixed question set.
How to run this yourself
Nothing here is proprietary. If you would rather not pay anyone, this is the method.
- Fix a question set and write it down. The questions a buyer actually asks before choosing someone like you, in their phrasing. At least two where price is the question and two you expect to lose. Store it verbatim — it is the denominator of every number that follows.
- Name your competitors explicitly, with their domains. Without that list you learn whether you were named, but not who beat you, which is the more actionable half.
- Ask every question to every engine you can reach, through an API rather than a chat window, so the run is reproducible and free of personalisation. Set a timeout and allow a small number of retries.
- Record failures separately and never as absences. Count errors and empty responses in their own column, keep them out of the metrics, and mark a run containing one as incomplete so it cannot become a baseline.
- Parse each answer for three things: whether your brand is named, its position among the brands named, and every cited source domain with a flag for whether you own it.
- Compute the three metrics and the weighted score using the arithmetic above.
- Store the whole run and repeat monthly, written atomically and never overwritten, comparing only against your own previous runs on the same question set.
Our own run is a script in our repository rather than a spreadsheet, and the stored records behind our published score are the raw output of it.
What this method does not measure
Every limitation below is real and we would rather state them than have a buyer find them.
- It is a sample, not a census. It reports what an engine says when asked your questions. It cannot count every time you were cited to somebody.
- Questions are not weighted by real demand. No engine publishes how often a question is actually asked, so every question in the set counts equally, which is a simplification.
- One engine automatically, today. Perplexity is the only engine we hold an API key for. ChatGPT and Claude adapters are built and awaiting keys; Gemini is not built. Google AI Overviews and Copilot have no API and are reviewed by hand for Scale clients. A score from one engine says nothing about the others.
- No personalisation or memory effects. API answers are not the answers a logged-in user with chat history receives. Those may be better or worse for you and we cannot see them.
- Sentiment is recorded but excluded from the score. Being named badly and being named well both count as a mention. We keep sentiment as a separate field rather than smuggling a judgement into a headline number.
- English-language phrasing. The same question in another language can return a different set of brands entirely.
- Scores are not comparable between vendors. Different weights, different questions, different engines. Compare yours only with your own.
Common questions
How is an AI visibility score calculated?
Ours combines three measures: mention rate at 50 percent, citation share at 30 percent, and a position component at 20 percent, multiplied by 100 and rounded. The position component gives an answer 1.0 when you are the first brand named, 0.75 for second, 0.5 for third, 0.25 for fourth and 0 from fifth onwards, then averages that across every answer analysed — not only the ones that named you.
What happens if an engine call fails during a measurement run?
It is recorded as a failure and excluded from the metrics entirely. A failed call is never counted as ‘not mentioned’, because that would make the score a measure of the vendor’s reliability rather than your visibility. A run containing any failure is marked incomplete and stored separately so it can never become the baseline for a trend.
Can two AI visibility scores from different vendors be compared?
No. Weightings differ, question sets differ, and engine coverage differs, so two vendors scoring the same brand are not performing the same measurement. A score is only meaningful against itself, on a fixed question set, over time. Treat any cross-vendor comparison of headline scores as meaningless.
What does this method not measure?
It samples a question set rather than counting every time you were cited to anyone. It does not weight questions by how often they are really asked, because no engine publishes that. It covers one engine automatically today, Perplexity, so it says nothing about ChatGPT or Gemini. It does not account for personalisation or chat memory. And sentiment is recorded but deliberately kept out of the headline score.
See the method applied to your domain
Enter your domain. We ask Perplexity three of your buyers’ questions and score them exactly as described above.
3 questions on Perplexity, free. A domain checked in the last week is served from that stored run rather than asked again, and the daily free allowance resets at midnight UTC.