Brand measurement
MeasurementEngine, added in 0.7.0, is the counterpart to the AI Readiness Engine's static analysis: it actually queries your configured AI engines, with repeated sampling, and reports whether your brand gets mentioned, recommended, and cited — versus named competitors — each rate with a 95% confidence interval, because a single AI response is not a reliable measurement.
MeasurementEngine
Runs every configured engine adapter against a prompt list (typically from PromptDiscovery) runs times each — default 3, max 10 — and aggregates into a MeasurementReport:
import { MeasurementEngine } from "ai-visibility/measure";
import { OpenAIAdapter, PerplexityAdapter } from "ai-visibility/engines";
import { PromptDiscovery } from "ai-visibility/prompts";
const { clusters } = PromptDiscovery.discover({ brand: "Acme CRM", category: "CRM software", competitors: ["HubSpot"] });
const engine = new MeasurementEngine();
const report = await engine.measure({
brand: "Acme CRM",
prompts: clusters.flatMap((c) => c.prompts),
engines: [new OpenAIAdapter(process.env.OPENAI_API_KEY!), new PerplexityAdapter(process.env.PERPLEXITY_API_KEY!)],
runs: 3,
competitors: ["HubSpot"],
});All calls run through a single sequential queue, grouped by engine — every call to one engine completes, with a 1-second delay between them, before moving to the next engine. Never more than one HTTP call in flight, and never a burst against one provider. A failed call is logged and counted in stats.failedRuns; it is never recorded as a RunResult— fabricating a failure as "not mentioned" would silently bias every rate downward.
The statistics
For each tracked name (the brand, plus every competitor), across every successful run:
- mentionRate — fraction of runs where the name appeared in the response (case-insensitive substring match).
- recommendRate — fraction of runs where the name appeared within 2 sentences of a recommendation-context keyword ("recommend", "best", "top pick", etc.) — deliberately simple keyword proximity, not sentiment analysis.
- averagePosition — mean 1-indexed rank by first-mention order among all tracked names within that response (lower is more prominent); 0 when never mentioned.
- citationRate — fraction of runs where a cited URL's hostname contains the name's alphanumeric slug ("Acme CRM" →
acmecrm, matchesacmecrm.com). An approximation — there's no reliable brand-to-domain mapping without asking for one. - variance — population variance of the per-run mention indicator (divides by
n, notn-1, so a single-run measurement doesn't divide by zero). - confidence — 95% confidence interval half-width:
1.96 × √(variance / sampleSize). Report a rate asmentionRate ± confidence; a wide interval means "measure more runs," not "the number is wrong."
CLI: measure
npx ai-visibility measure --brand "Acme CRM" --category "CRM software" --competitors "HubSpot,Pipedrive" --runs 3
npx ai-visibility measure --brand "Acme CRM" --category "CRM software" --json > report.jsonmeasure runs discover internally, queries every configured engine, and prints overall + recommendation-rate bars (brand vs. competitors, each with its confidence interval), a per-engine mention-rate table, and sample-size/duration stats. It resolves engine API keys the same way as every command in this suite — see crawlpod.config.js and environment variables— and throws a clear, actionable error if zero engines resolve a key. Saved --json output can be reused by citations, compare, and report via their --from flag, without re-spending API credits.
Interpreting a result
Read every rate alongside its confidence interval, not in isolation. A brand at 40% mention rate ± 5% and a competitor at 45% ± 30% are not clearly different — the competitor's interval is too wide from too few samples to say so with any confidence; increase runs before concluding anything. perEnginetracks only the primary brand per engine, not competitors — the CLI's "PER ENGINE" display reconstructs a full per-engine-per-competitor breakdown by re-aggregating perPrompt[].runs[] instead.
A low mentionRate alone doesn't say why— that's what citation analysis and competitor gap analysis are for, both of which mine the same MeasurementReport this command produces.