Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
erichowens avatar

Openapi Spec Writer

  • 113 installs
  • 178 repo stars
  • Updated July 14, 2026
  • erichowens/some_claude_skills

Write OpenAPI 3.0/3.1 specifications for REST APIs with schema design and documentation.

About

Generates comprehensive API contracts with schemas, examples, authentication, and server configurations. Integrates with Swagger UI, Redoc, Spectral linting, and SDK generation.

  • Schema design with discriminators and composition patterns
  • Markdown in descriptions for rich documentation

Openapi Spec Writer by the numbers

  • 113 all-time installs (skills.sh)
  • Ranked #629 of 1,879 Documentation skills by installs in the Skillselion catalog
  • Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/erichowens/some_claude_skills --skill openapi-spec-writer

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs113
repo stars178
Last updatedJuly 14, 2026
Repositoryerichowens/some_claude_skills

What it does

Write OpenAPI 3.0/3.1 specifications for REST APIs with schema design and documentation.

Files

SKILL.mdMarkdownGitHub ↗

OpenAPI Spec Writer

Overview

Expert in writing OpenAPI 3.0/3.1 specifications for REST APIs. Specializes in schema design, documentation best practices, API-first development, and tooling integration. Generates comprehensive API documentation that serves as both documentation and contract.

When to Use

  • Creating OpenAPI specifications for new APIs
  • Documenting existing REST APIs
  • Designing API contracts before implementation
  • Generating client SDKs from specs
  • Setting up interactive API documentation (Swagger UI, Redoc)
  • Validating API responses against schemas
  • Migrating from OpenAPI 2.0 (Swagger) to 3.x

Capabilities

Specification Writing

  • OpenAPI 3.0 and 3.1 syntax
  • Path and operation definitions
  • Request/response schemas
  • Authentication schemes
  • Server configurations

Schema Design

  • JSON Schema with OpenAPI extensions
  • Reusable component schemas
  • Discriminators for polymorphism
  • oneOf, anyOf, allOf composition
  • Nullable types and defaults

Documentation Quality

  • Meaningful descriptions and examples
  • Markdown in descriptions
  • Request/response examples
  • Error response documentation
  • Deprecation notices

Tooling Integration

  • Swagger UI configuration
  • Redoc customization
  • Spectral linting rules
  • SDK generation setup
  • Mock server configuration

Dependencies

Works well with:

  • api-architect - API design patterns
  • rest-api-design - RESTful conventions
  • typescript-pro - Generated client types
  • github-actions-pipeline-builder - CI validation

Examples

Complete OpenAPI 3.1 Spec

openapi: 3.1.0
info:
  title: Task Management API
  description: |
    RESTful API for managing tasks and projects.

    ## Authentication
    All endpoints require a Bearer token in the Authorization header.

    ## Rate Limiting
    - 1000 requests per hour per API key
    - Rate limit headers included in all responses
  version: 1.0.0
  contact:
    name: API Support
    email: api@example.com
    url: https://docs.example.com
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT

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: Local development

tags:
  - name: Tasks
    description: Task management operations
  - name: Projects
    description: Project management operations

