37 Audits
πŸ—‚οΈ

AI Catalog Auditor

General Auditor

Validates a spec-compliant ARD ai-catalog.json for agent discovery

AI
150 credits
Per check
~30 seconds
Average runtime
Active
Status

How it works

The auditor resolves the site origin from the audited URL and locates ai-catalog.json:

  1. Well-known URI β€” GET {origin}/.well-known/ai-catalog.json.

  2. Agentmap fallback β€” if the well-known path is missing or returns non-JSON (for example an HTML catch-all), parse /robots.txt for an Agentmap: directive.

  3. HTML fallback β€” otherwise look for <link rel="ai-catalog" href="..."> on the audited page.

  4. Header checks β€” the catalog response should be JSON (Content-Type: application/json or a +json type) with Access-Control-Allow-Origin so crawlers can fetch it.

  5. Schema checks β€” specVersion must be 1.0; entries must be an array; each entry needs identifier, displayName, type, and exactly one of url or data; identifiers must match urn:air:<publisher>:<namespace>:<agent-name>. Nested application/ai-catalog+json data objects are checked one level deep with the same entry rules.

  6. Specification pin β€” every run emits 37A-AiCatalogAuditor-100 (INFORMATION) naming ARD v0.91 (26 Aug 2026) and ai-catalog.schema.json commit 4a8a6b8fdd3ac4a50dcb63213573159c1eed7856 (20 Jun 2026). That check does not change overall status.

  7. Aggregate β€” any failing rule makes the audit FAIL; otherwise warnings (CORS, empty entries, omitted host, representativeQueries size, invalid updatedAt) make it WARNING; otherwise SUCCESS.

A missing catalog or a JSON parse error produces a FAIL and still includes the specification pin check.

What this auditor validates

Every row maps to one checkRule* method and one CheckCode. Nested inline catalogs reuse the same entry rules (402–414, 301, 303–304); hosting rules (400, 401, 300) and host object rules (404, 302) apply only to the HTTP catalog response. 37A-AiCatalogAuditor-100 is emitted on every run, including missing-catalog and invalid-JSON failures. CheckCode suffixes use status ranges: 100 information, 200 success, 300–399 warning, 400–499 fail, 500–599 error.

CheckCodeStatusWhen it firesRecommendation
37A-AiCatalogAuditor-100INFORMATIONEvery run. Records that this auditor implements ARD v0.91 and the pinned ai-catalog.schema.json commit.This auditor implements ARD v0.91; catalog documents still use specVersion "1.0". Schema pin 4a8a6b8fdd3ac4a50dcb63213573159c1eed7856.
37A-AiCatalogAuditor-400FAILThe catalog HTTP response has a missing or blank Content-Type header.Send Content-Type: application/json for {catalogUrl}.
37A-AiCatalogAuditor-401FAILContent-Type is present but is not application/json or a +json type.Serve {catalogUrl} as application/json instead of {contentType}.
37A-AiCatalogAuditor-402FAILspecVersion is missing or is not "1.0".Set specVersion to "1.0" on {catalogUrl}; current value is {observed}.
37A-AiCatalogAuditor-403FAILentries is missing or is not an array.Add an entries array on {catalogUrl} listing the advertised agentic resources.
37A-AiCatalogAuditor-404FAILhost is present but host.displayName is missing or blank.Set host.displayName on {catalogUrl} to a human-readable publisher name.
37A-AiCatalogAuditor-405FAILA catalog entry has no identifier.Set identifier on entry {label} in {catalogUrl} to a urn:air:<publisher>:<namespace>:<agent-name> URN.
37A-AiCatalogAuditor-406FAILA catalog entry has no displayName.Set displayName on entry {label} in {catalogUrl}.
37A-AiCatalogAuditor-407FAILA catalog entry has no type.Set type on entry {label} in {catalogUrl} to an IANA media type such as application/mcp-server-card+json.
37A-AiCatalogAuditor-408FAILAn entry identifier is present but does not match urn:air:<publisher>:<namespace>:<agent-name>.Change {identifier} in {catalogUrl} to a domain-anchored URN such as urn:air:example.com:agent:assistant.
37A-AiCatalogAuditor-409FAILAn entry has both url and data.Keep only url or only data on entry {label} in {catalogUrl}; the schema forbids both.
37A-AiCatalogAuditor-410FAILAn entry has neither url nor data.Add url or inline data on entry {label} in {catalogUrl}.
37A-AiCatalogAuditor-411FAILA trustManifest object is present without identity.Set trustManifest.identity on {label} in {catalogUrl} to a SPIFFE ID, DID, or HTTPS FQDN URI.
37A-AiCatalogAuditor-412FAILAn attestation object has no type.Set attestation.type on {label} in {catalogUrl} (e.g. SOC2-Type2).
37A-AiCatalogAuditor-413FAILAn attestation object has no uri.Set attestation.uri on {label} in {catalogUrl} to the attestation document URL.
37A-AiCatalogAuditor-414FAILAn attestation object has no mediaType.Set attestation.mediaType on {label} in {catalogUrl} (e.g. application/pdf).
37A-AiCatalogAuditor-415FAILNo catalog was found at /.well-known/ai-catalog.json, robots.txt Agentmap:, or <link rel="ai-catalog">.Publish ai-catalog.json at /.well-known/ai-catalog.json for {url}, or advertise it with an Agentmap: robots.txt directive or <link rel="ai-catalog">.
37A-AiCatalogAuditor-416FAILA catalog was found but the body is not valid JSON.Fix the JSON served for {url}; parser reported {detail}.
37A-AiCatalogAuditor-300WARNINGThe catalog response has no Access-Control-Allow-Origin header.Add Access-Control-Allow-Origin: * on {catalogUrl} so discovery crawlers can fetch the catalog.
37A-AiCatalogAuditor-301WARNINGentries is an empty array.Add at least one catalog entry on {catalogUrl} so agents can discover capabilities.
37A-AiCatalogAuditor-302WARNINGThe root host object is omitted.Add a host object with displayName on {catalogUrl} so publishers can be identified.
37A-AiCatalogAuditor-303WARNINGrepresentativeQueries is present but does not contain 2–5 strings.Change representativeQueries on {label} in {catalogUrl} from size {observed} to 2–5 examples.
37A-AiCatalogAuditor-304WARNINGupdatedAt is present but is not an ISO 8601 date-time.Set updatedAt on {label} in {catalogUrl} to an ISO 8601 timestamp such as 2026-01-15T12:00:00Z instead of {observed}.
37A-AiCatalogAuditor-500ERRORThe audited URL is null or blank.Pass a non-blank page URL instead of {observed} so the auditor can discover ai-catalog.json.
37A-AiCatalogAuditor-501ERRORThe audited URL is not a valid URI.Pass an absolute HTTP(S) URL instead of {url}; parser reported {detail}.
37A-AiCatalogAuditor-502ERRORDiscovery failed with an unexpected exception.Retry the audit of {url}; the auditor failed with {detail}.
37A-AiCatalogAuditor-200SUCCESSEvery rule above passed; one SUCCESS check is added with the message AI catalog at "{catalogUrl}" is valid: specVersion {specVersion}, {entryCount} entries.β€”

