openapi-documentation

OpenAPI Documentation Expert

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "openapi-documentation" with this command: npx skills add dengineproblem/agents-monorepo/dengineproblem-agents-monorepo-openapi-documentation

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:

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)

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

social-media-marketing

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

video-marketing

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

frontend-design

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

k6-load-test

No summary provided by upstream source.

Repository SourceNeeds Review