AI Visibility Setup: Onboard a Client Brand Step by Step
AI visibility setup in six steps: intake, site read, brand brief, competitors, prompt review and first run, plus the setup mistakes our own data exposed.
Kazi Khalid Hasan Tamim · BugViso Team
14 min read
AI visibility setup takes six steps: intake, a read of the client's site, a brand brief you correct, at least three competitors, a reviewed prompt set, and the first run. The steps are quick. What isn't quick is undoing a bad setup, because the brief, the competitor list and the prompt set become the measuring instrument for months. Every change after the first run breaks the trend.
Our own brand's setup shows where that bites: a pricing summary that caused a false accuracy alarm, a topic too thin to measure and a single "alternatives" prompt. By the end of this post you'll have the six steps, the check for each, the fixes we'd make to our own setup in hindsight, and a pre-flight script that inspects a client's site before you start.
Data used: BugViso's own brand setup in its AI Visibility Tracker: the site read re-run with the tracker's production crawl code against bugviso.com on 2026-10-29, the 50-prompt set frozen before the runs, and 400 answers from ChatGPT, Gemini, Perplexity and Claude on 2026-10-20 that exposed the setup issues described here.
The Six Steps at a Glance
Each step has one thing to check, and skipping that check costs accuracy later.
| Step | You provide | Check before moving on | What goes wrong if you skip it |
|---|---|---|---|
| 1. Intake | Website, brand name, market, language | The market is where buyers are, not where the company is registered | Answers are localised to the wrong country |
| 2. Site read | Nothing; the tracker reads the site | Pricing and product pages were found and readable | The brief is built without prices |
| 3. Brand brief | Corrections | Every plan, price and limit is listed exactly | Accuracy checks raise false alarms or miss errors |
| 4. Competitors | 3+ rivals with domains and aliases | They're the brands you lose deals to | The benchmark compares you with the wrong market |
| 5. Prompts | Review and edits | Mix, topics and wording match how buyers ask | Months of data on questions nobody asks |
| 6. First run | A schedule and report recipients | The run completed on every engine | A broken baseline |
Step 1: Intake, Four Fields
Intake needs the website, the brand name, the market and the language buyers ask in. The market sets the location the engines search from where their APIs support it; the language sets the language of every prompt.
Pick the market by where the buyers are. A company registered in one country that sells mainly to another should be tracked in the second. If buyers are spread across several markets, start with the one that brings the most revenue, because the same question can return different brands in different countries.
Step 2: The Site Read
The tracker reads the client's key pages to draft the brief; if a fact isn't on a crawlable page, the brief won't have it. We re-ran BugViso's production crawl code against our own site to show what it collects:
| Measure | bugviso.com, 2026-10-29 |
|---|---|
| robots.txt | Read first; nothing blocked |
| Sitemap | Found |
| Requests made | 16 |
| Pages kept | 15: home, pricing, about, contact, sales contact, scan, the agency page, the GEO page and 7 feature pages |
| Time | 6.4 seconds |
| Raw page text | 81,203 characters |
| Digest sent on to drafting | 13,672 characters (83% smaller) |
Two rules decide what's kept. Pages are scored by what buyers check (pricing highest, then product and feature pages, then about, comparisons and contact), with a bonus for pages linked from the main navigation. Blog posts, legal pages, logins and carts are never read. Then repeated navigation and footer text is dropped from every page, so the digest is mostly facts.
So before you start, check the client's pricing and product pages are public, linked from the navigation and readable without JavaScript. The pre-flight script below does that in about a second. If prices only appear after a quote form, write them into the brief by hand in step 3.
Step 3: Correct the Brand Brief
The brief is the most important five minutes of setup, because it becomes the fact sheet every answer is checked against. BugViso pre-fills it from the site read: category, a one-sentence description, what the brand offers, other names, who it's for, what sets it apart, and facts AI should get right.
Correct three things above all:
- List every plan with its exact price and limit. Not a range. Our first brief summarised pricing as "$19 (20 scans) to $149 (300 scans)". When engines correctly described our $49 tier, the checker couldn't confirm it and flagged it. Our pricing page shows 27 distinct dollar amounts (monthly and annual prices, per-scan rates, credit packs), so a summary was always going to lose something.
- Add other names. Product names, abbreviations and common misspellings, so mentions aren't missed.
- Write the facts buyers check. Refund window, free tier, limits, guarantees, locations served. These feed the accuracy check; anything missing comes back "unverified", as we found when we analysed 369 unverified AI claims.
💡 Rule of thumb: read the brief as if you were a buyer checking an AI answer against it. If the brief can't settle "how much is the middle plan?" or "can I get a refund?", it isn't finished.
Step 4: Choose the Competitors
Track at least three competitors, chosen from the deals the client loses, not from the biggest names in the category. The tracker suggests competitors from the site read; the client's sales team knows better.
For each competitor, enter the domain (it's how the tracker recognises their own pages among citations) and any other names. Then test each name for ambiguity. A rival called "Atlas" or "Signal" can be matched in answers that never mention the company, which inflates its share of voice. Our post on brand name ambiguity in AI answers shows how to test a name in a few minutes.
We tracked five competitors. Five was a good number: enough to see the category's shape, few enough that every name was a real deal-loss rival.
Step 5: Review the Prompt Set
The prompt set is the instrument; review it for mix, topics and wording before anything runs. BugViso drafts 50 prompts from the brief by default and checks them in code. Here's the set we froze for our own brand:
| Part of the set | Prompts | Rule |
|---|---|---|
| Discovery (no brand named) | 35 | About 70% of the set |
| — learn / consider / purchase | 10 / 15 / 10 | About 30 / 40 / 30 |
| Branded | 10 | About 20% |
| Comparison (brand vs a named rival) | 5 | About 10% |
| Topics | 7 | 4–8 topics, at least 3 prompts each |
Check four things:
- Wording a buyer would type. Plain questions, 6 to 25 words, no insider jargon. Our guide to buyer prompts for AI search has the tests.
- Topic size. Our accessibility topic had 3 prompts, the minimum. After two runs it held 24 answers, enough only to say "zero mentions, interval up to 13.8%". Give important topics 5 or more prompts.
- Alternatives prompts. We had one "alternatives to a rival" prompt. Its 8 answers couldn't separate a displacement rate of 1 in 8 from 3 in 8. Write one per main rival buyers switch from.
- Branded share. Keep branded and comparison prompts near 30% combined, so the unbranded visibility score stays meaningful.
Step 6: Freeze, Run and Schedule
Freeze the set, run once, check the run's health, then set the schedule. The first run is the baseline. Check that every engine returned answers and that no engine failed on many calls; an outage on day one makes every later comparison look like growth.
Then set the cadence by what you report. Daily runs pooled into weekly reports are the practical default for active work; weekly runs suit monthly reporting. Add report recipients if the account team wants the daily email.
After the freeze, resist editing prompts. Every edit creates a new version, and trends restart from it. Collect the edits you want and apply them together at a reporting boundary, as described in prompt set versioning.
Run a Pre-Flight Check on the Client's Site
This script checks the things setup depends on, without any AI calls: text in the raw homepage HTML, whether robots.txt blocks the main AI crawlers, how many URLs the sitemap lists, which key pages exist (pricing, product, about, contact, locations, case studies), and the distinct prices on the pricing page. Standard library only.
#!/usr/bin/env python3
"""Pre-flight for AI visibility tracking setup: can AI search crawlers read the client's site,
which pages a brand brief will be built from, and which facts to confirm before prompts are drafted.
Usage: python3 geo_intake_check.py example.com
Standard library only. robotparser is a close approximation of RFC 9309, not an exact match.
"""
import re, sys, urllib.request, urllib.robotparser
from html import unescape
from urllib.parse import urljoin, urlparse
UA = "Mozilla/5.0 (compatible; geo-intake-check/1.0)"
AI_BOTS = ["OAI-SearchBot", "GPTBot", "PerplexityBot", "ClaudeBot", "Claude-SearchBot", "Google-Extended", "Bingbot"]
KEY_PAGES = {"pricing": "pricing|plans|prices", "product/features": "features?|products?|services|solutions",
"about": "about|company|team", "contact": "contact", "locations": "locations?|stores?|branches",
"case studies": "case-studies|customers|work|portfolio"}
def get(url, limit=1_500_000):
try:
req = urllib.request.Request(url, headers={"User-Agent": UA})
with urllib.request.urlopen(req, timeout=15) as r:
return r.status, r.read(limit).decode("utf-8", "replace")
except Exception as e:
return getattr(e, "code", None), ""
def visible_text(html):
html = re.sub(r"(?is)<(script|style|noscript|svg)[^>]*>.*?</\1>", " ", html)
return re.sub(r"\s+", " ", unescape(re.sub(r"(?s)<[^>]+>", " ", html))).strip()
def main(domain):
origin = "https://" + domain.removeprefix("https://").removeprefix("http://").strip("/")
status, home = get(origin + "/")
print(f"# AI visibility intake: {origin}\n\nhomepage: HTTP {status}, {len(visible_text(home)):,} chars of text in raw HTML"
+ (" ✗ little text without JavaScript" if len(visible_text(home)) < 500 else ""))
rp = urllib.robotparser.RobotFileParser(origin + "/robots.txt")
rs, robots = get(origin + "/robots.txt")
rp.parse(robots.splitlines() if rs and rs < 400 else [])
blocked = [b for b in AI_BOTS if not rp.can_fetch(b, origin + "/")]
print("AI crawlers blocked from the homepage: " + (", ".join(blocked) + " ✗" if blocked else "none ✓"))
sitemaps = re.findall(r"(?im)^sitemap:\s*(\S+)", robots) or [origin + "/sitemap.xml"]
urls = []
for sm in sitemaps[:3]:
s, xml = get(sm)
locs = re.findall(r"<loc>\s*([^<\s]+)\s*</loc>", xml)
for child in [l for l in locs if l.endswith(".xml")][:5]: # one level of sitemap index
locs += re.findall(r"<loc>\s*([^<\s]+)\s*</loc>", get(child)[1])
urls += [l for l in locs if not l.endswith(".xml")]
links = [urljoin(origin + "/", h) for h in re.findall(r'href=["\']([^"\'#?]+)', home)]
pages = {u.rstrip("/") for u in urls + links if urlparse(u).netloc.removeprefix("www.") == urlparse(origin).netloc.removeprefix("www.")}
print(f"sitemap URLs: {len(urls):,}; same-site pages known: {len(pages):,}\n\n## Pages the brief will lean on")
found = {}
for kind, pat in KEY_PAGES.items():
hits = sorted((p for p in pages if re.match(rf"^/({pat})(/|$)", urlparse(p).path)), key=lambda p: (p.count("/"), len(p)))
found[kind] = hits
print(f"- {kind}: {hits[0] if hits else 'not found'}" + (f" (+{len(hits) - 1})" if len(hits) > 1 else ""))
print("\n## Facts to confirm in the brief")
if found["pricing"]:
text = visible_text(get(found["pricing"][0])[1])
vals = sorted({float(m.replace(",", "")) for m in re.findall(r"[$€£]\s?(\d[\d,]*(?:\.\d+)?)", text)})
shown = ", ".join(f"{v:g}" for v in vals) or "none in raw HTML ✗"
print(f"- {len(vals)} distinct amounts on the pricing page: {shown} -> list every plan with its price and limit")
else:
print("- no pricing page: write the price facts into the brief by hand, or engines will guess")
print("- 3+ competitors the client actually loses deals to, with their domains and any common-word names")
print("- the market (country) and language buyers ask in")
if __name__ == "__main__":
main(sys.argv[1] if len(sys.argv) > 1 else sys.exit(__doc__))On our own site:
homepage: HTTP 200, 23,192 chars of text in raw HTML
AI crawlers blocked from the homepage: none ✓
sitemap URLs: 285; same-site pages known: 298
## Pages the brief will lean on
- pricing: https://bugviso.com/pricing
- product/features: https://bugviso.com/features (+8)
- about: https://bugviso.com/about
- contact: https://bugviso.com/contact
- locations: not found
- case studies: not foundPython's urllib.robotparser is close to RFC 9309 but not identical, so treat a "blocked" line as a prompt to check the rules by hand. Crawler names change; OpenAI documents its current ones on its crawler overview.
How BugViso Handles AI Visibility Setup
Setting up a brand in BugViso's AI Visibility Tracker asks for the website, name, market and language. The tracker reads robots.txt, finds the sitemap, fetches the homepage and its key pages politely (15 pages in total), condenses them into a digest, and stops at a pre-filled brand brief for you to correct: category, description, offerings, other names, audience, differentiators, facts AI should get right, and suggested competitors. You confirm at least three competitors before any prompt is drafted.
The prompts are then drafted from the confirmed brief and checked in code for mix, topic sizes, length, duplicates and leading wording. The first set waits on a "Review your prompts" step, where you add, edit, move or delete by topic or as a list, and starting tracking freezes the set and runs the first measurement. Runs are manual by default and can be scheduled daily, weekly or monthly. The setup flow is described on the AI visibility tracker page.
Setup Mistakes We'd Avoid Next Time
A pricing range in the brief. It caused a false accuracy alarm on a correct claim. List every plan.
Minimum-size topics for things that matter. Three prompts per topic is the floor, not the target, for topics you'll report on.
One alternatives prompt. Too few answers to measure displacement. One per main rival.
Choosing competitors by fame. The benchmark is only useful against the rivals buyers actually compare you with.
Editing prompts in week one. Every edit restarts the trend. Batch changes for a reporting boundary.
Frequently Asked Questions
How do I set up AI visibility tracking for a client?
Enter the client's site, name, market and language; let the tracker read the site; correct the brand brief so every plan, price and key fact is exact; confirm at least three competitors the client loses deals to; review the drafted buyer prompts; then freeze the set and run the first measurement.
How many prompts and competitors should I track?
Fifty prompts and three to five competitors is a solid default: about 35 unbranded, 10 branded and 5 comparison prompts across 4 to 8 topics. Give topics you'll report on at least five prompts each.
What information does AI visibility tracking need from the client?
The website, the brand's other names, the market and language buyers use, the competitors they lose deals to, and the exact facts buyers check: plans, prices, limits, refund terms and locations.
Why does the brand brief matter for AI visibility?
It's the fact sheet every AI answer is checked against. A vague brief makes the accuracy check flag true claims or miss wrong ones. Our first brief's price range caused a false alarm on a correct $49-plan claim.
Can I change prompts after AI visibility tracking starts?
Yes, but each change creates a new prompt version, and comparisons restart from it. Collect edits and apply them together at a reporting boundary.
Spend the Setup Time on the Brief
Of the six setup steps, the brief and the competitor list are the ones that quietly decide whether months of data mean anything, so correct them with the client before the first run. BugViso's AI visibility tracking stops at the brief on first setup for exactly that reason.
Written by
Kazi Khalid Hasan Tamim · BugViso Team
Kazi writes BugViso’s guides on website audits, Core Web Vitals, technical SEO, accessibility and AI search. The data in them comes from audits BugViso runs in a real Chromium browser, including our 219-site study of website health.
Summarise with AI
Open this guide in your assistant.
Follow BugViso
New guides and audit data as we publish them.
See where your site stands
Run a free BugViso audit for SEO, speed, accessibility and AI search readiness — with fixes you can ship today.