APIs.guru directory API: spec vs live

Summary

Spec
https://api.apis.guru/v2/openapi.yaml (OpenAPI 3)
Base URL
https://api.apis.guru/v2
Run
, read-only GET requests, no credentials
Coverage
7 operations in the spec, 6 requests sent, 6 successful,6 operations observed
Hard violations
13 distinct schema locations
Reviewer note
Confirmed: GET /specs/{provider}/{api}.json returns the OpenAPI document itself; the spec documents the API entry object (preferred, versions).

Hard violations 13

A typed client generated from the spec would break on these.

Hide 13 findings
GET /specs/{provider}/{api}.json > response 200 > application/json > /externalDocs

response body at /externalDocs: property "externalDocs" is not allowed

GET /specs/apis.guru/2.2.0.json → 200 application/json
actual "externalDocs"
  • If the spec is the source of truth: Stop returning "externalDocs" from GET /specs/{provider}/{api}.json; the spec forbids unknown properties here.
  • If the implementation is the source of truth: Add "externalDocs" to paths["/specs/{provider}/{api}.json"].get.responses["200"].content["application/json"].schema.properties or allow additionalProperties.
GET /specs/{provider}/{api}.json > response 200 > application/json > /info

response body at /info: property "info" is not allowed

GET /specs/apis.guru/2.2.0.json → 200 application/json
actual "info"
  • If the spec is the source of truth: Stop returning "info" from GET /specs/{provider}/{api}.json; the spec forbids unknown properties here.
  • If the implementation is the source of truth: Add "info" to paths["/specs/{provider}/{api}.json"].get.responses["200"].content["application/json"].schema.properties or allow additionalProperties.
GET /specs/{provider}/{api}.json > response 200 > application/json > /link

response body at /link: property "link" is not allowed

GET /specs/apis.guru/2.2.0.json → 200 application/json
actual "link"
  • If the spec is the source of truth: Stop returning "link" from GET /specs/{provider}/{api}.json; the spec forbids unknown properties here.
  • If the implementation is the source of truth: Add "link" to paths["/specs/{provider}/{api}.json"].get.responses["200"].content["application/json"].schema.properties or allow additionalProperties.
GET /specs/{provider}/{api}.json > response 200 > application/json > /openapiVer

response body at /openapiVer: property "openapiVer" is not allowed

GET /specs/apis.guru/2.2.0.json → 200 application/json
actual "openapiVer"
  • If the spec is the source of truth: Stop returning "openapiVer" from GET /specs/{provider}/{api}.json; the spec forbids unknown properties here.
  • If the implementation is the source of truth: Add "openapiVer" to paths["/specs/{provider}/{api}.json"].get.responses["200"].content["application/json"].schema.properties or allow additionalProperties.
GET /specs/{provider}/{api}.json > response 200 > application/json > /preferred

response body at /preferred: required property "preferred" is missing

GET /specs/apis.guru/2.2.0.json → 200 application/json
expected "preferred"
  • If the spec is the source of truth: Include "preferred" in the 200 response of GET /specs/{provider}/{api}.json.
  • If the implementation is the source of truth: Remove "preferred" from required at paths["/specs/{provider}/{api}.json"].get.responses["200"].content["application/json"].schema.
GET /specs/{provider}/{api}.json > response 200 > application/json > /swaggerUrl

response body at /swaggerUrl: property "swaggerUrl" is not allowed

GET /specs/apis.guru/2.2.0.json → 200 application/json
actual "swaggerUrl"
  • If the spec is the source of truth: Stop returning "swaggerUrl" from GET /specs/{provider}/{api}.json; the spec forbids unknown properties here.
  • If the implementation is the source of truth: Add "swaggerUrl" to paths["/specs/{provider}/{api}.json"].get.responses["200"].content["application/json"].schema.properties or allow additionalProperties.
GET /specs/{provider}/{api}.json > response 200 > application/json > /swaggerYamlUrl

response body at /swaggerYamlUrl: property "swaggerYamlUrl" is not allowed

GET /specs/apis.guru/2.2.0.json → 200 application/json
actual "swaggerYamlUrl"
  • If the spec is the source of truth: Stop returning "swaggerYamlUrl" from GET /specs/{provider}/{api}.json; the spec forbids unknown properties here.
  • If the implementation is the source of truth: Add "swaggerYamlUrl" to paths["/specs/{provider}/{api}.json"].get.responses["200"].content["application/json"].schema.properties or allow additionalProperties.
GET /specs/{provider}/{api}.json > response 200 > application/json > /updated

response body at /updated: property "updated" is not allowed

GET /specs/apis.guru/2.2.0.json → 200 application/json
actual "updated"
  • If the spec is the source of truth: Stop returning "updated" from GET /specs/{provider}/{api}.json; the spec forbids unknown properties here.
  • If the implementation is the source of truth: Add "updated" to paths["/specs/{provider}/{api}.json"].get.responses["200"].content["application/json"].schema.properties or allow additionalProperties.
GET /specs/{provider}/{api}.json > response 200 > application/json > /versions

response body at /versions: required property "versions" is missing

GET /specs/apis.guru/2.2.0.json → 200 application/json
expected "versions"
  • If the spec is the source of truth: Include "versions" in the 200 response of GET /specs/{provider}/{api}.json.
  • If the implementation is the source of truth: Remove "versions" from required at paths["/specs/{provider}/{api}.json"].get.responses["200"].content["application/json"].schema.
GET /{provider}.json > response 200 > application/json > /apis/added

response body at /apis/added: required property "added" is missing

GET /apis.guru.json → 200 application/json
expected "added"
  • If the spec is the source of truth: Include "added" in the 200 response of GET /{provider}.json.
  • If the implementation is the source of truth: Remove "added" from required at paths["/{provider}.json"].get.responses["200"].content["application/json"].schema.properties["apis"].
GET /{provider}.json > response 200 > application/json > /apis/apis.guru

response body at /apis/apis.guru: property "apis.guru" is not allowed

GET /apis.guru.json → 200 application/json
actual "apis.guru"
  • If the spec is the source of truth: Stop returning "apis.guru" from GET /{provider}.json; the spec forbids unknown properties here.
  • If the implementation is the source of truth: Add "apis.guru" to paths["/{provider}.json"].get.responses["200"].content["application/json"].schema.properties["apis"].properties or allow additionalProperties.
GET /{provider}.json > response 200 > application/json > /apis/preferred

response body at /apis/preferred: required property "preferred" is missing

GET /apis.guru.json → 200 application/json
expected "preferred"
  • If the spec is the source of truth: Include "preferred" in the 200 response of GET /{provider}.json.
  • If the implementation is the source of truth: Remove "preferred" from required at paths["/{provider}.json"].get.responses["200"].content["application/json"].schema.properties["apis"].
GET /{provider}.json > response 200 > application/json > /apis/versions

response body at /apis/versions: required property "versions" is missing

GET /apis.guru.json → 200 application/json
expected "versions"
  • If the spec is the source of truth: Include "versions" in the 200 response of GET /{provider}.json.
  • If the implementation is the source of truth: Remove "versions" from required at paths["/{provider}.json"].get.responses["200"].content["application/json"].schema.properties["apis"].

Reproduce

The first hard violation came from this request. Compare the response to the schema at the location named in the finding.

curl -s -H 'Accept: application/json' 'https://api.apis.guru/v2/specs/apis.guru/2.2.0.json'

Data

If a finding is wrong, open an issue; if it is right, a pull request on the spec is welcome.