Methodology & sources.
Every quantified claim on the marketing site links back to the method that produced it. This page documents the sample populations, formulas, and caveats behind each figure so you can decide for yourself how seriously to take it.
Updated
How are the "10,000 US SMB websites" and "64/100 median health score" figures calculated?
Silent Traffic Killers report — source population: the published Silent Traffic Killers report scanned 10,000 public US service-business websites sourced from DataForSEO Business Listings. Of those, 9,047 were reachable during the scan window; 953 timed out or returned errors and are excluded from the per-rule prevalence figures. The "64/100 median health score" is the median across the 9,047 reachable sites in that 10,000-site corpus.
State of SMB SEO dashboard — live sample: the State of SMB SEO dashboard re-runs the aggregation daily against a separate, continuously-refreshed snapshot of 1,149 randomly selected US SMB sites drawn from a public Inc. 5000-style operator list. This is the figure shown on the live dashboard tile; it updates as the daily scans run and will drift slightly from the static report as site health changes over time.
Scan method (both): each site is crawled via its sitemap (max 200 URLs) and evaluated against the same 54-check scanner (42 SEO + 12 AEO) that runs daily on customer projects. The 64/100 figure in the Silent Traffic Killers report reflects the historical SEO core only — AEO scoring was added after the 10,000-site research run, so the report and live dashboard report SEO and AEO scores separately. No URL filtering or curation beyond the per-scan cap.
Health score formula: max(0, 100 − critical×15 − warning×5 − info×1) per page, then aggregated to the site median. Implementation: backend/app/services/anon_audit_service.py:compute_score.
How do we calculate the "150 client posts a month at $1.66 each" Agency-tier figure?
Formula: $249 / 150 = $1.66. The Agency tier costs $249/mo and includes 150 AI-generated posts/mo. The "$1.66 each" number is the simple division, not an amortization or attribution model.
What's not included: CMS hosting, domain costs, your own time to review and approve content before publishing, custom-image overage, and any platform fees on the publishing side.
Where to verify: the Agencies page has an interactive ROI calculator that lets you plug in your actual client + cadence + writer cost.
What does the "$5K/mo writer retainer" segment dossier figure represent?
Reference range: $5,000/mo represents a midpoint for a contract content writer or boutique content shop producing 8–15 long-form posts per month for a B2B SaaS startup. Lower-cost arrangements exist (offshore, junior, AI-assisted) and higher-cost arrangements exist (senior in-house, major agencies). It is not a survey average — it is a segment reference figure used for positioning the one-person marketing team dossier.
How to read it: the dossier is illustrative — the actual savings vs. VectraSEO depend on your current spend and post volume. The Agencies ROI calculator uses your real numbers.
What is included in the "54 checks" site monitor figure?
Source: the canonical rule list lives in backend/app/services/rules/__init__.py as DEFAULT_RULES. It currently registers 42 SEO rules (R01–R42); a further 12 AEO readiness checks live in backend/app/services/rules/aeo.py, for 54 total. Each implements a Rule interface with an evaluate(fetch_result) method; site-level checks can also implement evaluate_batch(results).
Visible inventory: the homepage Ruleset section enumerates all 54 by ID with one-line descriptions, split into the 27-rule SEO core grid (R01–R27, now including soft-404 and duplicate-metadata detection), the 15-rule Lighthouse-inspired HTML/accessibility tier (R28–R42), and the 12-check answer-engine tier (R43–R54). The docs describe the behaviour and severity per rule. SEO health and AEO readiness scores are computed independently — the homepage and this page both update from the same source list.
Where does the "Google's actual indexing verdict" page-indexing panel come from?
Source: Google's URL Inspection API (part of the Search Console API). For each URL on a project's sitemap, VectraSEO records Google's verdict, coverageState, indexingState, userCanonical, googleCanonical, last-crawl time, and robotsTxtState. We surface what Google decided, not what a third-party crawler guessed.
Method: on the same daily cadence as the rest of the GSC refresh, the worker inspects up to 200 URLs per project (within Google's published 2,000/day quota), buckets each into one of 13 indexing states (Indexed, Alternate page with proper canonical, Duplicate without user canonical, Duplicate where Google chose a different canonical, Crawled-not-indexed, Discovered-not-indexed, Excluded by noindex, Redirect, Soft 404, 404, Server error, Blocked by robots.txt, Other), and writes daily rollups so the sparkline trend builds up over time.
Where to verify: after connecting Search Console, the panel renders on /projects/{id}/search with example URLs and a "Validate fix" button that re-inspects on demand. Implementation lives in backend/app/services/gsc_service.py (run_index_refresh, _bucket_from_inspection) and the read endpoint is GET /api/v1/projects/{id}/search/index-coverage. The same FAIL-bucket rows are exposed to coding agents via GET /api/v1/projects/{id}/agent/recommendations under rule_id=gsc_index_*.
How does the "30-day no-card trial · cancel anytime · keep everything we generated" claim work?
Trial mechanics: sign-up is via magic link with no payment information collected. After 30 days, the account remains active in read-only mode unless you select a paid plan. All generated posts, images, monitor history, and competitor data remain in your account.
30-day money-back guarantee: applies to the first paid invoice after the trial, monthly or annual. Request it within 30 days of that invoice and receive a refund. Cancellation is one-click from the billing dashboard at any time.
Where to verify: the Terms page documents the trial, billing, and refund mechanics in full.
How is the "99.98% uptime" status-strip figure measured?
Measurement: the homepage status strip and /integrations top strip display a rolling 30-day uptime figure for the public API surface (health checks at /health and /health/ready). The number is sourced from the same monitoring endpoint that fronts our internal alerting.
What it covers: API and worker availability. It does not cover individual third-party CMS or Gemini outages, which are tracked separately and surfaced as per-job error states inside the dashboard.
What it isn't: this is VectraSEO's own uptime, not a monitor for your site. VectraSEO watches your site's SEO and answer-engine health; for uptime and app monitoring, pair it with Nightlamp.
How do the Agent Truth Layer and public /verify/ receipts work?
Pipeline: after a draft passes the content-quality gate, the Agent Truth Layer runs in five passes — (1) extract factual claims from the draft and their cited sources; (2) fetch each cited URL; (3) verify the claim against the fetched source text; (4) recover unsupported claims via a Gemini Google Search grounded pass; (5) repair or strip sentences whose claims still can't be supported, then re-assess. A needs_review verdict is a hard publish gate alongside metadata and content-quality failures.
Output: every post stores a truth_report field with a truth_score and per-claim verdicts (verified, recovered, unsupported, unverifiable). The post detail view in the dashboard surfaces the report inline.
Public receipt: for any post whose status is published, a sanitized public-safe subset of the truth report is served at /verify/<project_id>/<post_id> — no auth required. The receipt is the GTM artifact: link to it from the published post so anyone (including AI Overviews and Perplexity crawlers) can audit the claims.
Where to verify: implementation lives in backend/app/services/agent_truth_layer.py; the public endpoint is GET /api/v1/verification/<project_id>/<post_id> and is gated to status=published posts only. Full reference: docs/agent-truth-layer.md. Feature-flagged behind agent_truth_layer_enabled (defaults True).
What powers the "daily keyword rank tracker" figure?
Sources: a hybrid provider mix. Queries you already rank for are pulled from Google Search Console (most accurate signal, zero per-query API cost). Queries you don't yet rank for are pulled from the configured live SERP provider: Serper first, then DataForSEO, then legacy SerpApi.
Cadence: daily refresh per tracked keyword. Geo and language default to the project's geo setting (desktop results, no local-pack split in v1).
Surfacing: per-project /projects/<id>/ranks view with sparklines, a "top wins this week" rollup chip on the project card, and drop alerts when a tracked keyword falls out of the top 10. The dashboard hero polls GET /api/v1/projects/<id>/ranks/summary.
Where to verify: implementation lives in backend/app/services/rank_service.py with repository backend/app/repositories/rank_repo.py. API endpoints are under /api/v1/projects/<id>/ranks/*. The hybrid GSC + paid-provider path was introduced in PR #684 and now supports Serper, DataForSEO, and legacy SerpApi fallbacks.
How does a one-click fix avoid overwriting edits you made outside VectraSEO?
Source of truth: for a page VectraSEO publishes, the fixer reads your live page — what's actually served — and recovers the exact editable content fragment from it, rather than editing a stored snapshot that may be out of date. Recovery is marker-first: published bodies are wrapped in a data-vectraseo-body element for deterministic re-extraction, with a single <main>/<article> landmark as the fallback. Because the patch is built on the live version, edits you made outside VectraSEO are preserved, not overwritten.
Method: read live → apply the minimal patch → re-validate through the same publish quality gates (metadata, content-quality delta, and the Agent Truth Layer for model-written changes) → republish via your CMS adapter → request a recrawl. On success, the stored snapshot is re-baselined to the live-plus-patch body so it stops drifting.
Safety: if the live page can't be fetched (down or blocked) or its editable content can't be isolated with confidence, the fix is skipped (live_unreadable / extract_low_confidence) rather than republished from an older copy, and the result states why. A never-published draft has no live page, so it patches its stored draft directly.
Where to verify: implementation lives in backend/app/services/autofix_service.py (apply / apply_batch), backend/app/services/live_content_extractor.py, and backend/app/services/autofix/base.py. Round-trip contract for custom endpoints: docs/custom-api-setup.md.
This page is updated when the underlying methodology changes. Most recent revisions: added M_07 (Agent Truth Layer + public verification receipts), M_08 (hybrid GSC + paid-provider rank tracker), and M_09 (one-click fixes read your live page as the source of truth and never overwrite outside edits); rule count moved to 54 with the addition of soft-404 detection, duplicate title/meta-description detection, and an AI-crawler-access (robots.txt) answer-engine check; the 10,000-site median is still computed against the historical SEO core because AEO scoring postdates that research run.