claude/skills/openapi-specialist/SKILL.md
OpenAPI specification expert for creating, improving, and validating clear, self-documenting API specs. Use when designing, reviewing, or refactoring OpenAPI/Swagger specs for clarity, consistency, and usability.
npx skillsauth add b-galati/dotfiles openapi-specialistInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill provides expert guidance for creating, improving, and maintaining high-quality OpenAPI specifications that are self-documenting and easy to consume.
Use make oas-lint to validate your changes at the end.
Use this skill when:
The spec should be understandable without external documentation:
# ✅ GOOD - Self-documenting
/workflows/{id}:
get:
summary: Retrieve a specific workflow
description: |
Fetches a workflow by ID along with all its associated metadata.
Requires read access to the workflow's workspace.
operationId: getWorkflow
parameters:
- name: id
in: path
required: true
description: The UUID of the workflow to retrieve
schema:
type: string
format: uuid
responses:
'200':
description: Workflow retrieved successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Workflow'
# ❌ POOR - Unclear and vague
/workflows/{id}:
get:
summary: Get workflow
operationId: getWorkflowById
parameters:
- name: id
in: path
required: true
schema:
type: string
additionalProperties: true without reasonminLength, maxLength, pattern for stringsminimum, maximum for numbers# ✅ PRECISE
properties:
name:
type: string
minLength: 1
maxLength: 255
description: The workflow name
status:
type: string
enum: [draft, active, archived]
description: Current workflow state
priority:
type: integer
minimum: 0
maximum: 4
description: Priority level (0=none, 1=urgent, 4=low)
# ❌ VAGUE
properties:
name:
type: string
status:
type: string
priority:
type: integer
$ref to reference common schemasopenapi: 3.1.0
info:
title: Yousign API
version: 3.0.0
description: |
The Yousign document signing and workflow API.
## Authentication
Use Bearer tokens in the Authorization header:
```
Authorization: Bearer your-api-token
```
## Rate Limiting
Requests are limited to 100 per minute per API token.
contact:
name: Yousign Support
url: https://support.yousign.com
email: [email protected]
license:
name: Proprietary
url: https://yousign.com/legal
servers:
- url: https://api.yousign.com/v3
description: Production API
- url: https://sandbox.yousign.com/v3
description: Sandbox for testing
tags:
- name: Workflows
description: Workflow management and execution
- name: Signatures
description: Signature requests and tracking
- name: Documents
description: Document upload and management
paths:
# ... endpoints here
components:
# ... schemas, responses, parameters here
paths:
/workflows:
get:
tags: [Workflows]
summary: List workflows
operationId: listWorkflows
description: |
Retrieves a paginated list of workflows in the authenticated user's workspace.
Results are ordered by creation date (newest first).
parameters:
- $ref: '#/components/parameters/PageParam'
- $ref: '#/components/parameters/LimitParam'
- name: status
in: query
schema:
type: string
enum: [draft, active, archived]
description: Filter by workflow status
responses:
'200':
$ref: '#/components/responses/WorkflowList'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
post:
tags: [Workflows]
summary: Create a workflow
operationId: createWorkflow
description: Creates a new workflow in the authenticated user's workspace.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateWorkflowInput'
examples:
basic:
summary: Basic workflow creation
value:
name: Sales Agreement Review
description: Contract review process
responses:
'201':
description: Workflow created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Workflow'
'400':
$ref: '#/components/responses/ValidationError'
'401':
$ref: '#/components/responses/Unauthorized'
Create base schemas that are composed into others:
components:
schemas:
# Base schemas (used as building blocks)
Timestamp:
type: object
properties:
createdAt:
type: string
format: date-time
description: When the resource was created
updatedAt:
type: string
format: date-time
description: When the resource was last updated
required: [createdAt, updatedAt]
# UUID reference
IdField:
type: string
format: uuid
description: Unique identifier
# Error response
ErrorResponse:
type: object
properties:
type:
type: string
description: Machine-readable error type
title:
type: string
description: Human-readable error title
detail:
type: string
description: Detailed explanation
status:
type: integer
description: HTTP status code
required: [type, title, status]
# Pagination metadata
PaginationMeta:
type: object
properties:
page:
type: integer
minimum: 1
description: Current page number
limit:
type: integer
minimum: 1
maximum: 100
description: Items per page
total:
type: integer
description: Total number of items
pages:
type: integer
description: Total number of pages
required: [page, limit, total, pages]
# Domain models
Workflow:
allOf:
- $ref: '#/components/schemas/IdField'
- $ref: '#/components/schemas/Timestamp'
- type: object
properties:
name:
type: string
minLength: 1
maxLength: 255
description: Workflow name
status:
type: string
enum: [draft, active, archived]
description: Current status
workspaceId:
$ref: '#/components/schemas/IdField'
creatorId:
$ref: '#/components/schemas/IdField'
required: [id, name, status, workspaceId, creatorId, createdAt, updatedAt]
# Input schemas
CreateWorkflowInput:
type: object
properties:
name:
type: string
minLength: 1
maxLength: 255
description: Workflow name
description:
type: string
maxLength: 1000
description: Optional workflow description
workspaceId:
$ref: '#/components/schemas/IdField'
required: [name, workspaceId]
Prefer allOf for composing schemas:
# ✅ GOOD - Composable
Workflow:
allOf:
- $ref: '#/components/schemas/BaseEntity'
- $ref: '#/components/schemas/Timestamps'
- type: object
properties:
name: { type: string }
# ❌ AVOID - Duplication
Workflow:
type: object
properties:
id: { type: string, format: uuid }
createdAt: { type: string, format: date-time }
updatedAt: { type: string, format: date-time }
name: { type: string }
Always specify required arrays:
# ✅ EXPLICIT
User:
type: object
properties:
id:
type: string
format: uuid
email:
type: string
format: email
name:
type: string
role:
type: string
enum: [admin, user, viewer]
required: [id, email, name] # role is optional
# ❌ UNCLEAR - Which fields are required?
User:
type: object
properties:
id:
type: string
format: uuid
email:
type: string
format: email
name:
type: string
role:
type: string
enum: [admin, user, viewer]
components:
responses:
BadRequest:
description: Request validation failed
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/ErrorResponse'
- type: object
properties:
violations:
type: array
items:
type: object
properties:
propertyPath:
type: string
message:
type: string
code:
type: string
description: List of validation violations
examples:
invalid_email:
value:
type: 'https://tools.ietf.org/html/rfc2616#section-10'
title: Validation Failed
detail: email must be a valid email address
status: 400
violations:
- propertyPath: email
message: This is not a valid email.
code: invalid_format
Unauthorized:
description: Authentication required or invalid credentials
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
type: 'https://tools.ietf.org/html/rfc2616#section-10'
title: Unauthorized
detail: Valid authentication credentials required
status: 401
Forbidden:
description: Insufficient permissions
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
type: 'https://tools.ietf.org/html/rfc2616#section-10'
title: Access Denied
detail: You do not have permission to access this resource
status: 403
NotFound:
description: Resource not found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
type: 'https://tools.ietf.org/html/rfc2616#section-10'
title: Not Found
detail: The requested workflow could not be found
status: 404
components:
responses:
WorkflowList:
description: Paginated list of workflows
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Workflow'
meta:
$ref: '#/components/schemas/PaginationMeta'
required: [data, meta]
example:
data:
- id: 123e4567-e89b-12d3-a456-426614174000
name: Sales Agreement
status: active
workspaceId: 550e8400-e29b-41d4-a716-446655440000
creatorId: 6ba7b810-9dad-11d1-80b4-00c04fd430c8
createdAt: 2024-01-15T10:30:00Z
updatedAt: 2024-01-15T14:22:00Z
meta:
page: 1
limit: 20
total: 45
pages: 3
components:
parameters:
IdPath:
name: id
in: path
required: true
schema:
type: string
format: uuid
description: The resource UUID
PageParam:
name: page
in: query
schema:
type: integer
minimum: 1
default: 1
description: Page number (starts at 1)
LimitParam:
name: limit
in: query
schema:
type: integer
minimum: 1
maximum: 100
default: 20
description: Number of results per page
SortParam:
name: sort
in: query
schema:
type: string
enum: [name, created_at, updated_at]
default: created_at
description: Sort by field
OrderParam:
name: order
in: query
schema:
type: string
enum: [asc, desc]
default: desc
description: Sort order
paths:
/workflows:
post:
requestBody:
required: true
description: Workflow creation details
content:
application/json:
schema:
$ref: '#/components/schemas/CreateWorkflowInput'
examples:
minimal:
summary: Minimal workflow
value:
name: Simple Process
workspaceId: 550e8400-e29b-41d4-a716-446655440000
full:
summary: Complete workflow
value:
name: Complex Multi-Step Process
description: Comprehensive workflow with all optional fields
workspaceId: 550e8400-e29b-41d4-a716-446655440000
components:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: |
Authenticate using a Bearer token in the Authorization header.
Example:
```
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```
security:
- BearerAuth: []
# Override security for specific endpoints
paths:
/auth/login:
post:
security: [] # Public endpoint, no auth required
When creating or reviewing an OpenAPI spec:
summary for every endpoint (1-2 sentences)description explaining purpose and preconditionsdescriptiondescription/resources/{id} for single item)typeminimum/maximum or rangesminLength/maxLength or patternsrequired arrays specify mandatory fieldstype: object without properties definedcomponents/schemascomponents/parameterscomponents/responses$ref to avoid duplicationallOf for schema compositionsecuritySchemes/v3/) or header# WRONG - No context
paths:
/workflows/{id}:
get:
summary: Get workflow
operationId: getWorkflow
# GOOD - Self-documenting
paths:
/workflows/{id}:
get:
summary: Retrieve a workflow
description: |
Fetches a workflow by ID with all associated metadata.
The authenticated user must have read access to the workflow's workspace.
For templates, the creator or organization admin can read.
operationId: getWorkflow
# Different error formats
responses:
'400':
schema:
properties:
error: { type: string }
'404':
schema:
properties:
message: { type: string }
# All errors use same schema
responses:
'400':
$ref: '#/components/responses/ValidationError'
'404':
$ref: '#/components/responses/NotFound'
properties:
data:
type: object # What's in this object?
items:
type: array # Array of what?
properties:
data:
$ref: '#/components/schemas/Workflow'
items:
type: array
items:
$ref: '#/components/schemas/WorkflowSignature'
High-quality OpenAPI specs are:
Following these patterns makes your API:
testing
TDD workflow - Write a failing test, then implement Super Green
testing
Implement behaviors from a specification file produced by the local-create-spec skill. Use when the user says 'implement behaviors from ...', 'implement the spec', 'implement spec ...', or wants to implement a .specs/ markdown file containing Given/When/Then behaviors with checkboxes.
tools
Implement a Linear issue by breaking its acceptance criteria into tasks, implementing each with TDD, and updating the Linear issue status when done. Use when the user says 'implement issue ...', 'implement TEAM-123', or wants to implement a Linear issue.
testing
Interview the user relentlessly about a plan or design until reaching shared understanding, resolving each branch of the decision tree. Use when user wants to stress-test a plan, get grilled on their design, or mentions "grill me".