Output Documentation

StatusDescriptionTest logic
INFORMATIONProvenance only; does not change overall statusEvery run includes 37A-AiCatalogAuditor-100 with ARD v0.91 and schema commit 4a8a6b8f… in the message and Check.data.
SUCCESSA catalog was found and every publishing and schema rule passedWell-known, Agentmap, or HTML rel="ai-catalog" returned parseable JSON; Content-Type is JSON; specVersion is 1.0; entries is a non-empty array; each entry has a valid urn:air identifier, displayName, type, and exactly one of url or data; CORS is present. The specification pin check is still present.
WARNINGThe catalog is usable but incomplete for crawlers or searchMissing Access-Control-Allow-Origin (300); empty entries (301); omitted host (302); representativeQueries not sized 2–5 (303); or updatedAt not ISO 8601 (304). No FAIL rule fired. The specification pin check is still present.
FAILThe catalog is missing, not JSON, or violates a schema MUSTNot found at well-known / Agentmap / HTML link (415); unparseable JSON (416); missing or non-JSON Content-Type (400, 401); specVersion not 1.0 (402); no entries array (403); host.displayName missing (404); missing entry fields (405–407); invalid URN (408); both or neither url/data (409, 410); trustManifest without identity (411); incomplete attestations (412–414). The specification pin check is still present.
ERRORThe request cannot be auditedThe audited URL is null or blank (500), not a valid URI (501), or discovery threw (502). Checks include the specification pin (100) and the process error.

Risks and Considerations

Discovery

  • Agents and federated registries look first at /.well-known/ai-catalog.json. An HTML SPA that serves 200 for every path hides the catalog unless Content-Type is JSON or an Agentmap / HTML link points at the real file.

  • CORS (Access-Control-Allow-Origin: *) is required for browser-based crawlers. A catalog that exists but cannot be read cross-origin is effectively unpublished.

Schema fidelity

  • Identifiers must stay urn:air: domain-anchored names. HTTP URLs in identifier break federation uniqueness and trust binding described in the ARD specification.

  • Strict value-or-reference (url XOR data) keeps parsers from choosing between two payloads. Both or neither makes the entry unusable.

  • representativeQueries (2–5 examples) are how registries build semantic embeddings. Omitting them is allowed; a list of the wrong size is a warning because search ranking will be weak or rejected by schema-strict consumers.

Source: docs.37audits.com

Ready to start auditing?

Add this auditor to your monitoring setup and start identifying issues on your websites today.

Β© 2026 37 Audits. All rights reserved. Audit your websites with confidence.

Supported by

Featured on Dofollow.Tools

Made with ❀️ in Floripa