Cheap Seats

Metric definitions

Every number Cheap Seats reports, with its formula and denominator, and how each maps to Peec AI, Profound, Gauge, Otterly.AI, Ahrefs, SE Ranking, Elmo and Limelit Open.

What exactly does each Cheap Seats number mean? Almost every metric below is a count of graded answers over a count of graded answers, worked out from what’s stored. No model is called to build a report. The same numbers are on the run page, in the run’s JSON (/api/runs/<id> and /runs/<id>/export.json, under Summary), in cheapseats report <run-id> -json (under summary) and in MCP get_run.

Terms used throughout:

  • Graded answer: one answer from one answerer, on one track, that the grader graded. Errors and unfinished answers count nowhere.
  • Choice prompt: a prompt that asks for a choice. Prompts marked intent = "info" ask for an explanation, so their answers count toward named only, never toward recommended, top pick, named first or top 3.
  • Named: graded recommended or mentioned. For your brand this is always the grade, never the grader’s list of names, so your named rate and your share-of-voice row always agree.
  • Products named: the grader’s list of every product an answer names, in order, folded onto your competitors’ canonical names. Each product counts at most once per answer.

Your rates

metricnumeratordenominatorJSON
Namedanswers that name the brandevery graded answervisible
Recommendedanswers graded recommendedanswers to choice promptsrecommended
Top pickanswers whose single top pick is the brandanswers to choice promptstop_pick

Each comes with a 95% Wilson interval, so 0 of 10 and 0 of 1,000 don’t read the same. For h hits of n answers, with p = h/n and z = 1.96:

centre = (p + z²/2n) / (1 + z²/n)

half-width = z · √(p(1 − p)/n + z²/4n²) / (1 + z²/n)

The run page shows these per answerer and track, and for the run as a whole. The run’s rates pool its answers: a prompt with more answers counts for more. Rankings and trends instead take the mean over prompts, each prompt counting once (see Trends).

Unbranded and branded

A branded prompt names your brand or one of its aliases as a whole word (“Is Acme any good?”). Being named in its answers proves little. The track cards lead with the unbranded rates, the same three rates over the answers to every other prompt (unbranded in JSON), and show the rates with branded prompts underneath. The prompt list marks each branded prompt. Rankings and trends use the overall rates.

Share of voice and position

The share-of-voice board lists every product the answers named, not only the competitors you configured.

columnformulaadds up toJSON
Namedanswers naming the product ÷ every graded answermore than 100%named_rate
Share of voiceanswers naming the product ÷ the sum, over every product, of answers naming it100%share_of_voice
Avg placemean of the product’s place among the products an answer names, over the answers naming it at a known placeavg_position
Firstanswers naming it first ÷ answers to choice promptsnamed_first
Top 3answers naming it first, second or third ÷ answers to choice promptstop3
Weightedmean over every graded answer of (N − place + 1) / N, where N is the number of products the answer names, and 0 where it isn’t namedposition_weighted
Top pickanswers whose top pick is the producttop_pick
  • Named rate was called share of voice. In earlier versions the board’s one rate column was labelled share of voice. That number is now named rate; share of voice is the true share, which sums to 100%. The JSON still writes the old field, share, with the named rate in it, so existing readers keep working.
  • Place. Your brand’s place is the position from its grade. Another product’s place is where it comes in the grader’s list of names. An answer that names your brand without listing it has no known place for it, and is left out of avg place, first, top 3 and weighted.
  • First and top 3 carry 95% Wilson intervals in JSON.
  • Weighted is position-weighted visibility as SE Ranking defines it: first of four scores 1, fourth of four 0.25, absent 0.
  • Rank is your place on the board: 1 + the number of products named in more answers than you. Products named in the same number of answers share a rank, and a brand no answer named has none (0 in the API).

Head to head

For each product on the board, against your brand, over every graded answer (head_to_head):

countwhich answers
both namedname both
you ahead / it aheadof those, which led: the answer’s top pick if it’s one of the two, otherwise whichever was named first. An answer whose order isn’t known counts for neither
only youname your brand and not the product
only itname the product and not your brand
neithername neither

Objections

The concerns raised in answers that name your brand (objections), folded for counting: lowercase, every run of punctuation and spaces one space, so “Pricing unclear.” and “pricing, unclear” count once. Each objection counts once per answer, with the first prompt it came up on as an example.

Sentiment and themes

The grader records each answer’s tone about your brand (positive, neutral, mixed or negative; none when absent) and the praise it gives, the strengths it credits you with. See How grading works.

