Audit CMS content with AI
The content auditor sends the website’s CMS document to a fast LLM (Anthropic Haiku via OpenRouter) and returns a structured rubric across 8 dimensions plus a weighted overall score. Findings come back with severity, score, one-line summary, and a concrete fix the operator can act on.
Prerequisites
Section titled “Prerequisites”- A Website with SEO enabled (
POST /websites/:id/seoset to any tier aboveessentials) - A published content document at
content/settings/site.jsonon the per-client repo (anything you can edit throughvantage content editor the Content tab in the portal)
Tier gates
Section titled “Tier gates”| Tier | Audits / month |
|---|---|
| Essentials | 0 (not available) |
| Growth | 4 |
| Premium | 12 |
| Premium+ | 30 |
essentials returns 403 from the API. growth and up consume one
slot per uncached audit — see the cache section below.
The 8 dimensions
Section titled “The 8 dimensions”| Dimension | What the LLM scores |
|---|---|
title | Site title clarity. Penalizes defaults like “Your Business”. |
tagline | One-line value prop — what the business does and for whom. |
about | About section depth. 2+ sentences with concrete history/values. |
services | Service list count + per-item descriptions. |
faq | 3+ Q&As that AI search engines could cite. Empty = error. |
business | NAP profile (name/address/phone) + hours + service area. |
contact | Email + phone presence. |
localPages | Per-city landing pages. Optional, but a strong local-SEO signal. |
Each finding lands in one of four severity bands derived from the
0–100 score: 0-29 → error, 30-59 → warn, 60-84 → info,
85-100 → info.
The overall score is a weighted average — about, services,
faq, and business count double (they carry the GEO load),
title, tagline, contact count single, and localPages counts
half.
Caching
Section titled “Caching”Cost-management is baked in. The auditor canonicalizes the
siteContent body (stable-stringify with sorted keys, deep) and
sha256s it. A repeat audit on byte-identical content returns the
prior result with cached: true and does not consume a quota
slot. Operators can poke the audit button as much as they like;
quota only tracks calls where the LLM had new work to do.
Cache survives forever (until the content changes) — it’s stored on
the SEO row’s metadata.lastContentAudit alongside the hash. The
cached response includes cachedAt so the UI can render a “last
audited X minutes ago” badge.
Four ways to run it
Section titled “Four ways to run it”Portal
Section titled “Portal”Open a website’s Content editor, click Quality check in the settings rail. The panel runs the audit, sorts findings by severity, and exposes a Fix → button on each row that jumps the editor to the relevant section.
vantage seo ai-content-audit [<websiteId>] [--json]Defaults to the site you’re cwd’d into. Pretty-prints findings by
default; pass --json to pipe.
import { VantageClient } from "@vantageconnections/sdk";
const vc = new VantageClient({ token, baseUrl });const { content } = await vc.content.get(websiteId);const res = await vc.seo.contentAudit(websiteId, { siteContent: content });// res.findings: SeoContentAuditFinding[]// res.overallScore: number (0-100)// res.cached: boolean// res.cachedAt?: string// res.used, res.limit: monthly countersFor Claude Desktop / Claude Code with the Melbora MCP server connected:
vantage_seo_ai_content_audit websiteId: ws_… siteContent: <the parsed content document>A typical flow: call vantage_content_get first to retrieve the
document, then pass .content straight into siteContent.
Response shape
Section titled “Response shape”{ "overallScore": 72, "findings": [ { "dimension": "faq", "severity": "warn", "score": 45, "summary": "Only 2 FAQs — below the 3+ AI search engines like to cite.", "suggestion": "Add Q&As about pricing, scheduling, and what's included so AI assistants have answer material." } ], "used": 1, "limit": 4, "cached": false}When cached: true, cachedAt (ISO timestamp) is also present.
What the auditor doesn’t do
Section titled “What the auditor doesn’t do”- It does not rewrite content for you. Each finding’s
suggestionis a one-line action — the operator (or the client) still does the writing. Usevantage seo ai-blog-draftorvantage seo ai-local-pagefor AI-authored content. - It does not crawl the live site. The audit is purely against the CMS document, so unpublished edits aren’t reflected until the operator saves them.
- It does not persist findings as historical timeseries. Each
audit overwrites the prior
lastContentAuditon the SEO row; there’s no audit log per site.