Methodology & measurement rules
A percentage is only information when its methodology is explicit and comparable. This page lays out our sampling, scoring formula, non-computable rules and known limits — not to look rigorous, but so you can verify it or reject it: if you think a rule is wrong, email us and say so.
Methodology version: vs2 (source constant VISIBILITY_SCORE_CALIBER). Reports across versions are not directly comparable.
1. Where the data comes from (sampling)
- Granularity: brand × AI engine × date. Sampled once per day (cron: UTC 01:00 = 09:00 Beijing time).
- Engine slots: ChatGPT, Perplexity, Gemini, Claude (internal keys
chat_gpt/perplexity/gemini/claude). Unsupported slots error out — we never substitute ordinary search results for an AI model's answer. - Sourcing discipline: engine slots are fed only by compliant automated channels that permit resale.
- Time lock: what an AI engine said today cannot be retrieved tomorrow. If you don't sample today, that day is permanently empty and cannot be backfilled.
- Retention: raw payloads are deleted after 7 days; derived metrics are retained permanently.
2. How the score is computed (bp & rank weights)
- Integer basis points (bp): a 0–100 score is stored internally as 0–10000 bp to avoid floating-point accumulation error; divided by 100 for display.
- Rank weights: mention at
rank ≤ 3scores 1,rank ≤ 5scores 0.8, anything else 0.5; not mentioned scores 0. - Visibility score:
visibility_score_bp = weighted mention sum / valid observations × 10000. - Valid observation: only samples with
answer_source !== 'none'— a prompt where the engine produced no AI overview is not a valid visibility measurement. - Mention rate:
mention_rate_bpis a different methodology, still counted over all prompts. It must not be mixed with the visibility score.
3. Methodology version: vs2
- vs1: denominator = all samples (including
answer_source='none') → prompts with no AI overview counted as "brand invisible" zeros, systematically understating visibility. - vs2 (current): denominator = only samples that did produce an AI overview → no-overview prompts stay out of the denominator.
- Changing methodology = changing the source constant
VISIBILITY_SCORE_CALIBER+ updating tests + bumping the version. A score without a version cannot be compared across periods or recomputed.
4. null and 0 are different things
null= not computable: valid observationsscored_samples = 0, or no mentions anywhere in the comparison set. Displayed asN/A.0= a real finding: there were valid observations, and the brand genuinely was not mentioned once.- We never display 0 in place of null: rendering "not measured" as 0 turns an engine / prompt / market configuration problem into "the brand is completely invisible in AI".
- An empty sampling day is not 0: a day with no sampling is
null, never padded with 0 (0 would be misread as "we dropped").
5. The SoV (share of voice) denominator
- The denominator includes the brand itself:
share_of_voice_bp = own_mentions / total_mentions × 10000, wheretotal_mentionscounts mentions of all brands in the comparison set, including itself. - Excluding self from the denominator produces values like 200% — mathematically self-contradictory, yet routinely written into reports as "we're strong in this set".
- When the denominator is 0 we return
null(not computable) — we never substitute 1 for 0. That would hand out the most optimistic number exactly when restraint is needed most. - The breakdown is returned with the result:
sov.own_mentions/sov.total_mentions/sov.brands/sov.comparable/sov.issues/sov.sample_note.
6. The comparison set must be declared explicitly
peerIdsis required — there is no "default: everything in the database" fallback. A default would make a report's denominator drift with whatever happens to be in the database.- The comparison set includes the brand itself and must be given explicitly by the caller (market, prompt version, authorized brands).
- Competitor citation gaps (
citation_gap) are computed within the same comparison set — passing the whole database would mix "who cites other customers" into your gap list.
7. Incomparability is disclosed, not hidden
- Comparison sets should only be compared within the same market + the same prompt version. Cross-market or cross-version sets get
sov.comparable = false, with each reason listed inissues(e.g. cross-market mixing, cross-version mixing). - When
comparable = false, that number must not be used as a client conclusion — internal reference only. - Multi-engine is by design (
engine_divergencelooks specifically at engine differences), but reports must disclose which engines were covered.
8. Uneven sample sizes must be visible
- When brands have different sample counts we return
sample_noteand never pretend sample sizes are equal. Unevenness is not judged incomparable, but it must be visible — share of voice counts mentions, so the less-sampled side is systematically understated.
9. Trend and engine-divergence rules
- Trend (
trend_delta): bp difference between the recent window and the preceding one. If either window has no valid observations →null; we never fabricate a delta fromnull − number. - Engine divergence (
engine_divergence): the spread is computed only when at least two engines have valid observations; with a single engine,spread_bp = null— with no second engine to differ from, a "spread" is meaningless.
10. Known limits (disclosed as-is)
- History cannot be backfilled: unsampled dates are permanently missing; starting one day late means losing that day forever.
- We measure; we don't promise lift: whether mention rates improve depends on the client's own content, backlinks and PR.
- Generable ≠ deliverable: when valid samples in a window are insufficient, we return covered and empty day counts and the trend field is
N/Arather than an invented number. - Sample data is not delivered: rows with
is_samplecount but are not delivered as conclusions; sample-watermarked reports must not be handed to clients. - Aggregation boundaries: public indices and benchmarks require k-anonymity (k≥5) and the confidentiality boundary (client brands never enter cross-client benchmarks); no single client's data appears outside public aggregates.
- Invite-only: currently invite-only; self-serve signup and online payment are opening progressively.
11. Change discipline
- Changing methodology = changing the source constant + updating tests + bumping the version, and updating this page. No silent methodology changes.
- This page,
/llms-full.txtand/docsmust agree; where they conflict, the newer statement wins, and you can verify by emailing service@saler.ai. - Field names referenced on this page are pinned by tests (byte-compared against
src/metrics/visibility.ts): renaming a field without updating the docs turns tests red.