Status: Draft Authors: Leon Ting (@LeonTing1010) Repository: github.com/LeonTing1010/agents-json Last updated: 2026-04-07
agents.json is a Schema.org JSON-LD document that websites publish to declare how AI agents should interact with them. It uses standard Schema.org types — the same vocabulary Google already indexes for rich search results.
No new vocabulary. No new standard. Just Schema.org WebAPI + potentialAction — types that Google, Bing, and every major search engine already understand.
Getting websites to adopt a new file format is nearly impossible. But 35% of websites already publish Schema.org JSON-LD for Google SEO benefits (rich snippets, sitelinks search box, knowledge panels).
agents.json rides on this existing infrastructure:
| Approach | Adoption | Indexed by Google |
|---|---|---|
| Custom JSON format | ~0% (must evangelize) | No |
| Schema.org JSON-LD | ~35% already have it | Yes |
Website owners already have motivation to publish Schema.org data — it improves their search rankings. agents.json gives them a reason to describe their APIs using the same mechanism.
Agents discover structured data through existing web standards, in priority order:
<script type="application/ld+json"> in any page’s <head>. Already published by 35% of websites for SEO. Google indexes this.GET /.well-known/agents.json with Content-Type: application/ld+json. 3-second timeout.<link rel="describedby" type="application/ld+json" href="/.well-known/agents.json"> in HTML or HTTP Link header.<url><loc>/.well-known/agents.json</loc></url> in sitemap.xml.If none found, fall back to page inspection (the capture meta verb).
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "Hacker News",
"url": "https://news.ycombinator.com",
"description": "Tech news aggregator with community voting"
}
This is a valid agents.json. Google already indexes this format for sitelinks. Agents use name and description for intent matching.
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "Hacker News",
"url": "https://news.ycombinator.com",
"description": "Tech news aggregator with community voting",
"potentialAction": {
"@type": "SearchAction",
"target": {
"@type": "EntryPoint",
"urlTemplate": "https://hn.algolia.com/api/v1/search?query={search_term_string}",
"httpMethod": "GET",
"contentType": "application/json"
},
"query-input": "required name=search_term_string"
}
}
This is the exact format Google uses for the sitelinks search box. Already supported by WordPress/Yoast, Shopify, and most CMS platforms.
{
"@context": "https://schema.org",
"@type": "WebAPI",
"name": "Hacker News",
"description": "Tech news aggregator with community voting",
"url": "https://news.ycombinator.com",
"documentation": "https://github.com/HackerNews/API",
"termsOfService": "https://www.ycombinator.com/legal#tou",
"provider": {
"@type": "Organization",
"name": "Y Combinator",
"url": "https://www.ycombinator.com"
},
"potentialAction": [
{
"@type": "ReadAction",
"name": "top-stories",
"description": "Front page stories ranked by score",
"target": {
"@type": "EntryPoint",
"urlTemplate": "https://hacker-news.firebaseio.com/v0/topstories.json",
"httpMethod": "GET",
"contentType": "application/json"
},
"object": {
"@type": "ItemList",
"itemListElement": {
"@type": "ListItem",
"additionalProperty": [
{ "@type": "PropertyValue", "name": "id", "description": "Story ID", "valuePattern": "[0-9]+" },
{ "@type": "PropertyValue", "name": "title", "description": "Story title" },
{ "@type": "PropertyValue", "name": "url", "description": "Link URL" },
{ "@type": "PropertyValue", "name": "score", "description": "Upvote count", "valuePattern": "[0-9]+" },
{ "@type": "PropertyValue", "name": "by", "description": "Author username" },
{ "@type": "PropertyValue", "name": "time", "description": "Unix timestamp", "valuePattern": "[0-9]+" }
]
}
}
},
{
"@type": "ReadAction",
"name": "new-stories",
"description": "Newest stories in chronological order",
"target": {
"@type": "EntryPoint",
"urlTemplate": "https://hacker-news.firebaseio.com/v0/newstories.json",
"httpMethod": "GET",
"contentType": "application/json"
}
},
{
"@type": "SearchAction",
"name": "search",
"description": "Full-text search across all stories",
"target": {
"@type": "EntryPoint",
"urlTemplate": "https://hn.algolia.com/api/v1/search?query={search_term_string}&tags=story",
"httpMethod": "GET",
"contentType": "application/json"
},
"query-input": "required name=search_term_string"
},
{
"@type": "CreateAction",
"name": "submit-story",
"description": "Submit a new story to Hacker News",
"target": {
"@type": "EntryPoint",
"urlTemplate": "https://news.ycombinator.com/submit",
"httpMethod": "POST",
"encodingType": "application/x-www-form-urlencoded"
},
"object": {
"@type": "CreativeWork",
"additionalProperty": [
{ "@type": "PropertyValue", "name": "title", "description": "Story title (required)", "valueRequired": true },
{ "@type": "PropertyValue", "name": "url", "description": "Link URL (optional)" },
{ "@type": "PropertyValue", "name": "text", "description": "Text body (optional)" }
]
}
}
]
}
Use WebSite for simple sites. Use WebAPI when the site exposes API endpoints.
| Type | When to use | Google indexes? |
|---|---|---|
WebSite |
Any website (name, description, search) | Yes — sitelinks, search box |
WebAPI |
Sites with API endpoints (extends Service) | Yes — as Service |
Both support potentialAction for declaring what agents can do.
Each action in potentialAction[] represents one thing an agent can do.
| Action Type | Schema.org Type | HTTP Method | Example |
|---|---|---|---|
| Read data | ReadAction |
GET | Fetch trending stories |
| Search | SearchAction |
GET | Full-text search |
| Create | CreateAction |
POST | Submit a new post |
| Update | UpdateAction |
PUT/PATCH | Edit a comment |
| Delete | DeleteAction |
DELETE | Remove a post |
Action properties:
| Property | Type | Required | Description |
|---|---|---|---|
@type |
string | yes | Schema.org action type |
name |
string | yes | Machine identifier (e.g. "top-stories") |
description |
string | yes | What this action does |
target |
EntryPoint | yes | How to invoke it |
object |
Thing | no | Input/output schema |
query-input |
string | no | For SearchAction: parameter binding (Google format) |
Describes how to reach an endpoint.
| Property | Type | Required | Description |
|---|---|---|---|
@type |
string | yes | "EntryPoint" |
urlTemplate |
string | yes | URL with RFC 6570 placeholders: https://api.example.com/items/{id} |
httpMethod |
string | no | GET, POST, PUT, DELETE. Default: GET |
contentType |
string | no | Response MIME type. Default: application/json |
encodingType |
string | no | Request body encoding |
Describe input/output fields using Schema.org PropertyValue inside additionalProperty:
| Property | Type | Description |
|---|---|---|
name |
string | Field name |
description |
string | Human-readable description |
valueRequired |
boolean | Is this field required? |
valuePattern |
string | Regex validation pattern |
defaultValue |
string | Default value |
minValue / maxValue |
number | Numeric bounds |
agents.json is a strict superset of what Google already indexes:
| Google Feature | Schema.org Type | agents.json extends with |
|---|---|---|
| Sitelinks search box | WebSite + SearchAction |
More action types (Read, Create, Update) |
| Knowledge panel | Organization + WebSite |
API endpoint details |
| Rich snippets | Article, Product, etc. |
Machine-actionable endpoints |
| Breadcrumbs | BreadcrumbList |
— (orthogonal) |
A valid agents.json is always valid Schema.org JSON-LD. Google will index it. No special handling needed.
What 35% of sites have now: What agents.json adds:
───────────────────────────── ──────────────────────────
WebSite.name WebAPI (@type upgrade)
WebSite.description ReadAction (data endpoints)
SearchAction (sitelinks) CreateAction (write operations)
EntryPoint.httpMethod
PropertyValue (field schemas)
The transition is incremental: websites keep their existing JSON-LD, add potentialAction entries for their API endpoints.
Step 1: You probably already have this. Check if your site has <script type="application/ld+json"> in the <head>. Most CMS platforms (WordPress, Shopify, etc.) add it automatically.
Step 2: Add API endpoints. Upgrade @type from WebSite to WebAPI, add potentialAction entries for your public endpoints.
Step 3: Publish at well-known URL. Copy the JSON-LD to /.well-known/agents.json for direct agent discovery.
/.well-known/agents.json (3-second timeout)<script type="application/ld+json"> from the pagepotentialAction with EntryPoint targetsurlTemplate + httpMethod to call endpoints directly# capture automatically consumes agents.json during inspection
tap capture https://news.ycombinator.com hackernews/hot --intent "trending stories"
# → capture finds agents.json → uses ReadAction endpoint directly
# After capturing, you can author an agents.json file for the site
# (Schema.org JSON-LD that the site owner can publish — see Examples §)
Q: How is this different from OpenAPI? A: OpenAPI describes every endpoint in exhaustive detail (often thousands of lines). agents.json describes the 3-5 most useful actions in under 50 lines using Schema.org vocabulary. Think of it as the TL;DR for agents — and Google indexes it.
Q: Do I need a new file?
A: No. You can embed agents.json as JSON-LD directly in your HTML <head> — the same place you put Schema.org data for SEO. Google indexes it from there.
Q: Will Google actually index the WebAPI/ReadAction parts? A: Google indexes all valid Schema.org JSON-LD, even types it doesn’t render as rich results yet. The data is in Google’s Knowledge Graph. As AI agents become first-class search consumers, this data will matter more.
Q: What about robots.txt? A: robots.txt and agents.json are complementary. robots.txt restricts crawling. agents.json declares API interfaces. An agent should respect both: don’t crawl disallowed paths, but do use declared API endpoints.
Q: Can I validate my agents.json? A: Yes — use Google’s Rich Results Test or Schema.org Validator. Any valid agents.json passes both.