metricformulaJSON
Net sentiment(answers positive − answers negative) ÷ answers naming the brand that have a tone, shown in points from −100 to +100net (−1 to 1)
Tone mixanswers naming the brand, per tonetones
Praised for, Objectionsthe five strengths and five objections the most answers named, each counted once per answerpraise, objections

Grades from before tone was graded have no tone, so net sentiment is over the answers that do, and the page says how many name the brand in all. With no toned answer, net sentiment is n/a.

Themes come from one more grader call after a run is graded. It groups the run’s objections, praise and reasons for picking something else into at most eight named themes, each with a kind (strength, weakness or competitive), the answers that said it, the product it helps (always one of your competitors or a product the answers named), and a quote copied word for word from what it groups. Counts, quotes and beneficiaries are checked against the inputs. With fewer than five distinct strings to group there’s no call, and the run says so.

Sources

Every page an answer cited, or its searches returned, is sorted into a kind of site:

kindwhat
ownyour sites ([[brand.sites]] and brand.domains)
competitora competitor’s domains
ugcforums, Q&A, video and social: Reddit, YouTube, Stack Overflow and Stack Exchange, Hacker News, Quora, Medium, dev.to, X, LinkedIn, GitHub issues and discussions
reviewG2, Capterra, TrustRadius, Product Hunt, Gartner Peer Insights, GetApp, Trustpilot and the like
referenceWikipedia, docs.* hosts, package registries, the rest of GitHub
institutional.gov, .edu, .mil, .int and their country forms (gov.uk, ac.uk)
editorialeverything else

Your sites come first, then competitors’ domains, then [sources] in cheapseats.toml, then the built-in lists; within a list the most specific entry wins. See Configuration.

For each page, host and kind:

metricnumeratordenominatorJSON
Retrievedanswers whose searches returned itanswers that could reach a page: the search track, plus any answer that searched, fetched or citedretrieved_rate
Citedanswers that linked itanswers that could reach a page: the search track, plus any answer that searched, fetched or citedcited_rate
Share of citationsits citations, one per answer that linked itevery citation in the runcitation_share
Cited when retrievedanswers that both retrieved and linked itanswers whose searches returned itcited_when_surfaced

A host counts each answer once, however many of its pages the answer used. Recall answers have no tools, so they’re left out of these rates rather than diluting them.

Buckets, outreach and found but not cited

Each host that isn’t yours gets a bucket from the products named in the answers that cite it:

bucketthe answers citing it name
missingcompetitors, never your brand
sharedboth, with some competitor named at least as often as you
strongyour brand more often than any one competitor
uniqueonly your brand

With competitors configured, only they count as competitors here; with none, every other product does. A host whose citing answers name neither gets no bucket.

  • Cited without your brand (outreach): the missing hosts that aren’t a competitor’s own, ranked by distinct competitors named × answers citing the host. These are the pages to get your brand onto.
  • Found but not cited (found_not_cited): your own pages that searches returned and no answer linked.

Page types

The kind of site says whose page it is; the page type says what the page does, from its URL and the title the search result or citation gave it (page_type on each page, rolled up in page_types with cited, retrieved, pages and share of citations). The first rule that matches wins:

typewhen
forumReddit, Quora, Lobsters, Discord; Hacker News items; Stack Overflow and Stack Exchange questions; GitHub or GitLab issues, pull requests and discussions; forum.*, community.*, discuss.* hosts
repoa repository’s front page: github.com/owner/repo (and GitLab, Codeberg, Bitbucket)
docsdocs.* hosts, a /docs/, /documentation/ or /reference/ path, Read the Docs, pkg.go.dev, docs.rs, MDN, Microsoft Learn
comparisonthe path or title says vs, versus, compare or comparison, or “alternative to”
reviewG2, Capterra, TrustRadius, GetApp, Software Advice, Trustpilot, PeerSpot, Gartner reviews; after the listicle rule, any page whose path or title says review
listiclebest (not “best practices”), top N, N best, alternatives, tools/apps/software/platforms for
articlea /blog/, /news/, /articles/, /posts/ path, a dated path (/2026/05/), blog.* and news.* hosts, Medium, dev.to, Substack, Hashnode
productthe home page, /pricing, /plans, /features, /product, /solutions, /integrations
othereverything else (Wikipedia, a repository’s files)

