Findings Schema
Every audit check produces one or more AuditFinding objects. This is the core data type in the VisibilityIQ audit engine.
AuditFinding type
Section titled “AuditFinding type”interface AuditFinding { checkId: string; // e.g. "canonical.mismatch-raw-rendered" scope: FindingScope; // where the defect lives severity: Severity; // how bad it is if real confidence: Confidence; // how certain we are pageUrl: string; // the affected URL templateId?: string; // present when scope is 'template' or 'cluster' evidence: Record<string, unknown>; // check-specific structured data remediation: string; // WHAT/WHERE/FIX/VERIFY/RISK operational instruction guidance: Guidance; // structured UX payload for the guided-fix modal affectedResources?: string[]; // related URLs or resources firstDetected?: string; // ISO 8601 date status: FindingStatus;}
type FindingScope = 'page' | 'template' | 'cluster' | 'site' | 'source-reconciled';type Severity = 'critical' | 'high' | 'medium' | 'low' | 'info';type Confidence = 'high' | 'medium' | 'low';type FindingStatus = 'new' | 'recurring' | 'regressed' | 'fixed';Scope values
Section titled “Scope values”| Scope | Meaning |
|---|---|
page | Defect on a specific URL only |
template | Defect shared by a URL pattern (e.g., all /blog/* pages) |
cluster | Defect across a group of semantically similar pages |
site | Site-wide defect (e.g., missing HSTS header on all responses) |
source-reconciled | Finding that only emerges when comparing crawl data with GSC/GA4 |
Evidence payload
Section titled “Evidence payload”The evidence object is check-specific. Every evidence payload includes the raw values that triggered the finding. Examples:
Canonical mismatch:
{ "rawCanonical": "https://example.com/page-a", "renderedCanonical": "https://example.com/page-b", "expectedCanonical": "https://example.com/page-a"}robots.txt AI bot block:
{ "userAgent": "GPTBot", "directive": "Disallow: /", "robotsTxtUrl": "https://example.com/robots.txt", "rawDirectives": ["User-agent: GPTBot", "Disallow: /"], "affectedPages": 1247}Missing HSTS:
{ "headerPresent": false, "observedHeaders": { "strict-transport-security": null }, "recommendedValue": "max-age=31536000; includeSubDomains"}Guidance type
Section titled “Guidance type”interface Guidance { summary: string; // one-sentence plain-language explanation whyItMatters: string; // business/visibility impact, no jargon steps: GuidanceStep[]; // ordered action list suggestedFix?: string; // copy-button-ready exact value to apply generatedArtifact?: GeneratedArtifact; learnMoreUrl?: string; autoApplyEligible: boolean; riskLevel: 'safe' | 'review' | 'destructive';}
interface GuidanceStep { label: string; // "Open your robots.txt" detail: string; // what to do and what success looks like generatesFile?: boolean;}
interface GeneratedArtifact { filename: string; // e.g. "robots.txt" mimeType: string; // e.g. "text/plain" contents: string; // the corrected, apply-ready file placement: string; // where it goes ("site root", "<head> of /products/*") sourceFindingIds: string[];}Finding status lifecycle
Section titled “Finding status lifecycle”new → recurring (if same finding in next audit)new → fixed (if not present in next audit)fixed → regressed (if reappears after being fixed)API response shape
Section titled “API response shape”When fetching findings via the API, the response looks like:
{ "ok": true, "data": { "findings": [ /* AuditFinding[] */ ], "total": 142, "page": 1, "limit": 50 }}Findings are paginated. Use ?limit=50&offset=50 for subsequent pages.