paths:
  /tasks:
    get:
      operationId: listTasks
      summary: List all tasks
      description: Returns a paginated list of tasks with optional filtering.
      tags:
        - Tasks
      parameters:
        - $ref: '#/components/parameters/PageParam'
        - $ref: '#/components/parameters/LimitParam'
        - name: status
          in: query
          description: Filter by task status
          schema:
            $ref: '#/components/schemas/TaskStatus'
        - name: project_id
          in: query
          description: Filter by project ID
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskListResponse'
              examples:
                default:
                  $ref: '#/components/examples/TaskListExample'
          headers:
            X-Total-Count:
              schema:
                type: integer
              description: Total number of tasks matching the query
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'

    post:
      operationId: createTask
      summary: Create a new task
      description: Creates a new task and returns the created resource.
      tags:
        - Tasks
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateTaskRequest'
            examples:
              minimal:
                summary: Minimal task
                value:
                  title: "Complete documentation"
              full:
                summary: Full task with all fields
                value:
                  title: "Complete documentation"
                  description: "Write API docs for v1.0"
                  project_id: "550e8400-e29b-41d4-a716-446655440000"
                  due_date: "2024-12-31"
                  priority: "high"
      responses:
        '201':
          description: Task created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
          headers:
            Location:
              schema:
                type: string
                format: uri
              description: URL of the created resource
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/ValidationError'

  /tasks/{taskId}:
    parameters:
      - $ref: '#/components/parameters/TaskIdParam'

    get:
      operationId: getTask
      summary: Get a task by ID
      tags:
        - Tasks
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
        '404':
          $ref: '#/components/responses/NotFound'

    patch:
      operationId: updateTask
      summary: Update a task
      description: Partially updates a task. Only provided fields are updated.
      tags:
        - Tasks
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateTaskRequest'
      responses:
        '200':
          description: Task updated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/ValidationError'

    delete:
      operationId: deleteTask
      summary: Delete a task
      tags:
        - Tasks
      responses:
        '204':
          description: Task deleted successfully
        '404':
          $ref: '#/components/responses/NotFound'

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT token obtained from /auth/login

  parameters:
    TaskIdParam:
      name: taskId
      in: path
      required: true
      description: Unique task identifier
      schema:
        type: string
        format: uuid
      example: "550e8400-e29b-41d4-a716-446655440000"

    PageParam:
      name: page
      in: query
      description: Page number for pagination (1-indexed)
      schema:
        type: integer
        minimum: 1
        default: 1

    LimitParam:
      name: limit
      in: query
      description: Number of items per page
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 20

  schemas:
    Task:
      type: object
      required:
        - id
        - title
        - status
        - created_at
        - updated_at
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier
          readOnly: true
        title:
          type: string
          minLength: 1
          maxLength: 200
          description: Task title
        description:
          type: string
          maxLength: 5000
          description: Detailed task description (supports Markdown)
        status:
          $ref: '#/components/schemas/TaskStatus'
        priority:
          $ref: '#/components/schemas/Priority'
        project_id:
          type: string
          format: uuid
          description: Associated project ID
        due_date:
          type: string
          format: date
          description: Due date (ISO 8601)
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true

    TaskStatus:
      type: string
      enum:
        - pending
        - in_progress
        - completed
        - cancelled
      description: Current task status
      default: pending

    Priority:
      type: string
      enum:
        - low
        - medium
        - high
        - urgent
      default: medium

    CreateTaskRequest:
      type: object
      required:
        - title
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 200
        description:
          type: string
          maxLength: 5000
        project_id:
          type: string
          format: uuid
        due_date:
          type: string
          format: date
        priority:
          $ref: '#/components/schemas/Priority'

    UpdateTaskRequest:
      type: object
      minProperties: 1
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 200
        description:
          type: string
          maxLength: 5000
        status:
          $ref: '#/components/schemas/TaskStatus'
        priority:
          $ref: '#/components/schemas/Priority'
        due_date:
          type: string
          format: date

    TaskListResponse:
      type: object
      required:
        - data
        - pagination
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Task'
        pagination:
          $ref: '#/components/schemas/Pagination'

    Pagination:
      type: object
      required:
        - page
        - limit
        - total
        - total_pages
      properties:
        page:
          type: integer
        limit:
          type: integer
        total:
          type: integer
        total_pages:
          type: integer
        has_next:
          type: boolean
        has_prev:
          type: boolean

    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: Machine-readable error code
        message:
          type: string
          description: Human-readable error message
        details:
          type: object
          additionalProperties: true
          description: Additional error details

    ValidationError:
      allOf:
        - $ref: '#/components/schemas/Error'
        - type: object
          properties:
            errors:
              type: array
              items:
                type: object
                properties:
                  field:
                    type: string
                  message:
                    type: string

  responses:
    BadRequest:
      description: Bad request - invalid parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: "BAD_REQUEST"
            message: "Invalid query parameters"

    Unauthorized:
      description: Authentication required
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: "UNAUTHORIZED"
            message: "Invalid or expired token"

    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            code: "NOT_FOUND"
            message: "Task not found"

    ValidationError:
      description: Validation failed
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ValidationError'
          example:
            code: "VALIDATION_ERROR"
            message: "Request validation failed"
            errors:
              - field: "title"
                message: "Title is required"

  examples:
    TaskListExample:
      value:
        data:
          - id: "550e8400-e29b-41d4-a716-446655440000"
            title: "Complete documentation"
            status: "in_progress"
            priority: "high"
            created_at: "2024-01-15T10:30:00Z"
            updated_at: "2024-01-15T10:30:00Z"
        pagination:
          page: 1
          limit: 20
          total: 42
          total_pages: 3
          has_next: true
          has_prev: false

security:
  - bearerAuth: []

Polymorphic Schemas (Discriminator)

components:
  schemas:
    Notification:
      type: object
      required:
        - id
        - type
        - created_at
      discriminator:
        propertyName: type
        mapping:
          email: '#/components/schemas/EmailNotification'
          sms: '#/components/schemas/SmsNotification'
          push: '#/components/schemas/PushNotification'
      properties:
        id:
          type: string
          format: uuid
        type:
          type: string
          enum: [email, sms, push]
        created_at:
          type: string
          format: date-time

    EmailNotification:
      allOf:
        - $ref: '#/components/schemas/Notification'
        - type: object
          required:
            - to
            - subject
          properties:
            to:
              type: string
              format: email
            subject:
              type: string
            body:
              type: string

    SmsNotification:
      allOf:
        - $ref: '#/components/schemas/Notification'
        - type: object
          required:
            - phone_number
            - message
          properties:
            phone_number:
              type: string
              pattern: '^\+[1-9]\d{1,14}$'
            message:
              type: string
              maxLength: 160

Spectral Linting Rules

# .spectral.yaml
extends: ["spectral:oas"]

rules:
  # Enforce operation IDs
  operation-operationId: error

  # Require descriptions
  operation-description: error
  oas3-schema-description: warn

  # Naming conventions
  path-casing:
    given: "$.paths[*]~"
    then:
      function: casing
      functionOptions:
        type: kebab

  # Security requirements
  operation-security-defined: error

  # Response codes
  operation-success-response: error

  # Custom: require examples
  require-examples:
    message: "Responses should have examples"
    given: "$.paths.*.*.responses.*.content.*.schema"
    then:
      field: example
      function: truthy

Best Practices

1. Use components - Extract reusable schemas, parameters, responses 2. Provide examples - Real-world examples for every schema 3. Meaningful descriptions - Markdown-formatted, explain business context 4. Consistent naming - kebab-case paths, camelCase properties 5. Version your API - Include version in URL or header 6. Document errors - Define all error responses with examples 7. Use operationId - Unique, descriptive IDs for SDK generation 8. Validate with linting - Use Spectral to enforce standards 9. Keep spec in sync - Automate validation in CI

Common Pitfalls

  • Missing required fields - Forgetting to mark fields as required
  • Inconsistent naming - Mixing snake_case and camelCase
  • Generic descriptions - "Returns data" instead of specific details
  • No examples - Makes spec hard to understand
  • Outdated spec - Spec doesn't match implementation
  • Overusing anyOf - Makes schemas hard to understand
  • Missing error responses - Only documenting happy path
  • No pagination - List endpoints without pagination info

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.