What the page is beats where it’s filed: /blog/notion-vs-obsidian is a comparison and /blog/best-note-apps a listicle. MCP get_run carries page_types and each top page’s page_type.

Citation stability

How much the hosts a set’s answers cite move from one run to the next, per track, over the same daily runs the trends use (each day’s newest finished run, the last 30 days by default). A run’s citations are a vector of host citation shares s_h: a host’s citations over all the run’s citations, so Σ s_h = 1. For each run against the one before it, with shares a and b:

metricformularange
Similarity (Bray–Curtis × 100)100 · (1 − Σ|a_h − b_h| / Σ(a_h + b_h)), which for shares is 100 · Σ min(a_h, b_h): the share of citations the two runs have in common by host100 when every host kept its share; 0 when no host was cited in both
Overlap (Jaccard × 100)100 · hosts cited in both ÷ hosts cited in either0 to 100
New, gonehosts cited this run and not the one before, and the other way round, largest share first
Stability scorethe mean similarity over the transitions, with the mean overlap beside itshown from 3 transitions
  • One or two transitions can be a fluke, so the score waits for three.
  • The chain stops at a change of method: the run that changed it is the oldest compared.
  • A run that cited nothing (an outage, or the recall track, which has no search) is skipped rather than read as every host leaving.
  • A change of prompts flags its transition prompts_changed: some of its churn is the questions.

A high score says the answers lean on the same sources run after run, so a host entering or leaving means something. A low one says each run’s sources table is a sample. It’s on the set page, at GET /api/sets/{id}/citation-stability and in MCP get_citation_stability.

metricformula
A day’s rate (rankings)the newest finished run that UTC day, per track: the mean over prompts of each prompt’s rate, each prompt counting once
Rolling averagethe mean of the window’s days: 7 by default, or 14 or 28
Band, across promptsrolling mean ± 1.96 · s / √m, where s is the standard deviation of the m prompt-day rates in the window
This set, todaythe day’s mean ± 1.96 · √(Σ_k var_k) / K over its K prompts
Vs day beforeD = mean over the prompts both days asked of (today − yesterday), with a 95% margin; within noise when D ± margin covers 0
A set’s promptseach prompt’s answers pooled over the window, with a Wilson interval
Fix outcomethe same paired D, before and after the fix, over its target prompts
Quick wins gainspeed × mean over the fix’s prompts of (1 − p), where speed is prompts per working day and p is the prompt’s recommended rate (named, for an info prompt) pooled over the last 14 days

var_k is a prompt’s sampling variance, p̃(1 − p̃)/n with p̃ = (h + 0.5)/(n + 1). How big a change Cheap Seats can detect explains these intervals and tests, with a worked example.

How these compare to other tools

Most AI visibility tools use the same few words for different formulas. The table below is from each vendor’s published documentation as of October 2026: Peec AI, Profound, Gauge, Otterly.AI, Ahrefs Brand Radar, SE Ranking, and the two open-source trackers, Elmo (visibility, sentiment, share of voice code) and Limelit Open (methodology). Check their pages for changes since.

conceptCheap SeatsPeec AIProfoundGaugeOtterly.AIAhrefsSE RankingElmoLimelit Open
Visibilitynamed rate: answers naming you ÷ every graded answervisibility: responses mentioning you ÷ all responsesvisibility: runs naming you ÷ runs naming any brandvisibility: answers naming you ÷ all answersbrand coverage: prompts mentioning you ÷ all promptsa mention: you appear at least once in an answervisibility: mean of (N − best position + 1)/N, 0 when absentvisibility: each prompt’s latest answers mentioning you ÷ those answers; a name match is confirmed by a model (Jev)visibility: answers containing your name string ÷ unbranded answers
Share of voiceyour mentions ÷ every product’s mentions, one per answer, all products namedyour mentions ÷ all brand mentionsyour mentions ÷ all brand mentions, one per runyour mentions ÷ yours plus selected competitors'your mentions ÷ all brand mentionsyour share of impressions, weighted by search volume, against tracked brandsyour mentions ÷ yours plus tracked competitors'your mention occurrences ÷ every tracked brand’s occurrences in the same answers
Positionavg place, over answers naming you; every product named countsaverage rank among all brands detected, where you appearaverage position, over runs naming younot scoredin visibility, as aboveaverage rank among the tracked companies an answer namesmean rank of the list items you appear in; prose has none
Wintop pick, and first (named first ÷ choice answers)win rate: chats where you’re position 1 ÷ all chats
Position-weightedweighted, SE Ranking’s formulavisibility
Sentimentnet sentiment: % positive − % negative of answers naming you0–100 scorepositive claims ÷ all claimspositive ÷ (positive + neutral + negative)net sentiment: (positive − negative) ÷ total × 100net sentiment: % positive − % negative0–100: positive 100, neutral and mixed 50, negative 0Limelit Cloud only
Citationscited rate (÷ answers) and citation share (÷ all citations)citation share: your domain’s citations ÷ all citationscitation rate: answers citing the page or domain ÷ all answerscitations by URL, domain and categorycitation share: your site’s citations ÷ all citations
Branded promptsleft out of the headline rates; shown underneathleft out of rankings by defaultleft out of the headline; kept in the grid, tagged
After a config changegrades and rates stay as graded, unless you re-grade stored answers under today’s grader; which pages are whose follows today’s configre-applied to history from today’s configpast answers re-judged for the changed company, 90 days back by defaultevery stored answer re-read from today’s brands and rules
Intervals95% intervals on every rate; changes tested against noisenone publishednone publishednone publishednone published“directional indicators”none publishednone published; 5 samples a run by defaultn on every number; under 20 answers captioned a small sample

