The Ora scanner bot
OraBot/1.0 (+https://ora.ai/bot)What it is
Ora measures how ready a website is for AI agents. When someone requests a score for your domain, our scanner fetches your public pages and the artifacts agents rely on: robots.txt, llms.txt, OpenAPI specs, MCP manifests, structured data. It visits on demand rather than on a schedule, and a scan is a bounded burst of requests with hard timeouts and body-size caps.How to verify it
A User-Agent string proves nothing, since anyone can copy it. So we are adopting HTTP Message Signatures (RFC 9421, the Web Bot Auth profile): our scanner will sign its requests with an Ed25519 key, and each request will carry Signature, Signature-Input and Signature-Agent headers.Our public keys are published now, ahead of the signing itself, so verifiers can list us before any of our traffic changes. Until signing is live our requests carry no signature, and nothing that claims to be Ora can be verified - so treat unsigned traffic on our User-Agent with the same suspicion you would treat any other unverified bot.The keys themselves live at https://ora.ai/.well-known/http-message-signatures-directory. Anything claiming to be us that fails verification against those keys is not us, and you should treat it like any other unidentified bot.The requests we do not sign
One part of a scan checks whether your site is reachable to AI crawlers at all, so during a scan we send a handful of requests carrying other crawlers' User-Agent strings (GPTBot, ClaudeBot, PerplexityBot and similar) at your homepage, and we record how your site answers.Those requests will stay unsigned even once signing is live. Signing them as Ora would contradict the User-Agent they carry and destroy the measurement, which is the whole point of sending them. We would rather state this plainly than have you discover crawler traffic from our range and read it as evasion. It is a small number of requests per scan, only ever against the homepage.Personal Agent Protocol checks
The Personal Agent Protocol (PAP) lets a company publish a file at /.well-known/poppy.json so personal agents can find its sign in and conversation endpoints. When a scan finds that file, OraBot checks it. Ora runs the scanner, and you can reach the people who run it at hello@ora.ai.Tier 0: plain reads of public files
The first request goes to every domain we scan. The others happen only when the file lists something to fetch, and each line says when. None of them carries a credential.- GET https://{domain}/.well-known/poppy.json, on every scanned domain. (T0-01)
- GET https://{www or apex sibling}/.well-known/poppy.json, when the requested host has no file and its homepage resolved to the sibling. (T0-SIB)
- GET the issuer's RFC 8414 metadata URL, when the file names an issuer. (T0-09)
- GET each listed OpenAPI document, when the file lists OpenAPI documents, at most 3. (T0-17)
- GET each MCP server's RFC 9728 metadata, when the file lists MCP servers, at most 3. (T0-18)
- GET each other domain in poppy_domains: /.well-known/poppy.json, when the issuer binding holds and the issuer lists other domains, at most 3. (X-04)
Tier 1: junk requests to the endpoints the file lists
Tier 1 probes run only when the request that starts the scan asks for them. Ora's scan page and report rescans on ora.ai ask for them, as do a check rerun in Ora Studio (only on the organization's own domain) and a debugging tool Ora's engineers run by hand. Any caller of Ora's scan API can ask for them too. Scans that do not ask never send them, and the MCP tools, scheduled jobs and bulk scans never ask. Each request below carries no valid credential, and a correct site refuses all of them. A probe follows a redirect only once, and only a 307 or 308 that stays on the same registrable domain. That second request counts toward the request cap.- POST to the token endpoint in the issuer's metadata, when the file names an issuer whose metadata has a token endpoint. It carries a JWT bearer grant with an assertion nobody signed, and client_id https://ora.ai/poppy/probe-client.json. A correct site answers invalid_client (401), invalid_grant (400) or a DPoP proof error (400). (T1-01)
- POST to one conversation endpoint that poppy.json lists for the poppy protocol (the first in alphabetical order), when the file lists one. It carries an empty JSON body and no token. A correct site answers 401 with a DPoP challenge. (T1-03)
- POST to one MCP server that poppy.json lists (the first in alphabetical order), when the file lists one. It carries an MCP initialize request and no token, skipped when the scan already saw this server answer 401. A correct site answers 401 with a WWW-Authenticate challenge that points at the server's RFC 9728 metadata, or a 401 when that metadata is published at the well-known URI. (T1-05)
- POST to web.browser_session_endpoint in poppy.json, when the file lists one. It carries a form body with a browser assertion nobody signed. A correct site answers 400 and no cookie (a CDN or load balancer cookie, or one the response clears, does not count). (T1-07)
- GET to the operations endpoint, with a made up operation id, when the file advertises the operations extension. It carries no token. A correct site answers 401. (T1-09)
Tier 2 and Tier 3: coming
Tier 2a will run only on a PAP domain whose poppy.json passes discovery and the issuer binding. It will run at most once per domain per 24 hours, with valid requests only, and owners can opt out. Tier 2b will run only for verified owners who opt in. Tier 3 needs a test account from the company and a person at the keyboard, so Ora does not run it on its own.Limits today
- A probe round per target domain at most once every 6 hours.
- At most 6 requests per round.
- Fetches of other domains named in poppy_domains are capped at 4 per host every hour.
- A budget of 10 seconds for all PAP work in one scan.