# api.qa report — api.services

> **Grade C** · AX score **10/10** · remote mode · attested

- verified: 2026-07-30T18:54:28.936Z
- verifier: api.qa v0.1.0 · seed 1915493268 (replayable)
- evidence digest: `abe7d0a6176481581d443472148efd340fe0126146eb2d1dc6a3afa0775c026f`
- report digest: `4bae2535693549b1358cfd392da5172d9a28d34583c9a3b2faf84eec83dd03eb` (Ed25519-signed)

## AX score (the 10-point checklist)

| # | check | verdict |
| --- | --- | --- |
| 1 | llms.txt is served and agent-actionable | PASS |
| 2 | /.well-known/agents.json capability card parses | PASS |
| 3 | /icp.json self-classification surface | PASS |
| 4 | root content-negotiates (curl → markdown, browser → HTML) | PASS |
| 5 | machine-readable API contract (OpenAPI) is published | PASS |
| 6 | MCP interface declared with transport + tools | PASS |
| 7 | at least one declared endpoint answers 2xx with no key | PASS |
| 8 | payment boundaries answer as structured 402 offers | PASS |
| 9 | surfaces cross-reference each other (linkset) | PASS |
| 10 | attestation/identity ladder is declared | PASS |

## Check details

### PASS — llms.txt is served and agent-actionable (`llms-txt`)

markdown with an H1 and substantive content

### PASS — /.well-known/agents.json capability card parses (`agents-json`)

valid JSON; name="api.services", 6 http endpoint(s) declared

### PASS — /icp.json self-classification surface (`icp-json`)

valid JSON with agent_classes — an agent can self-classify

### PASS — root content-negotiates (curl → markdown, browser → HTML) (`content-negotiation`)

Accept: */* got non-HTML text; Accept: text/html got HTML

### skip — API home answers machine-legible (JSON/markdown) to every client, browsers included (`machine-legible-home`)

no probe manifest declared — target does not claim the agent-first API contract; page surfaces may serve HTML

### PASS — machine-readable API contract (OpenAPI) is published (`openapi`)

OpenAPI parses; 16 path(s), 11 keyless GET candidate(s)

### PASS — MCP interface declared with transport + tools (`mcp-declared`)

mcp: streamable-http with tools [find_service, get_service, get_pricing, get_verticals, get_stack] (presence-grade; stdio not spawned)

### FAIL — MCP endpoint publishes RFC 9728 protected-resource metadata (`mcp-oauth-protected-resource`)

expected 200 JSON at https://api.services/.well-known/oauth-protected-resource — got: status 404

### FAIL — authorization server publishes RFC 8414 metadata (openid-configuration fallback) (`mcp-oauth-as-metadata`)

no authorization_servers[0] in protected-resource metadata to resolve

### FAIL — authorization server advertises PKCE S256 (RFC 7636) (`mcp-pkce`)

authorization server metadata not resolved — cannot confirm PKCE support

### FAIL — authorization server supports Dynamic Client Registration (RFC 7591) (`mcp-oauth-dcr`)

authorization server metadata not resolved — cannot confirm DCR support

### FAIL — protected-resource declares an RFC 8707 audience bound to the MCP origin (`mcp-oauth-resource-indicators`)

protected-resource metadata has no `resource` audience for the client to send as the RFC 8707 resource parameter

### FAIL — unauthenticated MCP request returns 401 with WWW-Authenticate → protected-resource metadata (`mcp-www-authenticate`)

unauthenticated MCP request returned 405, not 401 — the endpoint is not gated as an OAuth resource server

### skip — AAP discovery advertises Ed25519 + approval methods + register/status/revoke + jwks_uri (`aap-discovery`)

no /.well-known/agent-configuration document (2xx) — target does not claim the Agent Auth Protocol

### skip — auth.md agent-identity advertised (agent_auth identity/claim/events + ID-JAG + SET revocation) (`authmd-agent-identity`)

no authorization-server metadata resolved (no MCP/OAuth AS declared) — nothing advertises an agent_auth block

### PASS — at least one declared endpoint answers 2xx with no key (`keyless-flow`)

3/3 sampled endpoint(s) answered 2xx keyless (seed 1915493268)

### PASS — payment boundaries answer as structured 402 offers (`offers-402`)

1 offer(s) declared in agents.json (declared-only — no monetization.probe URL to verify behaviorally)

### PASS — surfaces cross-reference each other (linkset) (`linkset`)

Link header present on root

### PASS — attestation/identity ladder is declared (`attestation`)

attestation ladder declared (agents.json attestationLadder / icp.json ladder)

### PASS — sampled responses conform to their published schemas (`schema-conformance`)

3 sampled response(s) conform to their OpenAPI schemas

### PASS — claimed endpoints actually exist (no ghost surface) (`claims-honesty`)

every probed claimed endpoint exists (no 404/5xx)

### PASS — live responses match the published OpenAPI contract (full diff) (`contract-diff`)

live surface conforms to every declared contract; 13 additive deviation(s) (undeclared field/endpoint — live has more than declared, non-breaking)

### skip — card-declared probe manifest is valid (`probe-manifest`)

no probe manifest declared (agents.json top-level `probes`) — nothing to validate

### skip — capability card names its interfaces and cross-links its sibling surfaces (`card-interfaces-linked`)

no probe manifest — target does not claim the agent-first API contract

## Grade notes

- grade capped at C: published contract contradicted by behavior (mcp-oauth-protected-resource, mcp-oauth-as-metadata, mcp-pkce, mcp-oauth-dcr, mcp-oauth-resource-indicators, mcp-www-authenticate) — a lying surface is worse than a missing one

## Replay this verdict

The full evidence bundle is embedded in the JSON report. Judging is a pure
function of the bundle — re-run the checks over it and you MUST get this
same grade, or the report is forged / the verifier version changed:

```sh
curl -H 'accept: application/json' https://api.qa/api.services | npx autonomous-qa rejudge
```
