Skip to content
Scoring v1.5

What we check

25 checks across 6 categories. The weights are below because publishing them is the only way the score can be argued with, and a score nobody can argue with is a horoscope.

How the arithmetic works

Every number on this page is out of the same 100. A category is worth its weight; the checks inside it split that weight between them; and the figure beside each check is exactly what failing it takes off your score — the same number the findings list on your result prints back to you. A pass earns all of it, a warn earns half, a fail and an error earn none, and a check we could not run at all leaves the denominator instead of counting as a zero.

The weights themselves are our estimates, argued for one by one below and not yet measured against whether a site actually gets cited. We are collecting that evidence now and will publish it, alongside whatever it says about these numbers, before we change them. Changing any of them is a versioned event: every score records the version that produced it, so history is re-scored rather than quietly rewritten.

Some checks do not apply to your sector

A plumber has no API to document and no agent manifest to publish, and scoring one against those is scoring it against somebody else’s business. So a site that says what kind of business it is, in its own JSON-LD, is measured on the checks that apply to it. The rest are not failed; they are not asked, and the categories that remain carry the weight the exempt ones gave up.

A profile is only ever earned by a site declaring what it is. It is never inferred from the absence of the thing being exempted, because “no API docs, so none needed” would hand every site a free pass. A site that declares nothing is measured on all 25.

  • Local servicenot measured on api_docs_reachable, agent_manifest, no_wall_on_docs, pricing_structured
  • Ecommercenot measured on api_docs_reachable, agent_manifest, no_wall_on_docs
  • Medianot measured on api_docs_reachable, agent_manifest, no_wall_on_docs, pricing_structured
Heights are normalised against the 25% maximum.
25%

Retrievability

Can each client get the page at all, and is the text there without JavaScript

4 checks25 of the 100
20%

Discovery

robots.txt, sitemap.xml, llms.txt and the paths agents look for

5 checks20 of the 100
20%

Representation

Whether your own description of what you do is readable as data

4 checks20 of the 100
15%

Structure

Headings, titles and link targets that actually resolve

3 checks15 of the 100
15%

Actionability

Prices, plans and next steps an agent can quote

7 checks15 of the 100
5%

Freshness

Dates and change signals on the pages that carry them

2 checks5 of the 100
Everything adds up
25 checks100 pointsone score

The clients

We request your page once as each of these, sequentially, one second apart. The Chrome request is the control and everything else is compared against it.

  • chromeMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36control
  • claudebotClaudeBot/1.0agent
  • gptbotGPTBot/1.2agent
  • perplexityPerplexityBot/1.0agent
  • googleextGoogle-Extendedagent

The checks

Retrievability · 25 of the 100

Nothing else can matter if the client cannot get the page. This carries the most weight because every other category is measured on text that was retrieved, and a refusal makes the rest unobservable rather than merely worse.

Every client gets the same answer

12.9 of the 100
agent_status_parity

The headline finding of the whole product: 200 to Chrome and 403 to ClaudeBot, same URL, same second. The largest single check in the catalog, because it is the only failure that makes every other measurement moot.

fails when any agent client receives a different status class than the Chrome control

Page text survives without JavaScript

7.9 of the 100
js_dependency_ratio

Text that appears only after JavaScript runs is text most agent clients never see. Second largest because it is the failure that looks perfect in a browser and is invisible to the people it costs you.

fails when ratio above 0.7
warns when ratio between 0.4 and 0.7

First byte arrives quickly

2.1 of the 100
raw_fetch_latency

A slow first byte gets the request abandoned. Small because real timeouts are rare, and because this is the noisiest measurement in the catalog — see S2 in SCORING-PLAN.md.

fails when ttfb above 2500 ms

No long redirect chains

2.1 of the 100
redirect_depth

Every hop is a chance to lose the client. Small because chains are uncommon and a short one is harmless.

fails when more than 3 hops
Discovery · 20 of the 100

The files a client asks for before it reads anything: robots.txt, a sitemap, llms.txt. Weighted high for their cost — they are the cheapest things on this list to fix and they decide what gets fetched next.

robots.txt exists and parses

3.1 of the 100
robots_present

Not a refusal in itself, but it is the first thing every client asks for, and a 5xx here stops some of them before they reach the page.

robots.txt does not silently block reading agents

6.2 of the 100
robots_agent_rules

A robots.txt that disallows reading agents is a refusal you chose, usually by pasting a rule nobody read. Worth twice robots_present because this one actively turns clients away rather than merely failing to help them.

fails when an agent user agent is disallowed while search crawlers are allowed

Sitemap exists and is not empty

3.1 of the 100
sitemap_present

How a client finds the pages you did not link from the front door.

