
openapi-documentation
Эксперт по OpenAPI документации. Используй для создания Swagger спецификаций, API schemas и автогенерации документации.
- Installs
- 70
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/dengineproblem/agents-monorepo --skill openapi-documentation- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads openapi-documentation automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
OpenAPI Documentation Expert
Expert in creating comprehensive OpenAPI/Swagger specifications and API documentation aligned with OpenAPI 3.0+ standards.
Core Principles
Specification Standards
- Use OpenAPI 3.0.3 or 3.1.0
- Consistent naming conventions (kebab-case for paths, camelCase for properties)
- Organize endpoints through tags
- Maintain reusable component schemas
- Document all response codes
Documentation Quality
- Provide business logic context
- Include extensive realistic examples
- Document all error scenarios
- Define rate-limiting specifications
- Explicit data format definitions
OpenAPI 3.0 Structure
Basic Specification
openapi: "3.0.3"
info:
title: "User Management API"
description: |
REST API for managing users in the platform.
## Authentication
All endpoints require Bearer token authentication.
## Rate Limiting
- Standard: 100 requests/minute
- Premium: 1000 requests/minute
## Versioning
API version is included in the URL path (/v1/).
version: "1.0.0"
contact:
name: "API Support"
email: "api-support@example.com"
url: "https://developer.example.com/support"
license:
name: "Apache 2.0"
url: "https://www.apache.org/licenses/LICENSE-2.0"
termsOfService: "https://example.com/terms"
servers:
- url: "https://api.example.com/v1"
description: "Production server"
- url: "https://staging-api.example.com/v1"
description: "Staging server"
- url: "http://localhost:3000/v1"
description: "Development server"
tags:
- name: "users"
description: "User management operations"
- name: "authentication"
description: "Authentication and authorization"
- name: "admin"
description: "Administrative operations"
security:
- bearerAuth: []
Path Documentation
paths:
/users:
get:
operationId: "listUsers"
tags:
- "users"
summary: "List all users"
description: |
Retrieve a paginated list of users.
Results can be filtered by status and sorted by various fields.
Pagination is cursor-based for optimal performance.
parameters:
- $ref: "#/components/parameters/PageSize"
- $ref: "#/components/parameters/PageCursor"
- name: "status"
in: "query"
description: "Filter by user status"
required: false
schema:
type: "string"
enum: ["active", "inactive", "pending"]
default: "active"
- name: "sort"
in: "query"
description: "Sort field and direction"
required: false
schema:
type: "string"
enum: ["created_at:asc", "created_at:desc", "name:asc", "name:desc"]
default: "created_at:desc"
responses:
"200":
description: "Successful response"
content:
application/json:
schema:
$ref: "#/components/schemas/UserListResponse"
examples:
success:
$ref: "#/components/examples/UserListSuccess"
headers:
X-RateLimit-Limit:
$ref: "#/components/headers/X-RateLimit-Limit"
X-RateLimit-Remaining:
$ref: "#/components/headers/X-RateLimit-Remaining"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"429":
$ref: "#/components/responses/TooManyRequests"
post:
operationId: "createUser"
tags:
- "users"
summary: "Create a new user"
description: |
Create a new user account.
A verification email will be sent to the provided email address.
The user must verify their email before they can log in.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateUserRequest"
examples:
basic:
summary: "Basic user creation"
value:
email: "user@example.com"
name: "John Doe"
password: "SecurePassword123!"
withProfile:
summary: "User with profile data"
value:
email: "user@example.com"
name: "John Doe"
password: "SecurePassword123!"
profile:
bio: "Software developer"
location: "San Francisco, CA"
responses:
"201":
description: "User created successfully"
content:
application/json:
schema:
$ref: "#/components/schemas/User"
example:
id: "usr_1234567890"
email: "user@example.com"
name: "John Doe"
status: "pending"
createdAt: "2024-03-15T10:30:00Z"
headers:
Location:
description: "URL of the created user"
schema:
type: "string"
format: "uri"
example: "/users/usr_1234567890"
"400":
$ref: "#/components/responses/BadRequest"
"409":
description: "User already exists"
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
example:
code: "USER_EXISTS"
message: "A user with this email already exists"
"422":
$ref: "#/components/responses/ValidationError"
/users/{userId}:
parameters:
- $ref: "#/components/parameters/UserId"
get:
operationId: "getUser"
tags:
- "users"
summary: "Get user by ID"
description: "Retrieve detailed information about a specific user"
responses:
"200":
description: "Successful response"
content:
application/json:
schema:
$ref: "#/components/schemas/User"
"404":
$ref: "#/components/responses/NotFound"
patch:
operationId: "updateUser"
tags:
- "users"
summary: "Update user"
description: |
Partially update a user's information.
Only the fields provided in the request body will be updated.
To remove a field, set it to null explicitly.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UpdateUserRequest"
responses:
"200":
description: "User updated successfully"
content:
application/json:
schema:
$ref: "#/components/schemas/User"
"400":
$ref: "#/components/responses/BadRequest"
"404":
$ref: "#/components/responses/NotFound"
delete:
operationId: "deleteUser"
tags:
- "users"
summary: "Delete user"
description: |
Permanently delete a user account.
This action cannot be undone. All associated data will be removed.
responses:
"204":
description: "User deleted successfully"
"404":
$ref: "#/components/responses/NotFound"
Components
components:
schemas:
User:
type: "object"
description: "User account information"
required:
- "id"
- "email"
- "name"
- "status"
- "createdAt"
properties:
id:
type: "string"
description: "Unique user identifier"
pattern: "^usr_[a-zA-Z0-9]{10}$"
example: "usr_1234567890"
readOnly: true
email:
type: "string"
format: "email"
description: "User's email address"
example: "user@example.com"
name:
type: "string"
description: "User's display name"
minLength: 1
maxLength: 100
example: "John Doe"
status:
type: "string"
description: "Account status"
enum: ["active", "inactive", "pending", "suspended"]
example: "active"
profile:
$ref: "#/components/schemas/UserProfile"
createdAt:
type: "string"
format: "date-time"
description: "Account creation timestamp"
readOnly: true
example: "2024-03-15T10:30:00Z"
updatedAt:
type: "string"
format: "date-time"
description: "Last update timestamp"
readOnly: true
example: "2024-03-15T10:30:00Z"
UserProfile:
type: "object"
description: "Extended user profile information"
properties:
bio:
type: "string"
description: "User biography"
maxLength: 500
example: "Software developer passionate about APIs"
location:
type: "string"
description: "User's location"
maxLength: 100
example: "San Francisco, CA"
avatarUrl:
type: "string"
format: "uri"
description: "URL to user's avatar image"
example: "https://cdn.example.com/avatars/usr_123.jpg"
timezone:
type: "string"
description: "User's timezone"
example: "America/Los_Angeles"
CreateUserRequest:
type: "object"
description: "Request body for creating a new user"
required:
- "email"
- "name"
- "password"
properties:
email:
type: "string"
format: "email"
description: "User's email address"
example: "user@example.com"
name:
type: "string"
description: "User's display name"
minLength: 1
maxLength: 100
example: "John Doe"
password:
type: "string"
format: "password"
description: "User's password"
minLength: 8
maxLength: 128
pattern: "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$"
example: "SecurePassword123!"
profile:
$ref: "#/components/schemas/UserProfile"
UpdateUserRequest:
type: "object"
description: "Request body for updating a user"
properties:
name:
type: "string"
description: "User's display name"
minLength: 1
maxLength: 100
nullable: true
profile:
$ref: "#/components/schemas/UserProfile"
UserListResponse:
type: "object"
description: "Paginated list of users"
required:
- "data"
- "pagination"
properties:
data:
type: "array"
items:
$ref: "#/components/schemas/User"
pagination:
$ref: "#/components/schemas/Pagination"
Pagination:
type: "object"
description: "Pagination metadata"
required:
- "total"
- "hasMore"
properties:
total:
type: "integer"
description: "Total number of items"
example: 150
hasMore:
type: "boolean"
description: "Whether more items exist"
example: true
nextCursor:
type: "string"
description: "Cursor for next page"
example: "eyJpZCI6MTAwfQ=="
prevCursor:
type: "string"
description: "Cursor for previous page"
example: "eyJpZCI6NTB9"
Error:
type: "object"
description: "Error response"
required:
- "code"
- "message"
properties:
code:
type: "string"
description: "Machine-readable error code"
example: "VALIDATION_ERROR"
message:
type: "string"
description: "Human-readable error message"
example: "The request body is invalid"
details:
type: "array"
description: "Detailed error information"
items:
type: "object"
properties:
field:
type: "string"
description: "Field that caused the error"
example: "email"
message:
type: "string"
description: "Error message for this field"
example: "Must be a valid email address"
requestId:
type: "string"
description: "Request ID for support"
example: "req_abc123xyz"
timestamp:
type: "string"
format: "date-time"
description: "Error timestamp"
example: "2024-03-15T10:30:00Z"
parameters:
UserId:
name: "userId"
in: "path"
description: "User ID"
required: true
schema:
type: "string"
pattern: "^usr_[a-zA-Z0-9]{10}$"
example: "usr_1234567890"
PageSize:
name: "limit"
in: "query"
description: "Number of items per page"
required: false
schema:
type: "integer"
minimum: 1
maximum: 100
default: 20
PageCursor:
name: "cursor"
in: "query"
description: "Pagination cursor"
required: false
schema:
type: "string"
headers:
X-RateLimit-Limit:
description: "Request limit per minute"
schema:
type: "integer"
example: 100
X-RateLimit-Remaining:
description: "Remaining requests in current window"
schema:
type: "integer"
example: 95
X-RateLimit-Reset:
description: "Unix timestamp when limit resets"
schema:
type: "integer"
example: 1710500000
responses:
BadRequest:
description: "Bad request"
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
example:
code: "BAD_REQUEST"
message: "The request could not be processed"
requestId: "req_abc123xyz"
Unauthorized:
description: "Authentication required"
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
example:
code: "UNAUTHORIZED"
message: "Authentication credentials are missing or invalid"
NotFound:
description: "Resource not found"
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
example:
code: "NOT_FOUND"
message: "The requested resource was not found"
ValidationError:
description: "Validation error"
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
example:
code: "VALIDATION_ERROR"
message: "Request validation failed"
details:
- field: "email"
message: "Must be a valid email address"
- field: "password"
message: "Must be at least 8 characters"
TooManyRequests:
description: "Rate limit exceeded"
headers:
Retry-After:
description: "Seconds until rate limit resets"
schema:
type: "integer"
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
example:
code: "RATE_LIMIT_EXCEEDED"
message: "Too many requests. Please try again later."
securitySchemes:
bearerAuth:
type: "http"
scheme: "bearer"
bearerFormat: "JWT"
description: |
JWT authentication token.
Include in the Authorization header:
`Authorization: Bearer <token>`
Tokens expire after 1 hour. Use the refresh token endpoint
to obtain a new access token.
apiKey:
type: "apiKey"
in: "header"
name: "X-API-Key"
description: "API key for server-to-server communication"
examples:
UserListSuccess:
summary: "Successful user list"
value:
data:
- id: "usr_1234567890"
email: "user1@example.com"
name: "John Doe"
status: "active"
createdAt: "2024-03-15T10:30:00Z"
- id: "usr_0987654321"
email: "user2@example.com"
name: "Jane Smith"
status: "active"
createdAt: "2024-03-14T09:00:00Z"
pagination:
total: 150
hasMore: true
nextCursor: "eyJpZCI6MTAwfQ=="
Advanced Features
Webhooks (OpenAPI 3.1)
webhooks:
userCreated:
post:
operationId: "userCreatedWebhook"
summary: "User created event"
description: |
Triggered when a new user account is created.
Your endpoint must respond with a 2xx status code within 30 seconds.
Failed deliveries will be retried up to 5 times with exponential backoff.
requestBody:
required: true
content:
application/json:
schema:
type: "object"
required:
- "event"
- "timestamp"
- "data"
properties:
event:
type: "string"
const: "user.created"
timestamp:
type: "string"
format: "date-time"
data:
$ref: "#/components/schemas/User"
responses:
"200":
description: "Webhook received successfully"
security:
- webhookSignature: []
userUpdated:
post:
operationId: "userUpdatedWebhook"
summary: "User updated event"
description: "Triggered when a user's information is modified"
requestBody:
required: true
content:
application/json:
schema:
type: "object"
properties:
event:
type: "string"
const: "user.updated"
timestamp:
type: "string"
format: "date-time"
data:
type: "object"
properties:
user:
$ref: "#/components/schemas/User"
changes:
type: "object"
description: "Fields that were changed"
responses:
"200":
description: "Webhook received successfully"
Custom Extensions
x-code-samples:
- lang: "curl"
label: "cURL"
source: |
curl -X GET "https://api.example.com/v1/users" \
-H "Authorization: Bearer your_token_here" \
-H "Accept: application/json"
- lang: "javascript"
label: "JavaScript"
source: |
const response = await fetch('https://api.example.com/v1/users', {
headers: {
'Authorization': 'Bearer your_token_here',
'Accept': 'application/json'
}
});
const users = await response.json();
- lang: "python"
label: "Python"
source: |
import requests
response = requests.get(
'https://api.example.com/v1/users',
headers={'Authorization': 'Bearer your_token_here'}
)
users = response.json()
x-rate-limiting:
standard:
limit: 100
window: "1 minute"
premium:
limit: 1000
window: "1 minute"
x-changelog:
- version: "1.0.0"
date: "2024-03-15"
changes:
- "Initial release"
- version: "1.1.0"
date: "2024-04-01"
changes:
- "Added user profile endpoints"
- "Added pagination support"
Validation & Quality
Schema Validation Rules
validation_patterns:
strings:
email:
format: "email"
maxLength: 254
uuid:
format: "uuid"
pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
phone:
pattern: "^\\+[1-9]\\d{1,14}$"
url:
format: "uri"
pattern: "^https?://"
numbers:
positive_integer:
type: "integer"
minimum: 1
percentage:
type: "number"
minimum: 0
maximum: 100
currency:
type: "number"
multipleOf: 0.01
minimum: 0
dates:
date_only:
type: "string"
format: "date"
pattern: "^\\d{4}-\\d{2}-\\d{2}$"
datetime:
type: "string"
format: "date-time"
arrays:
non_empty_array:
type: "array"
minItems: 1
unique_array:
type: "array"
uniqueItems: true
Linting Configuration
# .spectral.yaml
extends: ["spectral:oas"]
rules:
# Naming conventions
operation-operationId-valid-in-url: true
path-keys-no-trailing-slash: true
# Documentation requirements
operation-description: true
operation-tag-defined: true
info-contact: true
# Schema quality
oas3-schema: true
typed-enum: true
# Custom rules
operation-summary-length:
description: "Operation summary should be concise"
severity: warn
given: "$.paths.*[get,post,put,patch,delete]"
then:
field: "summary"
function: length
functionOptions:
max: 80
must-have-examples:
description: "Responses should have examples"
severity: warn
given: "$.paths.*.*.responses.*.content.*"
then:
field: "examples"
function: truthy
Code Generation
Generator Configuration
# openapi-generator-cli.yaml
$schema: https://raw.githubusercontent.com/OpenAPITools/openapi-generator-cli/master/schema.json
spaces: 2
generators:
typescript-axios:
inputSpec: ./api/openapi.yaml
output: ./generated/typescript-client
generatorName: typescript-axios
additionalProperties:
npmName: "@example/api-client"
supportsES6: true
withInterfaces: true
withSeparateModelsAndApi: true
python-client:
inputSpec: ./api/openapi.yaml
output: ./generated/python-client
generatorName: python
additionalProperties:
packageName: "example_api_client"
projectName: "example-api-client"
go-server:
inputSpec: ./api/openapi.yaml
output: ./generated/go-server
generatorName: go-server
additionalProperties:
packageName: "api"
serverPort: 8080
SDK Generation Script
#!/bin/bash
# generate-sdks.sh
SPEC_FILE="./api/openapi.yaml"
OUTPUT_DIR="./generated"
# Validate spec first
npx @redocly/cli lint $SPEC_FILE
if [ $? -ne 0 ]; then
echo "Spec validation failed"
exit 1
fi
# Generate TypeScript client
npx openapi-generator-cli generate \
-i $SPEC_FILE \
-g typescript-axios \
-o $OUTPUT_DIR/typescript \
--additional-properties=npmName=@example/api-client,supportsES6=true
# Generate Python client
npx openapi-generator-cli generate \
-i $SPEC_FILE \
-g python \
-o $OUTPUT_DIR/python \
--additional-properties=packageName=example_api
echo "SDK generation complete"
Documentation Tools
Redoc Configuration
# redoc.yaml
openapi: "./api/openapi.yaml"
output: "./docs/index.html"
options:
theme:
colors:
primary:
main: "#1976d2"
typography:
fontSize: "15px"
fontFamily: "Inter, sans-serif"
code:
fontSize: "13px"
fontFamily: "JetBrains Mono, monospace"
hideDownloadButton: false
hideHostname: false
pathInMiddlePanel: true
requiredPropsFirst: true
sortPropsAlphabetically: false
hideLoading: false
nativeScrollbars: true
jsonSampleExpandLevel: 2
enumSkipQuotes: false
showExtensions: true
Swagger UI Configuration
// swagger-ui-config.js
const swaggerUiOptions = {
dom_id: '#swagger-ui',
url: '/api/openapi.yaml',
// Display options
deepLinking: true,
displayOperationId: false,
defaultModelsExpandDepth: 2,
defaultModelExpandDepth: 2,
displayRequestDuration: true,
docExpansion: 'list',
filter: true,
showExtensions: true,
showCommonExtensions: true,
// Try it out configuration
tryItOutEnabled: true,
supportedSubmitMethods: ['get', 'post', 'put', 'patch', 'delete'],
// Request interceptor for auth
requestInterceptor: (request) => {
const token = localStorage.getItem('api_token');
if (token) {
request.headers.Authorization = `Bearer ${token}`;
}
return request;
},
// Plugins
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
// Layout
layout: "StandaloneLayout",
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
]
};
Лучшие практики
- Version everything — используйте семантическое версионирование
- Examples for all — добавляйте реалистичные примеры для всех схем
- Error documentation — документируйте все возможные коды ошибок
- Consistent naming — kebab-case для paths, camelCase для properties
- Reusable components — выносите общие схемы в components
- Validate specs — используйте линтеры (Spectral, Redocly)
FAQ
What does the openapi-documentation skill do?
Эксперт по OpenAPI документации. Используй для создания Swagger спецификаций, API schemas и автогенерации документации.
How do I install openapi-documentation?
Run npx skills add https://github.com/dengineproblem/agents-monorepo --skill openapi-documentation in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/openapi-documentation/ (personal) or .claude/skills/openapi-documentation/ (project).
Which AI agents can use openapi-documentation?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is openapi-documentation safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains openapi-documentation?
It is published by dengineproblem in dengineproblem/agents-monorepo. It has 70 recorded installs.
More from dengineproblem/agents-monorepo
social-media-marketing
dengineproblem/agents-monorepo
Эксперт по SMM. Используй для стратегий в Instagram, Facebook, TikTok, LinkedIn, контент-планов и community management.
frontend-design
dengineproblem/agents-monorepo
Open the skill to read its SKILL.md instructions.
video-marketing
dengineproblem/agents-monorepo
Open the skill to read its SKILL.md instructions.
k6-load-test
dengineproblem/agents-monorepo
Open the skill to read its SKILL.md instructions.
b2b-saas-marketing
dengineproblem/agents-monorepo
Open the skill to read its SKILL.md instructions.
seo-expert
dengineproblem/agents-monorepo
Open the skill to read its SKILL.md instructions.
Popular docs & writing skills
grill-with-docs
mattpocock/skills
A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go.
lark-markdown
open.feishu.cn
飞书 Markdown:查看、创建、上传、编辑和比较飞书中的原生 Markdown 文件。当用户要操作飞书 Markdown 文件,或比较其远端版本及本地草稿时使用。纯本地 Markdown 文件操作不触发本 skill。不负责将 Markdown 导入为飞书在线文档,也不负责文件搜索、权限、评论、移动、删除等云空间管理操作。
writing-beats
mattpocock/skills
Writing, exploit; assemble raw material into a journey of beats, grounding each term before a beat leans on it.
writing-shape
mattpocock/skills
Writing, exploit: shape raw material into an article, paragraph by paragraph.
writing-fragments
mattpocock/skills
Writing, explore: mine raw fragments, no structure yet.
writing-for-agents
mattpocock/skills
Writing documents for agents. Use when creating or editing skills, or modifying AGENTS.md or CLAUDE.md.