The Semrush AI Toolkit sorts sources into the same four buckets Cheap Seats uses: missing, shared, strong and unique.

Migrating between Cheap Seats and these tools

  • Cheap Seats’ visibility is stricter than Profound’s. Profound leaves out the runs that name no brand at all; Cheap Seats’ named rate counts every graded answer. On the same answers, Cheap Seats’ number is lower or equal. To reproduce Profound’s, take Cheap Seats’ export and drop the answers whose named list is empty.
  • Profound averages per model. It works each metric out per AI model, then averages the models with equal weight. Cheap Seats’ run-level rates pool the answers; its per-answerer rates are the per-model numbers, so average those to match.
  • Gauge’s share of voice depends on whom you compare with. It divides by your mentions plus the selected competitors’. Cheap Seats divides by every product the answers named, so adding a competitor to your config doesn’t change your share, except where it folds two spellings into one name.
  • Peec AI’s visibility is Cheap Seats’ named rate. Responses mentioning you over all responses. Peec’s position also counts every brand detected, as Cheap Seats’ avg place does.
  • Otterly.AI counts prompts, not answers. Brand coverage is the share of prompts that mention you. In Cheap Seats, count the prompts in the prompt list whose named rate is above zero.
  • Ahrefs weights by search volume. Brand Radar’s AI share of voice is a share of estimated impressions. Cheap Seats weights every prompt you choose to ask the same, and estimates no traffic.
  • SE Ranking’s visibility is Cheap Seats’ weighted column, the same formula.
  • History. Profound applies today’s topics, tags and brands to past answers, so editing your setup changes past numbers (why past numbers change). In Cheap Seats, a run’s grades, rates and share of voice are fixed when it’s graded; a change in how answers are asked or graded starts a new method on the trend rather than rewriting the old one. To carry the trend on after a grading change, re-grade the stored answers: it’s a step you take, it keeps the replaced grades, and the run page says so. Only which pages count as yours or a competitor’s, and the source kinds, are read from today’s config for every run.
  • Elmo’s share of voice also depends on whom you track. Like Gauge, it divides by your mentions plus your tracked competitors’. Its position is your rank among the tracked companies an answer names, where Cheap Seats’ avg place counts every product named.
  • Elmo leaves out “I don’t know that brand”. A model reads each name match, and an answer saying it has no information about your brand isn’t counted. Cheap Seats counts it as named, graded mentioned, with the objection recorded, so Cheap Seats’ named rate can be higher on the same answers. Elmo’s visibility also counts each prompt’s latest answers, where Cheap Seats’ run rates pool the run’s.
  • Limelit Open counts strings, and occurrences. Its visibility is a deterministic text search, so “I could not find Acme” counts as a mention, as its methodology says. Its share of voice counts every occurrence, not one per answer: an answer that names you once and a rival five times is a 1:5 share, where in Cheap Seats it’s 1:1.
  • History, again. Elmo re-judges past answers when you add a competitor or change a name, 90 days back by default, and leaves older answers as they were, so a long chart can step at that point. Limelit Open re-reads every stored answer whenever the brands or its matching rules change.
  • Your prompts move with you. Cheap Seats’ prompt sets are plain TOML in your own repo. Each prompt is a line of text, so you can paste them into any of these tools. See Compare.