AIO Score

Agent Input Optimization — a single number (0–100) that tells you how well an AI agent can read a given URL.

What it measures

The AIO Score predicts the likelihood that an LLM consuming this page will produce accurate output. Higher score = more semantic signal per byte, less framework noise, better content negotiation, lower hallucination risk. The same engine powers the public scanner at buildonto.dev/api/aio, the authenticated POST /v1/score endpoint, and the score shown on /serve/dashboard.

Scoring model

Subtractive penalty model, not a weighted average. Every URL starts at 100. Each detected issue subtracts points; each detected positive signal can also add a benefit row but doesn't raise the score above the penalty result. Final score is the plain subtraction.

Result shape from the scoring engine:

ts
{
  score: 92,                       // 0–100, after all subtractions
  grade: 'Excellent',              // bucket name
  hallucination_risk: 'low',       // low | medium | high
  insights: { ... },               // boolean flags per signal
  penalties: string[],             // each is a -N point line item
  benefits:  string[],             // positive signals detected
  recommendations: [               // ranked, high-priority first
    { priority: 'High', title: '...', description: '...' }
  ],
  stats: { raw_size, efficiency, ... },
  bot_preview: '...',              // first 200 chars of cleaned Markdown
}

Grade ranges

Bucket names come from scoreToGrade() in the engine. The hallucination-risk column is the dominant case from getHallucinationRisk() — actual risk also depends on which insights flipped (robots, JSON-LD, semantic hierarchy, Markdown support), so the value below is the typical floor at each band.

ScoreGradeHallucination risk
90–100Excellentlow
75–89Goodlow
50–74Needs workmedium
25–49AI-hostilehigh
0–24Invisiblehigh

Signals checked

Every check below maps to a specific penalty branch in @ontosdk/core/score/aio.ts. Penalties accumulate; the robots check is fatal and short-circuits the rest.

SignalPenalty when missing/bad
robots.txt allows AI crawlersscore = 0 if GPTBot or * is disallowed (fatal)
Markdown layer (Accept negotiation or .md route)−25 if no Markdown surface is detected
Onto SDK is the Markdown layer−10 if Markdown is present but not Onto-managed
React Tax (HTML-to-semantic-text ratio)−25 if < 15% semantic, −10 if 15–30%
Raw page size−10 if > 200 KB
JSON-LD schema markup−20 if no JSON-LD anywhere on the page
Heading hierarchy (h1 / h2 / h3 count)−10 if fewer than 2 headings
Image alt-text coverage−5 per batch of images missing alt
Errors vs penalties. A few states surface as error responses rather than scoring penalties — notably WAF blocks (WAF_BLOCKED), 404s (URL_NOT_FOUND), and origin timeouts (TIMEOUT). See the error codes index for the full catalog.

How to improve

The fastest single move: install @ontosdk/next. The SDK serves clean Markdown to bots (negotiation penalty resolved), preserves semantic structure (heading penalty resolved), and reports its presence so the scorer sees the integration. Sites running the SDK typically jump 30–50 points without any content changes.