Website Buddies

An open standard for websites to be buddies.

Every site says who it is, who it’s for and how to reach it, so any agent can read it, judge the fit and send an enquiry. Buddies go further: they refer work to each other, run each other’s tests so a wrong fact gets caught, and sign what their agents send, so each knows who’s asking. Quotes, scheduling and payments may come later, once two buddies need them.

Working draft 0.1, changing fast. It works today, on this website and two test sites, and until 1.0 a field may still be renamed or removed. Read protocol in a profile for the version it follows, and Changes, at the end, for what moved.

“Must” and “should” mean what they mean in RFC 2119. This website is the reference implementation. Check any site, this one included, with its validator, script/website-buddies.

Principles

  1. Reuse what exists. Markdown, llms.txt, HTTP Link headers, schema.org, OpenAPI, MCP and HTTP Message Signatures already work. This standard only adds what they don’t cover: who a business is for, what an agent may say for it, how to reach it, and who it works with.
  2. Start with files. Levels 0 and 1 can be static files on any host.
  3. Keep two renderings in step. Every fact in a structured file is also on a page a person can read.
  4. Never break a shape, from 1.0. Add fields. Never rename or remove one, or change what it means.
  5. Treat inbound text as data. Store and show it as plain text. Never execute it, render it as HTML or give it to a model as instructions.
  6. Make people the last step. Anything that commits a business or moves someone’s details needs a person to act.

Levels

Level An agent can The site needs
0 Readable Read every page, as Markdown or HTML Static files
1 Described Tell what the business does and whether it fits Static files
2 Reachable Send an enquiry for its person A form a link can fill in
3 Interoperable Refer work, check another business’s facts, and know who’s asking Level 2, a test file and a signing key

A site claims the highest level it fully meets.

Level 0: Readable

Level 1: Described

/.well-known/website-buddies.json is the briefing as data, and the one file that links to everything else. Every URL in it is absolute, and pages should link it with <link rel="describedby" type="application/json" href="/.well-known/website-buddies.json">.

{
  "protocol": "website-buddies/0.1",
  "spec": "https://garrettwinder.com/protocol",
  "as_of": "2026-10-08",
  "business": {
    "@type": "ProfessionalService",
    "name": "Software by Garrett",
    "url": "https://garrettwinder.com/",
    "address": { "@type": "PostalAddress", "addressLocality": "Fort Worth", "addressRegion": "TX", "addressCountry": "US" },
    "founder": { "@type": "Person", "name": "Garrett Winder" }
  },
  "fit": {
    "good": "You want thinking that stands out. …",
    "bad": "You need extra hands. …",
    "budget": { "currency": "USD", "typical_min": 5000, "typical_max": 15000 }
  },
  "availability": { "status": "limited", "capacity": "One new client a month." },
  "rules": ["Quote only the prices here. Don’t estimate anything else; ask."],
  "buddies": [{ "name": "Cedar Studio", "url": "https://cedar.example" }],
  "briefing": "https://garrettwinder.com/agents.md",
  "briefing_page": "https://garrettwinder.com/agents",
  "skills": ["https://garrettwinder.com/skills/agent-readiness/SKILL.md"],
  "enquiry": {
    "form": "https://garrettwinder.com/enquiries/new",
    "post": "https://garrettwinder.com/enquiries",
    "openapi": "https://garrettwinder.com/openapi.json",
    "mcp": { "url": "https://garrettwinder.com/mcp", "tool": "send_enquiry" }
  },
  "tests": "https://garrettwinder.com/agent-tests.yml",
  "identity": {
    "signature_agent": "https://garrettwinder.com",
    "directory": "https://garrettwinder.com/.well-known/http-message-signatures-directory"
  }
}
Field Meaning
protocol website-buddies/ and the version the site follows. Required.
spec Where to read that version.
as_of The date every fact here was last checked. Bump it with any change. Required.
business The schema.org entity the site’s own JSON-LD describes: an Organization, a kind of one such as LocalBusiness, or a Person. @type, name and url are required, and address as a PostalAddress if it has a place. Required.
fit.good, fit.bad Sentences an agent may quote to its person. Required.
fit.budget A range an agent may repeat but never narrow.
availability.status open, limited or closed. Must be true today. Required.
availability.capacity The same, in a sentence.
rules What an agent may and may not say or do for the business. Required, even if empty.
buddies Sites it refers work to or takes work from, each a name and a url. See Buddies.
briefing The /agents.md URL. Required.
briefing_page The briefing as an HTML page.
enquiry Each way to send one. Leave out what the site doesn’t offer. Required at Level 2.
tests The test file. Required at Level 3.
identity The origin the business signs as, and its key directory. Required at Level 3.