llms.txt tells agents which pages matter

3.8 of the 100
llms_txt_present

The file agents look for to learn what you do in plain language. Just above the sitemap because it is the one file here we can generate for you in full, from pages we watched return 200.

A second page is reachable without a browser

3.8 of the 100
pages_reachable

A site an agent can only see one page of is a site an agent cannot answer questions about. Fails when the HTML you send carries no link to another page of your own site and the sitemap offers none either — most often because the navigation is built by JavaScript, which means a client that does not run one arrives at your front door and finds no doors.

fails when no page beyond the target could be reached from the HTML as sent, and the cause is the site rather than our own cap or a request nothing answered
warns when your robots.txt disallows the pages we would otherwise have read
Representation · 20 of the 100

Whether your own account of what you do survives as data rather than as layout. An agent can only quote what it can extract.

A markdown representation is advertised

7 of the 100
markdown_alternate

A markdown representation advertised in a Link header or tag is the cheapest way to hand a client clean prose instead of a layout to unpick.

fails when no link rel=alternate type=text/markdown and no Link header equivalent

One h1, a sane heading order, a main landmark

6 of the 100
semantic_landmarks

One h1, a sane heading order and a main landmark are how an extractor decides which part of the page is the content.

Each page has its own title and description

4 of the 100
title_meta_distinct

Pages that share a title are pages a client cannot tell apart when it comes to cite one of them.

Server honours Accept: text/markdown

3 of the 100
content_negotiation

Honouring Accept: text/markdown is the polite version of the markdown alternate. Small because hardly anyone implements it and its absence is unremarkable.

Structure · 15 of the 100

The scaffolding that says which page this is and what it is about: headings, canonical URLs, JSON-LD. Below representation because a well-described page with untidy structure still gets read.

JSON-LD describes what this is

6 of the 100
jsonld_present

On most pages this is the only place the site states what it is in a form that needs no interpretation.

Pricing is machine readable

5 of the 100
pricing_structured

An agent quotes a price it can read as data. A price in a table is a picture of a price.

fails when prices appear only in images or JS-rendered tables

Canonical URL and OpenGraph are complete

4 of the 100
canonical_og

Which URL is the real one, and what the page says about itself when somebody shares it.

Actionability · 15 of the 100

Prices, plans, docs and forms an agent can act on rather than only describe. Equal to structure because being quotable and being usable are worth the same to a buyer.

An agent manifest or WebMCP endpoint exists

2.9 of the 100
agent_manifest

A manifest or WebMCP endpoint turns a page an agent can read into a service an agent can use. Scored knowing most sites will fail it for a while yet; this is the check most likely to move at the next calibration.

API docs are two hops from the homepage

2.3 of the 100
api_docs_reachable

Docs two hops from the homepage are docs an agent finds while it is answering a question about you.

Primary forms have labels, names and autocomplete tokens

2.3 of the 100
form_semantics

Labels, names and autocomplete tokens are what let an agent complete a form rather than describe one.

Docs and pricing are not behind auth or a captcha

1.2 of the 100
no_wall_on_docs

Docs behind a login are docs no client reads. Small because it is rare, and because when it is deliberate it is a legitimate choice we should not punish hard.

A person is reachable in a way an agent can hand over

2.3 of the 100
contact_reachable

The most common thing anybody asks an assistant about a business is how to reach it. A tel: or mailto: link, or a telephone in your JSON-LD, is something an agent can read out or dial. A phone number set as an image, or as text with no link, is a number it cannot pass on. Every business has this answer already; this check is about whether it is machine-readable.

What can be done here is declared, not just described

2.3 of the 100
action_declared

Booking a table, ordering, requesting a quote, subscribing: a schema.org Action or an Offer says which of those your site supports. Without one an agent can describe you and cannot act for you, which is the difference the whole category is measuring. This is the check most sites can pass with one block of JSON-LD.

The way to act is in the HTML, not only after JavaScript

1.7 of the 100
action_not_js_only

A booking button that only exists once a script has run is a button no non-rendering client can find. Measured by comparing the raw response against the rendered DOM: contact links or declared actions present in one and not the other.

Freshness · 5 of the 100

Dates and change signals. Worth the least because a stale signal loses a citation rarely, and it is the category where a maintained site can look bad for reasons that do not matter.

Last-Modified or ETag is sent

3 of the 100
cache_headers

Last-Modified or ETag tells a client whether reading you again is worth it.

Sitemap lastmod values are maintained

2 of the 100
sitemap_lastmod_real

A lastmod that never changes is worse than no lastmod at all, because it is a claim rather than a gap.

fails when every lastmod is identical or in the future
What we check — botready.dev