Skilllibrary api-schema
Defines request/response shapes, versioning, validation, and compatibility rules for API-first work. Trigger on 'design API', 'OpenAPI spec', 'REST schema', 'API versioning', 'generate client SDK'. DO NOT USE for GraphQL schemas, gRPC/protobuf definitions (use stack-standards), auth endpoint logic (use auth-patterns), or external API client wrappers (use external-api-client).
git clone https://github.com/merceralex397-collab/skilllibrary
T=$(mktemp -d) && git clone --depth=1 https://github.com/merceralex397-collab/skilllibrary "$T" && mkdir -p ~/.claude/skills && cp -r "$T/02-generated-repo-core/api-schema" ~/.claude/skills/merceralex397-collab-skilllibrary-api-schema && rm -rf "$T"
02-generated-repo-core/api-schema/SKILL.mdPurpose
Design API schemas using OpenAPI 3.1 and JSON Schema for type-safe contracts between services. Define versioning strategy, distinguish breaking from non-breaking changes, and enable code generation from specs. The schema IS the contract—disagreement about the schema means disagreement about the API.
When to use this skill
Use when:
- Designing new REST/HTTP API
- Adding endpoints to existing API
- Generating client SDKs or server stubs
- Documenting API for external consumers
Do NOT use when:
- GraphQL APIs (different schema language)
- Internal RPC/gRPC (use protobuf)
- Simple scripts with no API consumers
Operating procedure
-
Create OpenAPI 3.1 specification:
openapi: 3.1.0 info: title: User Service API version: 1.0.0 description: API for user management servers: - url: https://api.example.com/v1 description: Production - url: https://staging-api.example.com/v1 description: Staging paths: /users/{userId}: get: operationId: getUser summary: Get user by ID parameters: - name: userId in: path required: true schema: type: string format: uuid responses: '200': description: User found content: application/json: schema: $ref: '#/components/schemas/User' '404': description: User not found -
Define reusable schemas in components:
components: schemas: User: type: object required: - id - email - createdAt properties: id: type: string format: uuid description: Unique user identifier email: type: string format: email displayName: type: string maxLength: 100 createdAt: type: string format: date-time additionalProperties: false # Strict schema Error: type: object required: - code - message properties: code: type: string enum: [NOT_FOUND, VALIDATION_ERROR, INTERNAL_ERROR] message: type: string details: type: object -
Classify changes as breaking or non-breaking:
BREAKING (requires major version bump): ───────────────────────────────────── - Removing endpoint or method - Removing required request field - Adding required request field without default - Changing field type - Removing response field clients depend on - Changing error response structure NON-BREAKING (minor or patch version): ───────────────────────────────────── - Adding new endpoint - Adding optional request field - Adding response field - Adding new enum value (if clients ignore unknown) - Relaxing validation (wider accepted range) -
Choose versioning strategy:
# URL path versioning (most common, clearest) servers: - url: https://api.example.com/v1 - url: https://api.example.com/v2 # Header versioning (cleaner URLs) # Client sends: Accept: application/vnd.api+json;version=1 # Query parameter (easy for debugging) # GET /users?api-version=2024-01-15 -
Generate code from spec:
# Generate TypeScript client npx openapi-typescript openapi.yaml -o types.ts # Generate Python FastAPI server stub pip install fastapi-code-generator fastapi-codegen --input openapi.yaml --output app/ # Validate spec npx @redocly/cli lint openapi.yaml -
Add request validation:
# FastAPI automatically validates against OpenAPI schema from pydantic import BaseModel, EmailStr from uuid import UUID class CreateUserRequest(BaseModel): email: EmailStr display_name: str | None = None class Config: extra = 'forbid' # Reject unknown fields @app.post("/users") async def create_user(request: CreateUserRequest) -> User: # Request already validated against schema ...
Output defaults
# openapi.yaml openapi: 3.1.0 info: title: [Service Name] API version: 1.0.0 description: | [Description] ## Versioning URL path versioning: /v1/, /v2/ ## Authentication Bearer token in Authorization header servers: - url: https://api.example.com/v1 paths: /[resource]: get: # ... post: # ... components: schemas: # Reusable types securitySchemes: bearerAuth: type: http scheme: bearer
References
- OpenAPI 3.1 Specification: https://swagger.io/specification/
- https://spec.openapis.org/oas/v3.1.0
- https://json-schema.org/learn/getting-started-step-by-step
Failure handling
- Schema and implementation drift: Generate code from schema or validate implementation against schema in CI
- Breaking change deployed accidentally: Add breaking-change detection to CI; tools like
can compare specsoasdiff - Clients fail on new fields: Design clients to ignore unknown fields; use
in response schemasadditionalProperties: true - Validation too strict: Start permissive, tighten later; it's easier to reject more than to accept more
- Large spec becomes unmaintainable: Split into multiple files using
to external files$ref