AI Visibility
AI search engines are becoming a discovery channel: people ask Perplexity, Gemini, Claude, or ChatGPT "what's the best X?" instead of scrolling search results. AI Visibility is the rank tracker for those answers — it queries the engines with the prompts your buyers actually ask and measures three things:
- Presence rate — the share of answers that mention your brand (or cite your domain), tracked over time.
- Cited-domain map — which websites the engines cite as sources, classified as yours, a competitor's, or other (review sites, Reddit, editorial). These are the pages that shape AI answers about your category.
- Per-engine breakdown — how Perplexity, Gemini, Claude, and ChatGPT compare, so you know where you're strong and where you're invisible.
Everything runs against the engines' official APIs — no scraping.
Not the same as Bot & Crawler Detection
AI Visibility measures how AI answers talk about your brand. To see which AI crawlers (GPTBot, ClaudeBot, PerplexityBot, …) visit your website, use Bot & Crawler Detection — the two are unrelated datasets.
Setup
AI Visibility is configured per project under AI visibility → Visibility in the project sidebar.
1. Configure provider API keys (server)
The analysis calls provider APIs with keys configured on the Kitbase server. A search provider with no key is simply disabled — with one exception: GEMINI_API_KEY is required to run analyses at all, because beyond powering the Gemini engine it also runs the answer-analysis pass that extracts brand mentions from every answer (a separate, non-grounded gemini-2.5-flash call). Without it, starting an analysis is rejected and scheduled runs are skipped.
| Env var | Provider | Notes |
|---|---|---|
PERPLEXITY_API_KEY | Perplexity Sonar | Uses the sonar model; citations and actual request cost come back in the response |
GEMINI_API_KEY | Google Gemini | Uses Search grounding; cost is estimated from configured rates |
ANTHROPIC_API_KEY | Claude | Uses the Messages API's web_search tool; cost is computed from real token + search usage in the response |
OPENAI_API_KEY | ChatGPT | Uses the Responses API's web_search tool; cost is computed from real token + search usage in the response |
On Kitbase Cloud, which engines your analyses run against is set by your plan — Starter tracks ChatGPT; Pro adds Gemini and Perplexity; Business covers every available answer engine. Per-organization overrides are supported.
Self-hosted deployments supply their own keys and run against every engine they've configured. Model names, per-minute rate limits, cost rates, and the default monthly spend cap are configurable under the ai-visibility: section of the server config; on Kitbase Cloud the monthly limit is set per plan.
2. Add your brand and competitors
Create one self brand (your product) with:
- Primary domain — the registrable domain (e.g.
example.com). Citations of this domain count as self-citations and classify the domain map. If the project has a website connected (set at project creation or on the project's Website page), the field is prefilled with it — a brand can still use a different domain than the tracked site. - Aliases — alternative names the engines might use (
Kitbase,kitbase.dev, …). An extraction model parses every answer into the full list of companies it names; those extracted names are then matched to your brands by name, alias, or domain — so add the spellings and short forms the engines actually use.
Add competitor brands the same way (name + domain + aliases) to see them in the domain map and mention data. You don't have to know them all up front — once analyses run, Suggested competitors proposes brands the AI itself named that you aren't tracking, and one click adds them here (see Reading the results). Brand changes apply retroactively: adding, renaming, or removing a brand (or its aliases) automatically re-matches your stored analysis history against the new list, so a newly added competitor appears with its full history instead of starting from zero — no re-run and no extra AI cost.
3. Add prompts
Prompts are the questions your buyers ask AI engines — e.g. "best session replay tool for startups", "Kitbase vs PostHog", "how do I track AI crawler traffic". Add them in bulk (one per line).
On Kitbase Cloud the number of active prompts per project is plan-limited (per-organization overrides supported). Deactivated prompts keep their historical data and don't count against the limit. AI visibility is also limited to a set number of projects per organization by plan (Starter 1, Pro 2, Business 5; overrides supported) — a project claims a slot once it has its first active prompt. Self-hosted deployments use the configured server cap instead.
Running an analysis
On Kitbase Cloud with an active paid subscription, analyses run automatically every 24 hours — the dashboard shows a countdown to the next run in place of the run button. An automatic run only starts once the project is fully configured (your own brand plus at least one active prompt) and skips any cycle that would exceed the organization's monthly limit.
On trials and self-hosted deployments, click Run analysis. Before starting you'll see a quick summary — the number of active prompts and the engines that will run for your plan. A run that would exceed your organization's monthly limit is rejected.
Suspended organizations keep read access to their AI visibility data and get a single lifetime analysis to try the feature. Once that run is used, starting another analysis (or requesting prompt suggestions) returns BILLING_018 until the plan is upgraded; the full reset is also unavailable while suspended.
Each analysis is a background job with one unit of work per (prompt × engine). Jobs are:
- Resumable — completed provider calls are recorded and never re-executed, so a server restart or deploy mid-run resumes from where it left off instead of re-paying for finished queries.
- Pausable — pause settles after the current batch; resume continues with the remaining prompts only.
- Cancellable — cancelling keeps the results of already-completed units.
Only one analysis can be active per project. Each completed job becomes one data point in the presence-rate chart, so the daily automatic run (or a regular manual click) builds your trend line. AI answers are non-deterministic — treat single runs as samples and read the trend, not one day's number.
Reading the results
- Presence rate counts a prompt as "present" when the answer mentions any of your aliases or cites your primary domain. Filter by engine or view the combined rate. The presence series and per-engine breakdown also report the mentioned and cited rates separately, so you can see whether engines talk about you, link to you, or both.
- Presence by engine over time plots one line per AI engine (Perplexity, Gemini, Claude, ChatGPT) across your completed analyses, so you can see which engines are picking you up — and which are trailing — as your presence trends. Toggle between the presence and cited rate.
- Competitor trends over time plots one line per tracked brand (you plus your top competitors), so you can watch how your presence or citation rate moves against theirs run over run, not just at a single point in time.
- Share of voice normalizes each brand's presence against the total across all tracked brands per run, with a rank over time — a competitive share, not just your own rate.
- Suggested competitors surfaces brands the AI named on its own that you aren't tracking yet — extracted from each answer during the analysis pass and ranked by how many runs mentioned each. Anything you already track (your brand or a competitor, by name or alias) is filtered out, so the list is purely new discoveries. Click Track on one to start measuring it against you: it moves straight onto the competitors leaderboard from the next run.
- Cited domains aggregates citations across recent runs. Domains classified OTHER with high citation counts are where the engines get their information — prime targets for content or PR. Each domain also carries a source type (UGC, review-site, news, reference, social, docs, editorial, or vendor) from a curated list, so you can see which kinds of sources shape answers in your category.
- Cited pages lists the exact pages (URLs) the engines cited, across every domain, most-cited first — each with its page title, domain, source type, and the engines that cited it. Switch the scope to Mentioning you to only count citations from answers where your brand appeared: those are the pages the engines lean on when they talk about you, and the best places to be present (or to pitch).
- Framing — the extraction pass labels every detected mention with sentiment (positive / neutral / negative) and whether the answer recommends the brand versus merely mentioning it. When the answer presents a ranked list, it also records the brand's position within it.
- Per-prompt breakdown shows presence (and the analysis signals) for every prompt across each engine — a prompt × engine heatmap of where you win and lose.
- Run drill-down shows the full answer text, extracted citations, and detected brand mentions for any individual query — including each mention's sentiment, recommended flag, and rank — useful for verifying matches and understanding phrasing.
How detection works
Each answer is processed once, right after it's collected: an extraction model parses the full answer text into a structured list of every company or product it names, each with its sentiment, recommendation status, list position, and any domain the answer ties to it. That extraction is stored per run. Matching extracted names to your tracked brands then happens in plain code (by name, alias, or primary domain) — which is why brand edits re-match history instantly without any new AI calls, and why untracked names can surface as Suggested competitors. Citations are matched separately by comparing each cited domain to your brands' primary domains.
The analysis signals (sentiment, recommended, rank, source type, mentioned/cited split) are populated for jobs run after the feature shipped; older jobs report them as not analyzed (null) rather than zero, so mixed-window charts don't understate rates. Runs from before the extraction pipeline keep their original mention data and are not re-matched on brand changes.
Tracking a new brand (reset)
To start over with a different brand, open Setup → Danger zone → Reset AI Visibility. The reset permanently deletes the project's entire AI Visibility state: all analysis history (jobs, runs, answers, citations, mentions, and metrics) and all configuration (your brand, competitors, and prompts). Any running analysis is stopped. Afterwards the project returns to the setup wizard so you can configure the new brand from scratch. Requires the aivisibility.manage permission and cannot be undone.
API
All endpoints live under /{orgSlug}/projects/{projectId}/ai-visibility/ and require a bearer token. Viewing requires the aivisibility.view permission; configuration and job control require aivisibility.manage.
| Method & path | Purpose |
|---|---|
DELETE (feature root) | Full reset: deletes all history and configuration to start tracking a new brand |
GET/POST /brands, PUT/DELETE /brands/{brandId} | Brand + competitor CRUD (aliases included in the payload) |
GET/POST /prompts, PUT/DELETE /prompts/{promptId} | Prompt CRUD (POST is bulk; DELETE deactivates, preserving history) |
GET /jobs/estimate | Pre-run summary: active prompt count, the engines that will run, and whether the run is allowed |
GET /schedule | Auto-run schedule state: whether automatic runs are enabled, when the next run is due (nextRunAt, secondsUntilNextRun), and whether a manual run is currently allowed |
POST /jobs | Start an analysis job |
GET /jobs, GET /jobs/{jobId} | Job history and live progress, incl. the engines each job ran (providers) |
GET /jobs/{jobId}/runs | The job's per-(prompt × engine) runs (each carries its promptId) |
POST /jobs/{jobId}/pause · /resume · /cancel | Job control |
GET /visibility?provider=ALL&limit=30 | Presence-rate series per job, incl. runsWithMention / runsWithCitation and derived mentionRate / citationRate |
GET /provider-series?limit=30 | Presence series per job split by engine — one entry per AI provider (self brand), each with presenceRate / citationRate / mentionRate. Powers the per-engine trend chart |
GET /competitor-series?provider=ALL&limit=30 | Presence series per job split by brand — one entry per tracked brand (self + competitors), each with presenceRate / citationRate and normalized shareOfVoice. Powers the competitor trend chart |
GET /domains?provider=ALL&jobs=10&limit=25 | Cited-domain map over recent jobs, incl. sourceType and the citing providers (AI engines) per domain |
GET /domains/{domain}/citations?provider=ALL&jobs=10&page=0&size=20 | Drill-in for one cited domain: totals, citing providers, and the paginated list of exact cited URLs |
GET /citations/pages?provider=ALL&mentioningBrand=false&jobs=10&page=0&size=20 | Flat cited-pages list across all domains, most-cited first, each with domain, title, classification, sourceType, and the citing providers. mentioningBrand=true only counts citations from answers where your brand appeared |
GET /breakdown?jobs=10 | Per-engine comparison, incl. mentioned/cited splits, sentiment counts, recommendedRate, and avgAnswerRank |
GET /competitors?jobs=10&limit=25&provider=ALL | Every tracked brand ranked, incl. shareOfVoice, mentionRate, citationRate, recommendedRate, avgAnswerRank, rank buckets, and sentiment counts |
GET /discovered-competitors?jobs=10&limit=25&provider=ALL | Suggested (untracked) competitors the AI named organically, ranked by mentionCount (distinct runs), with the citing providers and a best-effort primaryDomain. Already-tracked brands are excluded. Track one via POST /brands |
GET /share-of-voice?provider=ALL&jobs=10 | Per-job share-of-voice series: each brand's normalized share and dense rank |
GET /prompts-breakdown?jobs=10 | Per-prompt breakdown with an overall rollup plus one cell per engine |
GET /runs/{runId} | Single-run drill-down (answer, citations, mentions with sentiment / recommended / rank) |
Every aggregate read above also accepts an optional date window, resolved server-side like the other analytics endpoints: a preset (e.g. today, last_7_days — takes precedence) or a from / to pair (YYYY-MM-DD), plus a timezone (e.g. Africa/Cairo, defaults to UTC) used to resolve the boundaries. Jobs that finished inside the window are aggregated instead of the last-jobs window; the dashboard sends presets directly and uses explicit dates for custom ranges and period-over-period comparisons.
New analysis fields on the responses above are nullable — null means the job predates the analysis pass (or it was disabled), never zero.
Full request/response schemas are in the API reference.
Next steps
- Bot & Crawler Detection — see which AI crawlers visit your site (a separate dataset).
- CLI — run
kitbase ai-visibilitycommands from the terminal or CI. - API reference — full request/response schemas.