An API with no machine-readable schema has no contract. Every consumer must read the implementation source to understand request/response shapes — and when the implementation changes, there is no diff to review, no tooling to catch regressions, and no artifact to share with third-party integrators. iso-25010:2011 compatibility.interoperability and maintainability.analysability both fail: the API cannot be consumed reliably by any party without deep implementation access. SDK generation, mock servers, and contract testing are all impossible without a schema.
Critical because without a machine-readable schema, the API has no enforceable contract, making all consumer integrations fragile and all tooling (SDK gen, mock servers, contract tests) inaccessible.
Add a machine-readable schema. The fastest path depends on your framework. For Express/Hono, create openapi.yaml or use @asteasolutions/zod-to-openapi to generate from existing Zod schemas. For FastAPI, verify /docs is accessible — it's auto-generated. For NestJS, install @nestjs/swagger.
# openapi.yaml -- minimal starting point:
openapi: "3.1.0"
info:
title: "Your API"
version: "1.0.0"
paths:
/api/v1/users:
get:
summary: "List users"
responses:
"200":
description: "Success"
For GraphQL, enable introspection: true in development and export the SDL. For gRPC, your .proto files are the schema — ensure they are committed and up to date.
ID: api-design.contract-quality.schema-exists
Severity: critical
What to look for: Check for a machine-readable API schema definition. For REST: look for openapi.yaml, openapi.json, swagger.yaml, swagger.json in the project root, docs/, or api/ directory. Also check for auto-generation from code annotations (tsoa, NestJS Swagger, FastAPI automatic OpenAPI, go-swagger). For GraphQL: check for .graphql schema files, or schema auto-generated from code-first frameworks (type-graphql, NestJS GraphQL, Strawberry). For gRPC: check for .proto files with service definitions. Also check for AsyncAPI specs for event-driven APIs.
Pass criteria: Count the number of schema definition files found. A machine-readable API schema exists in at least 1 of these forms: OpenAPI spec file, GraphQL SDL, Protobuf definitions, or AsyncAPI spec. Code-first frameworks that auto-generate schemas at runtime also count (verify the framework is configured to expose the schema).
Fail criteria: No schema definition of any kind. No OpenAPI spec, no GraphQL SDL, no Protobuf files. The API's contract exists only in the route handler code, meaning consumers must read the implementation to understand the API. Do not pass when only inline JSDoc comments exist without a machine-readable spec file (e.g., /** @returns User */ comments are not a schema).
Skip (N/A) when: Never skip -- every API should have a schema definition.
Detail on fail: State what's missing (e.g., "No OpenAPI spec, no Swagger config, no auto-generation framework. The 14 REST endpoints have no machine-readable contract. Consumers must read route handler source code to understand request/response shapes."). Max 500 chars.
Cross-reference: For schema validation at runtime, see the schema-validation check below. For documentation quality beyond the schema, see the Developer Documentation audit.
Remediation: Add a schema definition. The lowest-effort path depends on your framework:
For Express/Fastify/Hono: Create an openapi.yaml file manually or use a code-first library like tsoa or @asteasolutions/zod-to-openapi to generate it from your Zod schemas.
For FastAPI: OpenAPI is generated automatically -- just verify /docs is accessible.
For NestJS: Install @nestjs/swagger and add decorators.
For GraphQL: Ensure introspection: true is enabled in development and export the SDL.
# openapi.yaml -- minimal starting point:
openapi: "3.1.0"
info:
title: "Your API"
version: "1.0.0"
paths:
/api/users:
get:
summary: "List users"
responses:
"200":
description: "Success"