# How Onto works · Content negotiation for the agent web
> One URL, two faithful responses: your page to people, Markdown to AI agents. Standard content negotiation, not cloaking — shown on Onto's own site.

**Source:** /how-it-works
**Extracted:** 2026-09-24T18:14:20.297Z

---
How it works

## One URL. Two faithful answers.

Onto doesn't build you a second website. When a page is asked for, it looks at who's asking and answers in the format they can use — your page to a person, Markdown to an AI agent. Here it is on our own site.

[Get started](https://app.buildonto.dev/signup) [Scan your site](/scanner)

`Accept: text/html`79.4 KBa person

`Accept: text/markdown`5.7 KBan agent

buildonto.dev/pricing, fetched both ways on 24 Sep 2026. Same URL, same facts.

14×

lighter for agents, on our own page

1

URL for both

0

changes to your pages

The mechanism

### Three checks pick the answer.

Before anything is served, the middleware reads the User-Agent, the Accept header and the URL. Any one says Markdown, and Markdown goes back. Pick a visitor: every answer here was fetched from our own pricing page.

Who's asking

ChromepageUser-Agent: Chrome/128GooglebotpageUser-Agent: Googlebot/2.1GPTBotMarkdownUser-Agent: GPTBot/1.2ClaudeBotMarkdownUser-Agent: ClaudeBot/1.0curlMarkdownUser-Agent: curl/8.7.1Accept: text/markdownMarkdownAccept: text/markdown?ontoMarkdownGET /pricing?onto

`GET buildonto.dev/pricing`_24 Sep 2026_

**Markdown, 5,841 bytes.** On the list, one of 42 names the SDK knows. It gets the Markdown, and x-onto-bot says who it took it for.

`curl -s -o /dev/null -D - -A "GPTBot/1.2" https://buildonto.dev/pricing`

HTTP/2 200
content-type: text/markdown; charset=utf-8
cache-control: no-store, must-revalidate
vary: User-Agent, Accept
x-onto-bot: GPTBot (OpenAI)
x-onto-matched: true

Not cloaking

This is HTTP content negotiation, the way an API hands JSON to one client and HTML to another. The Markdown is built from the page itself at deploy, so both answers say the same thing.

It goes out `no-store` with `Vary: User-Agent, Accept`, so no cache hands it to a person.

Fetched from buildonto.dev/pricing on 24 Sep 2026, headers trimmed.

The payload

### What an agent actually receives.

Our own pricing page, as GPTBot gets it — 5.7 KB of Markdown instead of 79.4 KB of HTML. It's rebuilt at every deploy; the Extracted line says which one.

`curl -s -o /dev/null -D - -A "GPTBot/1.2" https://buildonto.dev/pricing`

HTTP/2 200
content-type: text/markdown; charset=utf-8
vary: User-Agent, Accept
x-onto-bot: GPTBot (OpenAI)
x-onto-matched: true
cache-control: no-store, must-revalidate

`x-onto-bot` names the agent the SDK recognised. `vary` tells every cache that the same URL has two answers.

`/.onto/pricing.md`_5,841 bytes_

1\# Pricing · Onto2\> Read API tiers, credit packs, and Serve plans. Free forever for the first 1,000 credits. No card required to start.3 4\*\*Source:\*\* /pricing5\*\*Extracted:\*\* 2026-09-04T20:32:43.305Z6 7\---8Pricing9 10\## Two products. \_Two different meters.\_…the page, as Markdown

Every step

### Four trips through Onto.

What happens at your build, at an agent's visit, at a read and at a tool call — step by step. Watch them, or click a step.

Serve SDK · buildYour buildServe SDKAn agent visits your siteRead APIYour code reads a pageMCPYour agent reads a page

your build · @ontosdk/next

Your CI runs next build && onto-next

1.  01Find the pages
    
    Every prerendered page under `.next/server/app`. Routes rendered per request get no `.md`.
    
2.  02Clean each one
    
    The same `@ontosdk/core` cleaner the Read API uses — once per build, not once per request.
    
3.  03Write the files
    
    One `.md` per route in `public/.onto/`, and `llms.txt` from your `onto.config.ts`.
    
4.  04Send the list to your dashboard
    
    Posted with your site key — only when `ONTO_API_KEY` is set. That's what fills Serve → Routes.
    

public/.onto/\*.md, public/llms.txt, and your dashboard's route list

your edge · @ontosdk/next

GPTBot asks yoursite.com for /pricing

1.  01Who's asking
    
    A known AI crawler's User-Agent, an `Accept: text/markdown` header, or `?onto` on the URL.
    
    *   `a person`→straight through to your page — nothing changes
    *   `an agent`→carry on
    
2.  02Note the visit
    
    Sent to your dashboard without waiting, so it never slows the answer.
    
3.  03Hand over the Markdown
    
    Built from your pages at deploy time and served from your own site — nothing is extracted per request.
    
4.  04Add your context
    
    Notes you've written for the route, on Serve Pro and above.
    

Markdown for the agent, your page for everyone else

api.buildonto.dev

POST /v1/read { url }

1.  01Check the key
    
    Looked up by its hash — Onto never keeps the key itself.
    
2.  02Take a credit
    
    From your month's credits. A failed read is refunded.
    
3.  03Look in the cache
    
    Kept for an hour. `"fresh": true` skips it.
    
    *   `hit`→answer from the cache
    *   `miss`→carry on
    
4.  04Check the address
    
    Public hosts only, checked again on every redirect.
    
5.  05Read robots.txt
    
    If it shuts out GPTBot or every crawler, Onto stops before fetching.
    
6.  06Fetch the page
    
    15 seconds, up to 5 redirects, 10 MB at most, no JavaScript run.
    
7.  07Clean it
    
    Through `@ontosdk/core` — the same cleaner the Serve SDK runs at build.
    
8.  08Score it
    
    An AIO score, returned by `/v1/score` and `/v1/read-and-score`.
    
9.  09Answer
    
    Cached, logged, and sent back.
    

JSON — or raw Markdown with Accept: text/markdown

your client → api.buildonto.dev/mcp

You ask Claude, ChatGPT or Cursor about a page

1.  01You ask
    
    Your agent has no reader of its own for the page, so it looks at the tools it has.
    
2.  02It picks a tool
    
    One of Onto's six — here `read_url` and the URL.
    
3.  03The call reaches Onto
    
    Over the connector URL, signed in with your Onto account — or through the local `npx` server with a key.
    
4.  04The API call runs
    
    Each tool calls its `/v1` endpoint, so the credits are the API's, charged once.
    
5.  05Markdown comes back
    
    The agent reads the clean page and answers from it.
    

Clean Markdown in the chat, billed like any API call

The stack

### Six pieces, two layers.

Read is what developers call; Serve is what site owners install. Underneath both is one package, @ontosdk/core. Point at a piece to see which of its parts it runs on.

**Read**Developers call it_Live_

[

#### Read API

Any URL as clean Markdown, with an AIO score when you want one. 1 credit a read, failed reads refunded, results cached for an hour.

`stripe.com/pricing · 699 → 17 KB`cleanerscorer](/read-api)[

#### MCP server

The same endpoints as six tools in Claude, ChatGPT, Cursor, Codex and any MCP client.

`6 tools · OAuth or npx`cleanerscorer](/mcp-server)[

#### Free scanner

Any page, scored: every fault named, the Markdown an agent gets, and a full report you can save.

`8 checks · no signup`cleanerscorer](/scanner)

**Serve**Site owners install it_Live_

[

#### @ontosdk/next

Next.js 14+, App Router. At build it writes a Markdown copy of every prerendered page and your llms.txt.

`npm i @ontosdk/next`cleaner](/serve-sdk#install)[

#### The middleware

Agents get the prebuilt Markdown from your own site; everyone else, Googlebot included, gets the page.

`User-Agent · Accept · ?onto`agent list](/serve-sdk#how)[

#### Serve dashboard

Every agent visit the SDK answers: which agent, which page, how much lighter. Pro adds a year of history and context per route.

`needs ONTO_API_KEY`agent list](/serve-sdk#control)

`@ontosdk/core`One engine under all six

**The cleaner**HTML in, Markdown out

**The scorer**The 0–100 AIO score

**The agent list**42 names · Googlebot isn't one

Where data lives

### Four places, and what's in each.

No crawl archive, no copies of the pages you read beyond an hour's cache — and your API keys only ever as a hash.

*   Your accountEmail and password, GitHub or Google sign-in
*   API keysOnly a SHA-256 hash and the first 12 characters
*   Sites and routesYour sites, their keys, and the list of routes the SDK built
*   Agent visits and usageWhat the dashboard's analytics and Usage pages show
*   Plans and creditsSubscriptions, and a credit balance with its ledger

*   Credits and slotsThis month's count and your concurrent requests
*   The Markdown cacheOne hour, then gone
*   MCP sign-insClients, one-time codes and refresh tokens

*   Checkout and billingWebhooks keep the plans above in step

*   public/.onto/\*.mdWhat agents are actually served

What's next

### When agents stop reading and start acting.

Reading the web cleanly is the first step; serving it cleanly is the second. Acting on it is the third — and it isn't built yet.

Layer 03 · Act _Next · not built yet_

#### Agents that do things, not just read.

Everything above exists to make a page legible to a machine. Act is meant to make it _usable_ by one: an agent getting things done on a site by intent, using the same understanding of a page that Read and Serve already build.

It isn't built. The roadmap has it as next, and says so.

[See the roadmap](/roadmap)

Try it

### See the fork on your own site.

Free scan, no signup. It shows exactly what an agent gets from your page today.

[Get started](https://app.buildonto.dev/signup) [Scan your site](/scanner)

---
## Structured Data (JSON-LD)
```json
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://buildonto.dev/#org",
      "name": "Onto",
      "url": "https://buildonto.dev",
      "logo": "https://buildonto.dev/icon.png",
      "sameAs": [
        "https://x.com/buildonto",
        "https://github.com/ravixalgorithm/ontosdk"
      ]
    },
    {
      "@type": "WebSite",
      "@id": "https://buildonto.dev/#site",
      "url": "https://buildonto.dev",
      "name": "Onto",
      "publisher": {
        "@id": "https://buildonto.dev/#org"
      }
    },
    {
      "@type": "SoftwareApplication",
      "name": "Onto",
      "applicationCategory": "DeveloperApplication",
      "operatingSystem": "Web",
      "url": "https://buildonto.dev",
      "description": "Onto serves AI agents clean Markdown from your own site, at the same URL, and shows you which agents came. Plus the AIO score, a Read API and an MCP server.",
      "publisher": {
        "@id": "https://buildonto.dev/#org"
      },
      "offers": {
        "@type": "Offer",
        "price": "0",
        "priceCurrency": "USD",
        "description": "Free tier: 1,000 credits / month"
      }
    }
  ]
}
```
