1. Abstract
Publish an API catalog for automated public API discovery using RFC 9727 when this origin exposes public APIs.
API catalogs help agents find API endpoints, service descriptions, documentation, status resources, auth metadata, and related machine-readable contracts without guessing entry points.
2. Classification
- Check ID
- api-catalog
- Check version
- 1.0.0
- Package path
- lib/checks/api-catalog/versions/1.0.0
- Category
- Agent Ease of Use
- Subcategory
- API
- Check group
- API Discovery
- Check group ID
- api-discovery
- Maturity
- Established
- Scope
- site
- Check weight
- 1
3. Input And Output Contracts
- Input
- [email protected]
- Output
- [email protected]
- Resources inspected
- /.well-known/api-catalog
4. Scoring Semantics
| Step ID | Title | Weight | Description |
|---|---|---|---|
applicability | Decide whether API catalog applies | 0.1 | Detect public API, developer documentation, OpenAPI, API catalog, or community API discovery signals. |
discover-catalog | Fetch API catalog | 0.2 | Fetch GET /.well-known/api-catalog and record status, final URL, and HTTPS. |
head-link | Check API catalog HEAD Link header | 0.1 | Validate the RFC 9727 HEAD discovery signal where available. |
media-type | Validate API catalog media type | 0.15 | Require application/linkset+json and inspect the recommended RFC 9727 profile parameter. |
linkset-shape | Validate Linkset shape | 0.2 | Parse JSON and validate linkset array, relation arrays, target objects, and href values. |
api-relations | Classify API catalog relations | 0.15 | Classify RFC 9727, RFC 8631, adjacent, community, and legacy relations. |
target-validation | Validate API catalog targets | 0.2 | Fetch same-origin targets and classify same-site/external targets without requiring all APIs to be same-origin. |
security-review | Review catalog target safety | 0.1 | Flag private hosts, localhost, credentials in URLs, and internal/admin-looking target paths. |
5. Package Documentation
API Catalog Check v1.0.0
Status
- Version:
1.0.0 - Check identifier:
api-catalog - Input contract:
[email protected] - Output contract:
[email protected] - Scope: site
- Maturity: established
Abstract
This check validates RFC 9727 API catalog discovery for origins that publish or claim public APIs. It fetches /.well-known/api-catalog, validates the application/linkset+json Linkset representation, classifies API discovery relations, checks same-origin advertised targets, records same-site and external targets, and warns about risky public target URLs.
The check is applicability-aware. Ordinary websites with no public API signal do not need an API catalog and should return not_applicable when the well-known resource is absent.
Motivation
Public API publishers often expose API descriptions, documentation, auth metadata, status resources, and API endpoints across several URLs or domains. Without a catalog, automated clients and agents have to guess common paths such as /openapi.json, /swagger.json, /docs, or /api.
RFC 9727 gives API publishers a standard discovery location and relation type: /.well-known/api-catalog and rel="api-catalog". A Linkset catalog lets clients find endpoints and supporting metadata without scraping a developer portal.
Normative Model
This version follows:
- RFC 9727 for the
api-catalogwell-known URI and link relation. - RFC 9264 for the
application/linkset+jsondocument shape. - RFC 8288 for web linking semantics and relation processing.
- RFC 8631 for
service-desc,service-doc,service-meta, andstatus. - RFC 8615 for well-known URI deployment.
Normative expectations used by the check:
- API catalog discovery uses root-level
/.well-known/api-catalog. - Publishers that support the well-known URI should support HTTPS
GET. - Publishers should also support
HEADwith a usefulLinkheader. - The baseline representation is
application/linkset+json. - A top-level
linksetarray is required. - Relation members should be arrays of target objects.
- Target objects need
href. - Registered API/service relations are stronger evidence than community
conventions.
- Distributed APIs may link to same-site or external targets; external targets
are recorded but not fetched by this origin-scoped check.
Applicability
The check applies when public evidence suggests the origin publishes APIs or claims API catalog support:
/.well-known/api-catalogreturns HTTP 200.- Homepage
Linkheaders containrel="api-catalog"orrel="api". - Homepage HTML mentions API catalog, OpenAPI, Swagger, API reference, REST API,
GraphQL API, developer portal, /openapi.json, /swagger.json, or /apis.json.
The check is not applicable when:
/.well-known/api-catalogis absent and no public API signal is visible.- The site appears to be an ordinary marketing, editorial, ecommerce, local
business, or portfolio website with no public API/developer documentation.
- The site exposes only browser app routes, forms, or private/authenticated app
functionality.
Pass Criteria
The check passes when:
- Applicability is established by a found catalog or visible public API signal.
GET /.well-known/api-catalogreturns HTTP 2xx.- The final catalog URL is HTTPS.
- The response is
application/linkset+json. - The response includes the RFC 9727 profile parameter when possible.
- JSON parses successfully.
- The document contains a non-empty top-level
linksetarray. - Relation members are arrays of target objects.
- Target objects include valid HTTP(S) or relative
hrefvalues. - The catalog uses API-relevant relations such as
api-catalog,item,
service-desc, service-doc, service-meta, or status.
- Same-origin advertised targets return 2xx/3xx and compatible content types.
- The catalog does not expose localhost, private-network, credential-bearing, or
internal/admin-looking targets.
Warning Criteria
Warnings include:
- public API signals are visible but
/.well-known/api-catalogis absent - the catalog is reachable but uses a compatible generic JSON content type rather than
application/linkset+json - the RFC 9727 profile parameter is missing while the Linkset shape is otherwise valid
HEADsupport orLinkheader discovery evidence is incomplete- the catalog contains only weak, adjacent, community, or legacy API relations
- advertised targets are external or same-site and therefore not actively fetched by this version
- same-origin targets are reachable but use generic content types
Failure Criteria
Failures include:
- the site claims a public API catalog but no catalog can be fetched
GET /.well-known/api-catalogfails when applicability is established- the final catalog URL is not HTTPS
- the response is not JSON-compatible or cannot be parsed
- the document lacks a non-empty top-level
linksetarray - relation members are not arrays of target objects
- target objects are missing valid
hrefvalues - no API-relevant relations are present
- same-origin advertised targets fail to resolve or return incompatible content
- catalog targets expose localhost, private-network, credential-bearing, internal, or admin-looking URLs
Evidence Model
The check emits step-level evidence:
- Applicability signals from homepage headers and HTML.
- Requested API catalog URL.
- Final URL and HTTPS status.
- HTTP
GETstatus. - HTTP
HEADstatus andLinkheader summary. - Response
Content-Typeand RFC 9727 profile presence. - Cache headers.
- JSON parse status.
- Linkset item count.
- Link target count.
- Relation summary:
api-cataloganditemservice-desc,service-doc,service-meta, andstatus- adjacent auth/agent relations
- community relations such as
api - legacy underscore relations
- unknown relations
- Target validation summary:
- relation
href- resolved URL
- same-origin, same-site, or external classification
- advertised type
- same-origin status and content type when fetched
- type compatibility
- Security flags for private/internal hosts, credentials in URLs, and
internal/admin-looking paths.
Logs are emitted through the versioned check runtime wrapper. Logs must not include full catalog bodies, credentials, API keys, cookies, authorization headers, or large evidence blobs.
Validation/Scoring Steps
The version owns these internal steps:
applicability(0.1): decide whether the origin publishes or claims public
APIs.
discover-catalog(0.2): fetchGET /.well-known/api-catalog.head-link(0.1): checkHEAD /.well-known/api-catalogandLinkheader
discovery.
media-type(0.15): validateapplication/linkset+jsonand RFC 9727 profile
evidence.
linkset-shape(0.2): validate JSON, top-levellinkset, relation arrays,
target objects, and href.
api-relations(0.15): classify API, service, adjacent, community, legacy, and
unknown relations.
target-validation(0.2): fetch same-origin targets and classify same-site or
external targets.
security-review(0.1): flag unsafe public target URLs.
Standard Behavior
If no API catalog is found and no public API signal is visible, the result is not_applicable.
If public API signals are visible but /.well-known/api-catalog is absent, the result is warning.
If a catalog exists but is malformed, unsafe, or lacks usable API discovery links, the result is fail.
If a catalog exists but is partially non-standard, such as generic JSON, missing RFC 9727 profile, missing HEAD Link discovery, external-only targets, or weak/community relations, the result is warning.
If a catalog is valid and same-origin targets are reachable with compatible media types, the result is pass.
Non-Standard and Real-World Behavior
Many API publishers expose /openapi.json, /swagger.json, Swagger UI, Redoc, Scalar API references, developer portals, or /apis.json without an RFC 9727 catalog. This version treats those as applicability or community signals, not as full substitutes for /.well-known/api-catalog.
APIs are often distributed across api.example.com, developer.example.com, docs.example.com, or third-party gateway domains. This check records same-site and external targets instead of automatically failing them, but it fetches only same-origin targets.
Generic application/json is common for OpenAPI, status, and metadata targets. When a catalog advertises a specific media type, this check allows common compatibility matches for OpenAPI JSON/YAML and Markdown/plain text.
Non-Goals and Limitations
This check does not:
- Fully validate OpenAPI syntax.
- Crawl nested API catalogs recursively.
- Fetch external targets.
- Authenticate to private developer portals.
- Prove that every listed API endpoint is usable.
- Validate API auth, OAuth, MCP, agent-card, or status-resource schemas in depth.
- Infer public API availability from bundled JavaScript alone.
- Treat every website as required to publish an API catalog.
References
- www.rfc-editor.org/rfc/rfc9727
- www.rfc-editor.org/rfc/rfc9264
- www.rfc-editor.org/rfc/rfc8288
- www.rfc-editor.org/rfc/rfc8631
- www.rfc-editor.org/rfc/rfc8615
- www.iana.org/assignments/well-known-uris/well-known-uris.xhtml
- www.iana.org/assignments/link-relations/link-relations.xhtml
- spec.openapis.org/oas/latest.html
- apisjson.org/format/apisjson_0.19.txt
- www.rfc-editor.org/rfc/rfc9727.html
- www.rfc-editor.org/rfc/rfc9264.html
- www.rfc-editor.org/rfc/rfc8288.html
- www.rfc-editor.org/rfc/rfc8631.html
- www.rfc-editor.org/rfc/rfc8615.html
- www.iana.org/assignments/media-types/application/linkset+json
Source: lib/checks/api-catalog/versions/1.0.0/docs.md
6. Version Changelog
api-catalog v1.0.0 Changelog
- Added applicability-aware behavior: missing catalogs are
not_applicable
unless public API or API catalog signals are visible.
- Added RFC 9727
GETdiscovery,HEADLink header validation,
application/linkset+json media type validation, and RFC 9727 profile checking.
- Added Linkset shape validation, relation classification, same-origin target
validation, same-site/external target recording, and public target safety review.
- Expanded versioned documentation with standards, applicability, evidence,
pass/warning/fail boundaries, real-world behavior, and limitations.
Source: lib/checks/api-catalog/versions/1.0.0/changelog.md