/.well-known/api-catalog
RFC 9727 publishes a machine-readable index of the APIs and resources a host exposes. Served as a Linkset (RFC 9264) JSON document, discoverable via the api-catalog link relation.
What it is
/.well-known/api-catalog is an IETF-standardised path at which an organisation publishes a machine-readable catalogue of the APIs and structured resources its host exposes. The document is a Linkset (RFC 9264) — a JSON array of link relations grouped by an anchor URL.
GET /.well-known/api-catalog HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/linkset+json; charset=utf-8
{
"linkset": [
{
"anchor": "https://example.com/",
"describedby": [
{ "href": "https://example.com/llms.txt", "type": "text/markdown" }
],
"alternate": [
{ "href": "https://example.com/rss.xml", "type": "application/rss+xml" }
],
"sitemap": [
{ "href": "https://example.com/sitemap-index.xml", "type": "application/xml" }
],
"license": [
{ "href": "https://creativecommons.org/licenses/by/4.0/" }
]
}
]
}
The path is registered in the IANA Well-Known URIs Registry by RFC 9727 — unlike many AI-era conventions, this one is standards-track.
Why it matters
- One predictable fetch surfaces every machine-readable resource. Agents that obey
/.well-known/api-catalogget a typed list of feeds, sitemaps, llms.txt, OpenAPI specs, terms of service, licence URLs — without scraping HTML. - Pairs with the
Linkheader. AdvertiseLink: </.well-known/api-catalog>; rel="api-catalog"and the agent never has to guess the path. See HTTP Link headers. - Standards-track. RFC 9727 (May 2024) is final, not a draft. The IANA registration anchors the path.
- Cheap to ship. A small static JSON file.
How to implement
Serve a Linkset. RFC 9727 requires the response body to be a valid Linkset. The media type is application/linkset+json. Set the Content-Type accordingly — most static hosts default to application/octet-stream for files without an extension.
Each linkset entry has an anchor (the resource the links describe) and one or more relation-keyed arrays. Useful relations:
describedby— a description of the anchor (llms.txt, OpenAPI).service-desc— a machine-readable description of an API (OpenAPI, AsyncAPI).service-doc— a human-readable description of an API.alternate— alternative representations of the anchor’s content.sitemap— sitemap covering the anchor.license,author,terms-of-service— metadata.status— status / health endpoint.
Advertise it. Add the catalogue to your HTTP Link header on every response:
Link: </.well-known/api-catalog>; rel="api-catalog"; type="application/linkset+json"
This is what makes the path discoverable without an out-of-band hint.
Update it when the surface changes. A drifted catalogue is worse than no catalogue. CI should validate it on every change to the public resources it describes.
Keep it small. Catalogues are typically a few KB. Linksets are flat — there is no recursion to follow.
Common mistakes
- Returning the catalogue with
Content-Type: application/json(ortext/plain). It must beapplication/linkset+jsonfor RFC 9727 to apply; agents that strictly type-check will skip it otherwise. - Inventing relation names. Use only those in the IANA Link Relations Registry.
- Wrapping the catalogue inside an authentication wall. The whole point is unauthenticated discovery.
- Forgetting to keep it in sync with
/llms.txt,/sitemap-index.xml, and the<link>tags in HTML. They are different surfaces for the same statement of fact. - Pairing it with
Link: </.well-known/api-catalog>; rel="describedby". The correct relation isapi-catalog— that registration is what RFC 9727 added.
Verification
curl -sI https://example.com/.well-known/api-catalogreturns200withContent-Type: application/linkset+json.- The body parses as JSON and matches the Linkset schema (RFC 9264 §4).
- Is It Agent Ready? flips
discovery.apiCatalogtopass. - Every URL the catalogue points at returns
200from the same origin.