AI agents and automated tools are starting to poke at websites looking for APIs. Right now they mostly guess: try /api, try /wp-json, read the HTML and hope for a link tag. There’s never been a standard place to just ask “what APIs does this site have?”
The standard
RFC 9727, published in June 2025, fixes that.1 It registers a well-known URI, /.well-known/api-catalog, as the standard front door for API discovery. Any client, human or automated, can request that one path and get back a machine-readable list of what’s available.
The response format is a linkset, defined in RFC 9264, served as application/linkset+json: a flat JSON structure with an array of entries, each anchored to an API’s base URL with links to its documentation or description.2 I built a WordPress plugin that serves one: wp-api-catalog. Here’s the catalog it returns on a test install:
{
"linkset": [
{
"anchor": "https://example.com/wp-json/oembed/1.0",
"service-desc": [
{ "href": "https://example.com/wp-json/oembed/1.0", "type": "application/json" }
]
},
{
"anchor": "https://example.com/wp-json/wp/v2",
"service-desc": [
{ "href": "https://example.com/wp-json/wp/v2", "type": "application/json" }
],
"service-doc": [
{ "href": "https://developer.wordpress.org/rest-api/reference/", "type": "text/html" }
]
}
]
}
Two entries, one per REST namespace. The wp/v2 entry also carries a service-doc link pointing at the actual WordPress REST API handbook, so a client that finds this file has both the endpoint and the documentation for it in one response.
WordPress already has the data
Every WordPress install already has the raw material for this: /wp-json/ has served a namespace index since the REST API infrastructure landed in core in 4.4, and the content endpoints followed in 4.7.3 It’s been sitting there for a decade, and almost nobody publishes it at the one location a spec-compliant client would look.

The plugin
Activate the plugin and it’s done. No settings screen, no configuration. It walks the registered REST namespaces, builds the linkset, and serves it at /.well-known/api-catalog. Here’s the response from the same install:
$ curl -k -sS -D - https://example.com/.well-known/api-catalog
HTTP/2 200
content-type: application/linkset+json
cache-control: max-age=3600
link: <https://example.com/.well-known/api-catalog>; rel="api-catalog"
RFC 9727 also allows the discovery relation to show up on other responses, not just the catalog endpoint itself, so a client that lands on any page of the site can still find it.1 This plugin adds that Link header to every front-end response:
$ curl -k -sS -I https://example.com/
link: <https://example.com/.well-known/api-catalog>; rel="api-catalog"
That cache-control header tells clients they can hold the response for an hour. Server-side, the plugin caches the built catalog for five minutes so it doesn’t rebuild on every request. One requirement worth calling out: pretty permalinks have to be turned on. With plain permalinks WordPress never consults rewrite rules, and the endpoint 404s.
Extending it
If the built-in namespace listing isn’t enough, five filters cover the rest:
wp_api_catalog_entrymodifies or drops a single namespace’s entrywp_api_catalog_linksettouches the whole document before it’s cachedwp_api_catalog_send_link_headerturns off the front-end headerwp_api_catalog_cache_ttlandwp_api_catalog_cache_typecontrol caching
wp_api_catalog_linkset is the one to reach for when an API isn’t a WordPress REST namespace at all, say a separate service running alongside the site. It appends to whatever the plugin already found:
add_filter( 'wp_api_catalog_linkset', function ( array $linkset ): array {
$linkset['linkset'][] = array(
'anchor' => 'https://external.example.com/api',
'service-desc' => array(
array(
'href' => 'https://external.example.com/openapi.json',
'type' => 'application/vnd.oai.openapi+json',
),
),
);
return $linkset;
} );
The plugin is free, GPL-2.0-or-later, no Composer dependency, no build step.
84em.com ships an llms.txt for the same reason this plugin exists: agents work better when a site hands them a structured entry point instead of making them guess.
RFC 9727: api-catalog: A Well-Known URI and Link Relation to Help Discovery of APIs ↩︎ ↩︎
RFC 9264: Linkset: Media Types and a Link Relation Type for Link Sets ↩︎
WordPress 4.4 release notes (REST API infrastructure) and 4.7 release notes (content endpoints) ↩︎









