openapi-swagger-doc-skill
Purpose
This skill guides the agent to create, review, and improve OpenAPI / Swagger documentation that is accurate, consistent, readable, tool-friendly, and aligned with API design best practices.
The agent should produce OpenAPI documents that can be used for API design review, Swagger UI / Redoc documentation, frontend-backend contract alignment, mock server generation, client SDK generation, API testing, and contract testing.
Prefer OpenAPI 3.1 unless the user’s project or tooling explicitly requires OpenAPI 3.0.x or Swagger 2.0.
When to Use This Skill
Use this skill when the user asks to:
- Write OpenAPI / Swagger documentation
- Convert API descriptions into OpenAPI YAML or JSON
- Review existing Swagger / OpenAPI files
- Design RESTful API contracts
- Generate API docs from controller or service descriptions
- Standardize API request and response formats
- Improve API documentation quality
- Add examples, schemas, error codes, parameters, or authentication definitions
Core Principles
1. Prefer API-first / Design-first
Before writing implementation details, clarify the API contract:
- What resource is exposed
- Who calls the API
- What business action it represents
- What request parameters are required
- What response body is returned
- What errors can happen
- What authentication is required
Do not blindly mirror backend method names or database table names.
Good API documentation should describe the external contract, not the internal implementation.
2. Use OpenAPI 3.x Structure
The generated document should normally include:
openapi: 3.1.0
info:
title: Example API
version: 1.0.0
description: API description
servers:
- url: https://api.example.com
description: Production
tags: []
paths: {
}
components:
schemas: {
}
parameters: {
}
responses: {
}
securitySchemes: {
}
security: []
`
Use YAML by default because it is easier for humans to read and maintain.
Writing Rules
1. Path Design
Use resource-oriented paths.
Prefer:
/users/{
userId}
/orders/{
orderId}/items
/model-evaluation-tasks/{
taskId}
Avoid:
/getUser
/createOrder
/queryTaskInfo
/doEvaluation
Rules:
- Use nouns, not verbs
- Use lowercase path segments
- Use hyphen-case for multi-word resources
- Use plural resource names where appropriate
- Use path parameters only for resource identity
- Use query parameters for filtering, pagination, sorting, and optional search conditions
Example:
GET /model-evaluation-tasks?status=RUNNING&page=1&pageSize=20
2. HTTP Method Semantics
Use HTTP methods consistently:
GET: read resource, no side effectsPOST: create resource or trigger non-idempotent actionPUT: replace entire resourcePATCH: partially update resourceDELETE: delete resource
Do not use GET for operations that change server state.
3. Operation Metadata
Every operation should include:
tagssummarydescriptionoperationIdparameters, if neededrequestBody, if neededresponsessecurity, if different from global security
Example:
operationId: createModelEvaluationTask
summary: Create a model evaluation task
description: Creates an asynchronous task to evaluate a large model against a dataset.
Rules:
summaryshould be shortdescriptionshould explain business behavior and important constraintsoperationIdshould be stable, unique, and code-generation friendly- Use lowerCamelCase for
operationId
4. Parameters
Use parameter locations correctly:
path: resource identityquery: filtering, pagination, sortingheader: request metadata, tracing, auth-related metadatacookie: only when cookie-based API behavior is required
Every path parameter must be marked as required:
parameters:
- name: taskId
in: path
required: true
description: Unique ID of the evaluation task.
schema:
type: string
For pagination, prefer consistent names:
page:
type: integer
minimum: 1
default: 1
pageSize:
type: integer
minimum: 1
maximum: 100
default: 20
5. Request Body
Use requestBody for JSON payloads in POST, PUT, and PATCH.
Example:
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateEvaluationTaskRequest'
examples:
basic:
summary: Basic request
value:
modelId: "model-001"
datasetId: "dataset-001"
Rules:
- Always declare content type
- Prefer schema references under
components.schemas - Provide examples for important APIs
- Mark required fields explicitly inside the schema
6. Responses
Every operation must define responses. At minimum, include one successful response and common error responses.
Example:
responses:
'201':
description: Evaluation task created successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/CreateEvaluationTaskResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'500':
$ref: '#/components/responses/InternalServerError'
Rules:
- Do not only write
200 - Use accurate HTTP status codes
- Include error responses
- Include response examples where useful
- Use reusable common responses under
components.responses
Recommended status codes:
200: successful query or update201: resource created202: accepted async task204: successful delete or no response body400: invalid request401: not authenticated403: no permission404: resource not found409: conflict422: semantic validation failed429: rate limited500: server error
For asynchronous APIs, prefer:
'202':
description: Task accepted and will be processed asynchronously.
7. Schemas
Define reusable schemas under components.schemas.
Example:
components:
schemas:
CreateEvaluationTaskRequest:
type: object
required:
- modelId
- datasetId
properties:
modelId:
type: string
description: ID of the model to evaluate.
example: model-001
datasetId:
type: string
description: ID of the dataset used for evaluation.
example: dataset-001
Rules:
- Use meaningful schema names
- Use PascalCase for schema names
- Use lowerCamelCase for property names unless the API already uses another convention
- Add
descriptionfor non-obvious fields - Add
examplefor important fields - Use
enumfor fixed values - Use
formatfor known formats such asdate-time,uuid,int64 - Avoid vague
objectfields without structure - Avoid overusing
additionalProperties: true
8. Error Model
Define a standard error response.
Example:
ErrorResponse:
type: object
required:
- code
- message
- traceId
properties:
code:
type: string
description: Business error code.
example: INVALID_ARGUMENT
message:
type: string
description: Human-readable error message.
example: The datasetId field is required.
traceId:
type: string
description: Trace ID for troubleshooting.
example: 9f8c7a6b5d4e3f21
details:
type: array
description: Additional validation errors.
items:
type: object
properties:
field:
type: string
example: datasetId
reason:
type: string
example: must not be empty
Common reusable responses:
responses:
BadRequest:
description: Invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Unauthorized:
description: Authentication is required.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Forbidden:
description: Permission denied.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
NotFound:
description: Resource not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
InternalServerError:
description: Internal server error.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
9. Authentication and Security
Define security schemes under components.securitySchemes.
Bearer token example:
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
security:
- bearerAuth: []
API key example:
components:
securitySchemes:
apiKeyAuth:
type: apiKey
in: header
name: X-API-Key
Rules:
- Do not describe authentication only in prose
- Use OpenAPI security schemes
- Define global security if most APIs require authentication
- Override operation-level
securityonly when needed - Mark public endpoints explicitly when necessary:
security: []
10. Examples
For important APIs, provide request and response examples.
Examples should be realistic and consistent with the schema.
Bad:
example:
id: string
name: string
Good:
example:
id: "task-20260513-001"
status: "RUNNING"
createdAt: "2026-05-13T10:30:00Z"
Rules:
- Use realistic IDs, timestamps, and values
- Include success examples
- Include error examples for complex validation
- Keep examples synchronized with schemas
11. Naming Conventions
Recommended conventions:
- Path: kebab-case, for example
/model-evaluation-tasks - Path parameter: lowerCamelCase, for example
{taskId} - Query parameter: lowerCamelCase, for example
pageSize - JSON field: lowerCamelCase, for example
createdAt - Schema name: PascalCase, for example
EvaluationTask - Operation ID: lowerCamelCase, for example
createEvaluationTask - Tag: human readable, for example
Model Evaluation
12. Pagination
Use a consistent pagination response.
Example:
PageResult:
type: object
required:
- page
- pageSize
- total
- items
properties:
page:
type: integer
example: 1
pageSize:
type: integer
example: 20
total:
type: integer
format: int64
example: 128
items:
type: array
items: {
}
For specific resources, define concrete page schemas:
EvaluationTaskPage:
allOf:
- $ref: '#/components/schemas/PageResult'
- type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/EvaluationTask'
13. Sorting and Filtering
For list APIs, document all supported filters.
Example:
parameters:
- name: status
in: query
required: false
description: Filter tasks by status.
schema:
$ref: '#/components/schemas/EvaluationTaskStatus'
- name: sort
in: query
required: false
description: Sort expression. Prefix with '-' for descending order.
schema:
type: string
example: "-createdAt"
Avoid undocumented magic query parameters.
14. Async Task APIs
For asynchronous tasks, document the lifecycle clearly.
Recommended endpoints:
POST /evaluation-tasks
GET /evaluation-tasks/{taskId}
GET /evaluation-tasks/{taskId}/results
POST /evaluation-tasks/{taskId}/cancel
Recommended status enum:
EvaluationTaskStatus:
type: string
enum:
- PENDING
- RUNNING
- SUCCEEDED
- FAILED
- CANCELED
For task creation, use 202 Accepted if processing starts asynchronously.
15. File Upload APIs
Use multipart/form-data.
Example:
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
required:
- file
properties:
file:
type: string
format: binary
description:
type: string
16. Streaming APIs
For Server-Sent Events:
responses:
'200':
description: Streaming response using Server-Sent Events.
content:
text/event-stream:
schema:
type: string
description: SSE event stream.
For plain streaming text:
content:
text/plain:
schema:
type: string
Clearly document:
- Stream content type
- Event format
- End condition
- Error behavior
- Whether partial output is possible
17. Versioning
Prefer versioning through URL or header depending on project standard.
Common URL versioning:
servers:
- url: https://api.example.com/v1
Rules:
- Do not mix multiple versioning styles casually
- Keep
info.versionfor document version - Keep API version strategy explicit
18. Validation Checklist
Before finalizing OpenAPI output, verify:
openapi,info,servers,paths, andcomponentsexist- Every operation has
summary,operationId, andresponses - Every path parameter is declared and required
- Every request body has a schema
- Every response has a meaningful description
- Common errors are documented
- Schemas use correct
requiredfields - Enums are explicitly defined
- Examples match schema definitions
- Authentication is defined with
securitySchemes - Reusable objects are placed in
components - Names are consistent
- No internal implementation details are leaked
- No database-only field names are exposed unless they are part of the public contract
- The document can be validated by OpenAPI tooling
Output Style
When creating OpenAPI documentation, output in this order:
- Brief explanation of assumptions
- Complete OpenAPI YAML
- Notes or improvement suggestions, if needed
When reviewing OpenAPI documentation, output in this order:
- Major issues
- Contract consistency issues
- Schema and response problems
- Naming and style suggestions
- Corrected YAML snippets
Default OpenAPI Template
Use this as a starting point when the user has not provided an existing file.
openapi: 3.1.0
info:
title: Example API
version: 1.0.0
description: Example OpenAPI documentation.
servers:
- url: https://api.example.com/v1
description: Production server
tags:
- name: Example
description: Example APIs
paths:
/examples:
get:
tags:
- Example
operationId: listExamples
summary: List examples
description: Returns a paginated list of examples.
parameters:
- name: page
in: query
required: false
description: Page number, starting from 1.
schema:
type: integer
minimum: 1
default: 1
- name: pageSize
in: query
required: false
description: Number of records per page.
schema:
type: integer
minimum: 1
maximum: 100
default: 20
responses:
'200':
description: Examples returned successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/ExamplePage'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'500':
$ref: '#/components/responses/InternalServerError'
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
schemas:
Example:
type: object
required:
- id
- name
- createdAt
properties:
id:
type: string
description: Unique ID of the example.
example: example-001
name:
type: string
description: Name of the example.
example: Demo example
createdAt:
type: string
format: date-time
description: Creation time.
example: '2026-05-13T10:30:00Z'
ExamplePage:
type: object
required:
- page
- pageSize
- total
- items
properties:
page:
type: integer
example: 1
pageSize:
type: integer
example: 20
total:
type: integer
format: int64
example: 100
items:
type: array
items:
$ref: '#/components/schemas/Example'
ErrorResponse:
type: object
required:
- code
- message
- traceId
properties:
code:
type: string
example: INVALID_ARGUMENT
message:
type: string
example: Invalid request parameter.
traceId:
type: string
example: 9f8c7a6b5d4e3f21
responses:
BadRequest:
description: Invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Unauthorized:
description: Authentication is required.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Forbidden:
description: Permission denied.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
NotFound:
description: Resource not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
InternalServerError:
description: Internal server error.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
security:
- bearerAuth: []
Common Anti-patterns
Avoid these patterns:
- Only documenting happy-path
200responses - Missing error response model
- No examples
- All schemas defined inline
- Overusing
type: objectwithout fields - Exposing database table structure directly
- Using vague field names like
data,info,objwithout schema - Inconsistent status codes
- Using
GETfor state-changing operations - Duplicating the same parameter definitions everywhere
- Missing authentication definitions
- Inconsistent naming style
- Operation IDs generated from backend method names without cleanup
Agent Behavior Rules
When information is missing, make reasonable assumptions and state them clearly.
Do not ask excessive clarification questions. If the user gives partial API information, generate a best-effort OpenAPI draft and mark uncertain parts as assumptions or TODO comments.
When the user provides Java Controller code, infer:
- Path from class-level and method-level mappings
- HTTP method from mapping annotation
- Request parameters from method arguments
- Request body from DTOs
- Response schema from return type
- Tags from controller name
- Operation summaries from method names and comments
When the user provides database tables only, do not directly expose table fields as API fields. First infer the business resource model.
When generating documentation for Chinese development teams, field descriptions may be in Chinese, but schema names, operation IDs, and paths should normally remain English unless the project standard says otherwise.