AI Answer Check is a small Python script that works as an AI visibility tracker. Give it your brand, a few other brands in your category and 15 to 20 buyer questions. It asks each question to an AI answer built from live web and X sources and tells you whether your brand is named, where, and which sites the answer cites.
The problem
Buyers now ask AI tools "what is the best tool for X" and act on the answer. Marketers want to know if their brand appears, how often and next to whom. Asking by hand gives one answer at a time, and answers change from run to run, so a single check says little.
What the app does
- Reads one JSON file with your brand, other brands and your buyer questions.
- Asks each question several times (default 3) with a fixed, neutral system message.
- Records whether your brand is named and its position among the brands you listed.
- Saves the sentence that names your brand and the domains the answer links to.
- Writes a share-of-answer table, a per-question table and the top cited domains.
- Can re-score saved answers with an edited config, with no new calls.
How it works
- Ask. One
POST /desearch/ai/searchcall per question and run, withtools: ["web", "twitter"]andresult_type: "LINKS_WITH_FINAL_SUMMARY". - Read the answer. The response holds the answer text with numbered citations, plus the web results and X posts behind it.
- Match brands as whole words, case-insensitive, with optional aliases.
- Score. Count runs where your brand appears, its position, and how stable the brand set is across runs.
- Write
answer-check.md,runs.csvand a full JSON snapshot with every call and its cost.
The code
def ai_search(self, body, tag="call"):
"""One non-streamed AI Search call; one retry on 429/5xx/network error. Returns (ok, body, call)."""
attempt = 0
while True:
attempt += 1
ts = dt.datetime.now().astimezone().isoformat(timespec="seconds")
t0 = time.perf_counter()
status, headers, data, err = None, {}, None, None
try:
r = self.s.post(self.base + ENDPOINT, json=body, timeout=self.timeout,
headers={"Authorization": self._key, "Content-Type": "application/json"})
status, headers = r.status_code, {k.lower(): v for k, v in r.headers.items()}
try:
data = r.json()
except ValueError:
data = r.text
except Exception as e: # network error
err = f"{type(e).__name__}: {e}"
lat = round(time.perf_counter() - t0, 3)
cost = headers.get("x-desearch-cost-usd")
call = {"ts": ts, "tag": tag, "attempt": attempt, "status": status, "latency_s": lat,
"ok": status == 200 and isinstance(data, dict) and err is None,
"cost_usd": float(cost) if cost not in (None, "") else None,
"usage_count": int(headers["x-desearch-usage-count"]) if headers.get("x-desearch-usage-count") else None,
"service": headers.get("x-desearch-service"), "error": err,
"content_type": headers.get("content-type")}
if not call["ok"] and err is None:
call["error"] = (json.dumps(data)[:300] if not isinstance(data, str) else data[:300])
self.calls.append(call)
self._save(f"{len(self.calls):03d}-{tag}.json", {
"request": {"method": "POST", "url": self.base + ENDPOINT,
"headers": {"Authorization": "<redacted>"}, "body": body},
"call": call, "response_headers": headers, "body": data})
retry = err is not None or status == 429 or (status or 0) >= 500
print(f" {tag} {status} {lat}s cost={cost}", file=sys.stderr)
if call["ok"] or not retry or attempt >= 2:
return call["ok"], data, call
time.sleep(3)
The folder has answercheck.py, an example config in examples/, offline tests in test_answercheck.py and a full report in sample-output.md.
Endpoints
POST /desearch/ai/search
Example output
From a run on 2026-10-10: 18 buyer questions in one software category, 3 runs each, plus 3 questions asked again without the system message (63 calls).
| Output | What it shows |
|---|---|
| Share of answer | how many of the 54 answers named each brand |
| Per question | named in how many of 3 runs, positions, same brand set or not |
| Top cited domains | which sites the answers link to most |
The cited domains list doubles as an outreach list: these are the pages AI answers lean on for your category.
Run it yourself
The public examples folder linked above includes the script and a README. Install its requirements, set DESEARCH_API_KEY from console.desearch.ai, and use the run command in that README.
Useful flags: --runs (default 3), --questions N (only the first N), --ab N (also ask without the system message), --max-spend (default $0.50), --reanalyse RUN_DIR (re-score saved answers, no cost).
What it costs
Every call cost $0.004 (10 billed units at the AI Search rate) on 2026-10-10. A plain 18 questions x 3 runs check is 54 calls and $0.216. See pricing.
Ideas to extend it
- Run it monthly and chart your share of answer over time.
- Pitch the top cited domains so your brand is in the sources AI answers read.
- Add more questions per buyer stage (research, comparison, alternatives).