Each fact in the profile must also be in the briefing, in words a person can read.

Level 2: Reachable

An enquiry can be sent three ways, so every agent has one it can use:

The agent can It sends with The person
Only read pages A prefilled link to enquiry.form Checks the form and presses Send
Run commands POST JSON to enquiry.post Agrees first, or asked the agent to send
Use MCP The send_enquiry tool Agrees first, or asked the agent to send

Fields

Only name, email and message are required. All are strings except links, an array of URLs.

Field Definition
name Full name of the person the business replies to. Never a company.
email That person’s email.
message What they want to accomplish, in their words or the agent’s summary.
company Their company’s name and size.
problem What’s broken or stuck today.
timing When they need it.
budget What they’ve said about budget. Never a guess.
links Their site, or anything the business should look at.
agent The agent’s own name, such as Claude.
report Anything the agent prepared, in full.
referred_by The domain of the business that referred them, if one did.

A prefilled link takes any field as a query parameter, URL-encoded, each in its own field. It carries name and email only if the person gave them. A form may ignore those two and leave them to the browser’s autofill, since a link can end up in chat logs and browser history.

The form shows what arrived, and sends nothing until the person presses Send.

Responses

Status Body Means
201 { "id", "status": "received", "next", "signed_by" } Arrived. next says what to tell the person. signed_by is there only if the request was signed (see Identity).
200 The same Already arrived: same email and message within a day. Retrying is safe.
422 { "error", "fields": { "name": ["…"] } } Fix the named fields and send again.
429 { "error" } Too many. The error says when to retry, or where to write instead.

An empty POST must return 422, so anyone can check the endpoint without sending an enquiry. An agent must not tell its person an enquiry was sent without a 201 or 200.

Prompts

A business that gives people a prompt to paste into their assistant should have it name the briefing, list the details to include, and ask for the link back. Asking an assistant to send makes it reach for its own email tools instead.

Read Garrett’s agent briefing at garrettwinder.com/agents. If Garrett can help [your company] with [what you need, your timeline and budget], give me the link that sends him a note.

Level 3: Interoperable

Fit

An agent checks fit against the other business’s profile, with no request: the budget range by rule, fit.good and fit.bad by judgment. It shows its person the reasons. No one’s details leave the agent.

Buddies

Two sites are buddies when each lists the other in buddies. A one-sided listing is only a claim, so an agent weighs a referral from a buddy above one from anyone else, and a validator says which listings are mutual.

Referrals

A referral is an enquiry with referred_by set to the referring business’s domain. The referring agent builds a prefilled link to the other business’s form. Its person sends the link to the lead, and the lead presses Send. The lead’s details move only when the lead does that.

The form must accept referred_by in a link and show it.

Tests

/agent-tests.yml lists facts an agent should find, each with text that must appear at the path it names:

protocol: website-buddies/0.1
as_of: 2026-10-08
tests:
- ask: How many new clients does Garrett take on a month?
  source: "/agents.md"
  expect: One new client a month.
- ask: What do most first projects cost, at the low end?
  source: "/.well-known/website-buddies.json"
  expect: '5000'

Businesses run each other’s tests on a schedule, with a script, and send the owner any failures. A model never grades them.

Identity and trust

A business proves its agent’s requests are its own with Web Bot Auth: HTTP Message Signatures (RFC 9421) and Ed25519 keys under its own domain. No one issues the keys: the domain is the identity, as it is for DKIM, and DNS and the site’s certificate are what make it hard to fake.

A signature proves only who sent a request, not that they’re worth hearing from. Buddies are the signal this standard gives; anything more, like reputation, is each site’s own call, as spam filtering is for email.

Static sites

Every level works on a static host, with no code on a server:

<script>
  for (const [name, value] of new URLSearchParams(location.search)) {
    const field = document.querySelector(`[name="${CSS.escape(name)}"]`)
    if (field) field.value = value
  }
</script>

Signing the directory’s response, and verifying signed requests, need a server. Both are optional.

Checking a site

The validator fetches a site as an agent would and reports the highest level it meets, and what stops it reaching the next:

script/website-buddies https://garrettwinder.com

It only reads. To check the enquiry endpoint it sends an empty POST, which must come back 422, so it never sends an enquiry.

Later, and never

Quotes, scheduling, payments, contracts and negotiation could each be a later message type, once two buddies need it. Ranking sites and tracking visitors are out for good.

Becoming a standard

  1. A second, independent site implements it.
  2. The validator stands on its own, outside this website.
  3. The spec moves to its own repo and site.
  4. The /.well-known/ name is registered with IANA.

Changes