Insights · Demonstration
Crawlable, understandable, interactive, transactable: four levels of machine readiness
A worked example of how we assess machine readiness. The business, its pages and every number below are invented for illustration.
SYNTHETIC DATA — fictional business “Harbor & Pine Plumbing”
The four levels
We assess every site against four progressively harder questions. Each level builds on the one before, and each costs more to implement — so the goal isn't to reach Level 4 everywhere, it's to know which level your business actually needs.
- Crawlable — can AI crawlers and agents fetch the content?
- Understandable — can AI systems interpret it accurately?
- Interactive — can an agent search, compare or request something?
- Transactable — can an agent reliably complete a transaction?
Same business, two builds
Many crawlers and agents don't run JavaScript reliably. Here's what a simple HTTP fetch — no JavaScript — receives from two versions of the same homepage.
<!doctype html>
<html>
<head><title>Loading…</title></head>
<body>
<div id="root"></div>
<script src="/static/js/main.4f1c.js"></script>
</body>
</html>
What a non-JS fetch extracts
- Title: “Loading…”
- Business name: none
- Service area: none
- Hours, price, phone: none
- Actions available: none
<!doctype html>
<html lang="en">
<head>
<title>Emergency Plumbing in Northfield · Harbor & Pine</title>
<link rel="canonical" href="https://harborandpine.example/">
<script type="application/ld+json">
{ "@context": "https://schema.org",
"@type": "Plumber",
"name": "Harbor & Pine Plumbing",
"areaServed": "Northfield",
"openingHours": "Mo-Su 00:00-23:59",
"telephone": "+1-555-0100" }
</script>
</head>
<body>
<main>
<h1>24/7 emergency plumbing in Northfield</h1>
<p>Licensed plumbers. Call-out fee $95, waived if we do the repair.</p>
<form action="/quote" method="post">
<label for="zip">ZIP code</label>
<input id="zip" name="zip" autocomplete="postal-code">
<button>Check availability</button>
</form>
</main>
</body>
</html>
What a non-JS fetch extracts
- Business: Harbor & Pine Plumbing (Plumber)
- Service area: Northfield
- Hours: 24/7 · Call-out: $95, waived with repair
- Action: a labeled availability form (ZIP code)
- Canonical URL declared
Version B isn't “optimized for AI” in any special way. It's ordinary, well-built HTML: content in the server response, a clear heading, facts stated in plain text and repeated in structured data, and a form with a real label. That's most of Levels 1 and 2. The labeled form is the start of Level 3.
Structured data helps make facts explicit, but it must match what's visible on the page — and Google states it isn't required for its generative AI features. The plain-text facts do most of the work.
The assessment scorecard
| Level | Check | Result | Evidence we'd record |
|---|---|---|---|
| L1 | Search and AI-search crawlers allowed per policy | Pass | robots.txt rules; 200 responses to verified bots |
| L1 | Key content in server HTML | Pass | Non-JS fetch contains H1, hours, price |
| L2 | Facts consistent across site, schema and profiles | Partial | Directory listing shows old phone number |
| L2 | Structured data valid and matches visible content | Pass | Validator output, side-by-side diff |
| L3 | Primary action is an accessible, labeled form | Pass | Accessibility tree shows named input and button |
| L3 | Bot challenge doesn't block legitimate agents | Untested | Requires scripted agent test |
| L4 | Documented API for availability/booking | None | Not needed yet — recommendation: stay at L3 |
The recommendation here would be to fix the inconsistent phone number, test the form with a real browser agent, and not build an API yet. Level 4 only makes sense once customers' agents are actually trying to book.
A visibility dashboard that keeps signals apart
This is the shape of report we'd produce after a month of monitoring. Notice which rows are largest — and which ones matter.
Harbor & Pine · 30-day visibility
SYNTHETIC DATA
| Bucket | Count | Relative volume (log scale) | Source |
|---|---|---|---|
| Human organic search sessions | 4,820 | Search Console + analytics | |
| Human referrals from AI interfaces | 212 | Known assistant referrers | |
| Verified AI crawler requests | 38,650 | UA + IP/rDNS verification | |
| User-initiated AI fetches | 1,430 | ChatGPT-User, Claude-User, Perplexity-User (verified) | |
| Identified agent API calls | 0 | No public API yet | |
| Unclassified automation | 22,110 | Unverified bot-like traffic | |
| Qualified leads | 31 | Spam-checked, qualified form submissions |
How to read this: verified crawler requests are the biggest number and the least meaningful. They show access, not recommendation. The 212 assistant referrals and 31 qualified leads are what the business should track — and the 22,110 unclassified requests are excluded from every other row.