Programmatic API
audit(), batchAudit(), baselines, reporters, and all exported TypeScript types. Rendered from the canonical source in the repository: docs/api.md
Full TypeScript support; every public type is exported from the package root.
import { audit, batchAudit } from 'ax-audit';
import type { AuditReport, BatchAuditReport } from 'ax-audit';
The package is ESM-only ("type": "module"), targets Node 18+ (built-in fetch), and ships type declarations at dist/index.d.ts.
audit(options): Promise<AuditReport>
Runs all (or selected) checks against one URL.
function audit(options: AuditOptions): Promise<AuditReport>;
interface AuditOptions {
url: string; // required, fully qualified (scheme included)
checks?: string[]; // default: all. Unknown IDs are silently ignored here
// (the CLI validates them; the API does not)
timeout?: number; // ms per request, default 10000
retries?: number; // transient-failure retries, default 2
verbose?: boolean; // log to stderr, default false
}
Behavior:
- Checks execute in parallel via
Promise.allSettled. A check that throws becomes a score-0CheckResultwhose findings contain the error —audititself never rejects for a check failure. - All HTTP requests in a run share an in-memory cache keyed on URL + normalized request headers (
Vary-aware). - The homepage is fetched once and passed to every check as
ctx.html/ctx.headers.
const report = await audit({ url: 'https://example.com' });
report.overallScore; // number 0–100, weighted
report.grade; // { min, label, color }
report.results; // CheckResult[]
report.duration; // ms
audit rejects only for an unrecoverable setup error (e.g. an invalid url that can't be parsed). Network failure on the homepage fetch does not reject — it surfaces as failing checks.
batchAudit(urls, options?): Promise<BatchAuditReport>
function batchAudit(urls: string[], options?: BatchOptions): Promise<BatchAuditReport>;
interface BatchOptions extends Omit<AuditOptions, 'url'> {
concurrency?: number; // max parallel audits, default 1 (sequential)
}
Report order always matches input order, regardless of concurrency. concurrency < 1 is treated as 1.
const batch = await batchAudit(urls, { concurrency: 4, retries: 2 });
batch.reports; // AuditReport[], input order
batch.summary.total; // number
batch.summary.passed; // count scoring >= 70
batch.summary.failed; // count scoring < 70
batch.summary.averageScore;
batch.summary.grade; // Grade for the average
Result shapes
interface AuditReport {
url: string;
timestamp: string; // ISO 8601
overallScore: number; // 0–100
grade: Grade;
results: CheckResult[];
duration: number; // ms
}
interface CheckResult {
id: string; // e.g. 'llms-txt'
name: string; // e.g. 'LLMs.txt'
description: string;
score: number; // 0–100, clamped
findings: Finding[];
duration: number; // ms
}
interface Finding {
status: 'pass' | 'warn' | 'fail';
message: string;
detail?: string;
hint?: string; // remediation advice (warn/fail)
learnMoreUrl?: string; // link to the matching remediation guide
}
interface Grade { min: number; label: string; color: string; }
Scoring
function calculateOverallScore(results: CheckResult[], metas: CheckMeta[]): number;
function getGrade(score: number): Grade;
calculateOverallScore computes the weighted average; it falls back to a plain average when all selected checks have weight 0, and returns 0 for empty input. getGrade maps a score to its Grade.
Baselines
function toBaselineData(report: AuditReport): BaselineData;
function saveBaseline(path: string, report: AuditReport): void; // writes JSON
function loadBaseline(path: string): BaselineData; // throws on missing/invalid file
function diffBaseline(baseline: BaselineData, report: AuditReport): BaselineDiff;
interface BaselineData {
url: string;
timestamp: string;
overallScore: number;
checks: Record<string, number>; // checkId → score
}
interface BaselineDiff {
url: string;
baselineTimestamp: string;
currentTimestamp: string;
overallPrevious: number;
overallCurrent: number;
overallDelta: number;
checks: CheckDiff[];
regressions: CheckDiff[]; // delta < 0
improvements: CheckDiff[]; // delta > 0
}
loadBaseline throws (does not return null) on a missing file or invalid JSON — wrap it in try/catch. Checks present now but absent from the baseline appear as new (no delta); checks removed since are ignored.
Reporters
function renderMarkdown(report: AuditReport, diff?: BaselineDiff): string;
function renderBatchMarkdown(batch: BatchAuditReport): string;
Both return a Markdown string (summary table + findings with status emoji; baseline deltas when a diff is passed). Terminal and HTML rendering are CLI-internal; for other formats, consume the AuditReport JSON directly.
Checks registry
import { checks } from 'ax-audit';
interface CheckModule {
run: (ctx: CheckContext) => Promise<CheckResult>;
meta: CheckMeta; // { id, name, description, weight }
}
Run an individual check with a custom context:
const llms = checks.find((c) => c.meta.id === 'llms-txt')!;
const result = await llms.run({
url: 'https://example.com', // no trailing slash
html: homepageHtml,
headers: homepageHeaders, // lowercased keys
fetch: myFetchImpl,
});
interface CheckContext {
url: string;
html: string;
headers: Record<string, string>;
fetch: (url: string, options?: FetchOptions) => Promise<FetchResponse>;
}
interface FetchOptions { headers?: Record<string, string>; }
interface FetchResponse {
status: number; // 0 on network error
headers: Record<string, string>; // lowercased keys
body: string;
ok: boolean;
url: string; // final URL after redirects
error?: string; // set when status === 0
}
ctx.fetch custom headers merge case-insensitively over the defaults (a custom Accept or User-Agent replaces the default), and responses are cached per URL + normalized headers — mirroring HTTP Vary. Your fetch implementation should never throw; model failures as { status: 0, ok: false, error }.
API stability
Within a major version, the exported function signatures and the AuditReport JSON shape are stable. Specifically:
- Stable:
audit,batchAudit,calculateOverallScore,getGrade, the baseline functions, the reporter functions, and all exported type shapes. - May change in minor versions: the set of checks (new checks are added), individual check
score/findingscontent, and checkweightvalues (new checks start at 0; reweighting is reserved for majors). Treatresultsas a list to iterate, not a fixed-length tuple. - Internal: anything not exported from
src/index.ts, including terminal/HTML reporters and individual check modules' internals.
Exported types
AuditOptions, BatchOptions, AuditReport, BatchAuditReport, CheckResult, CheckMeta, CheckContext, CheckModule, Finding, FindingStatus, FetchOptions, FetchResponse, Grade, OutputFormat, BaselineData, BaselineDiff, CheckDiff.