Claude-skill-registry api-documentation-writer
Expert guide for writing comprehensive API documentation including OpenAPI specs, endpoint references, authentication guides, and code examples. Use when documenting APIs, creating developer portals, or improving API discoverability.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/api-documentation-writer" ~/.claude/skills/majiayu000-claude-skill-registry-api-documentation-writer && rm -rf "$T"
manifest:
skills/data/api-documentation-writer/SKILL.mdsafety · automated scan (low risk)
This is a pattern-based risk scan, not a security review. Our crawler flagged:
- makes HTTP requests (curl)
- references API keys
Always read a skill's source content before installing. Patterns alone don't mean the skill is malicious — but they warrant attention.
source content
API Documentation Writer Skill
Overview
This skill helps you create clear, comprehensive API documentation that developers love. Covers OpenAPI/Swagger specifications, endpoint references, authentication guides, code examples in multiple languages, and developer experience best practices.
Documentation Philosophy
The Three C's
- Clear: Unambiguous, jargon-free explanations
- Complete: All parameters, responses, and edge cases documented
- Current: Always in sync with the actual API behavior
What to Document
- DO: Document every public endpoint
- DO: Include request/response examples for all scenarios
- DO: Document error codes with remediation steps
- DO: Provide code examples in popular languages
- DON'T: Document internal/private endpoints
- DON'T: Assume readers know your domain
- DON'T: Let documentation drift from implementation
OpenAPI Specification
Basic Structure
# openapi.yaml openapi: 3.1.0 info: title: My API version: 1.0.0 description: | Welcome to the My API documentation. ## Getting Started 1. Sign up for an API key at [dashboard.example.com](https://dashboard.example.com) 2. Include your key in the `Authorization` header 3. Start making requests! ## Rate Limits - Free tier: 100 requests/minute - Pro tier: 1000 requests/minute contact: name: API Support email: api@example.com url: https://support.example.com license: name: MIT url: https://opensource.org/licenses/MIT servers: - url: https://api.example.com/v1 description: Production - url: https://staging-api.example.com/v1 description: Staging tags: - name: Users description: User management operations - name: Items description: Item CRUD operations
Endpoint Documentation
paths: /users: get: tags: - Users summary: List all users description: | Retrieves a paginated list of users. Results are sorted by creation date (newest first). **Permissions required:** `users:read` operationId: listUsers parameters: - name: page in: query description: Page number (1-indexed) required: false schema: type: integer minimum: 1 default: 1 example: 1 - name: limit in: query description: Number of results per page (max 100) required: false schema: type: integer minimum: 1 maximum: 100 default: 20 example: 20 - name: status in: query description: Filter by user status required: false schema: type: string enum: [active, inactive, pending] responses: '200': description: Successful response content: application/json: schema: $ref: '#/components/schemas/UserList' example: data: - id: "usr_123" email: "john@example.com" name: "John Doe" status: "active" created_at: "2024-01-15T10:30:00Z" meta: page: 1 limit: 20 total: 150 total_pages: 8 '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '429': $ref: '#/components/responses/RateLimited' post: tags: - Users summary: Create a new user description: | Creates a new user account. An email verification will be sent to the provided address. **Permissions required:** `users:write` operationId: createUser requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateUserRequest' examples: basic: summary: Basic user creation value: email: "jane@example.com" name: "Jane Doe" with_metadata: summary: User with metadata value: email: "jane@example.com" name: "Jane Doe" metadata: department: "Engineering" role: "Developer" responses: '201': description: User created successfully content: application/json: schema: $ref: '#/components/schemas/User' '400': $ref: '#/components/responses/BadRequest' '409': description: User with this email already exists content: application/json: schema: $ref: '#/components/schemas/Error' example: error: code: "USER_EXISTS" message: "A user with this email already exists"
Schema Definitions
components: schemas: User: type: object description: Represents a user in the system required: - id - email - status - created_at properties: id: type: string description: Unique identifier (prefixed with `usr_`) pattern: '^usr_[a-zA-Z0-9]+$' example: "usr_123abc" email: type: string format: email description: User's email address (unique) example: "user@example.com" name: type: string description: User's display name maxLength: 100 example: "John Doe" status: type: string enum: [active, inactive, pending] description: | Account status: - `active`: User can sign in and use the service - `inactive`: Account has been deactivated - `pending`: Awaiting email verification example: "active" metadata: type: object additionalProperties: true description: Custom key-value pairs for storing additional data example: department: "Engineering" created_at: type: string format: date-time description: ISO 8601 timestamp of account creation example: "2024-01-15T10:30:00Z" updated_at: type: string format: date-time description: ISO 8601 timestamp of last update example: "2024-01-16T14:45:00Z" CreateUserRequest: type: object required: - email properties: email: type: string format: email description: Email address for the new user (must be unique) name: type: string description: User's display name maxLength: 100 metadata: type: object additionalProperties: true Error: type: object required: - error properties: error: type: object required: - code - message properties: code: type: string description: Machine-readable error code message: type: string description: Human-readable error description details: type: array description: Additional error details for validation errors items: type: object properties: field: type: string message: type: string
Authentication Documentation
components: securitySchemes: BearerAuth: type: http scheme: bearer bearerFormat: JWT description: | JWT token obtained from the `/auth/token` endpoint. Include in requests as: ``` Authorization: Bearer <your-token> ``` Tokens expire after 1 hour. Use refresh tokens for long-lived sessions. ApiKeyAuth: type: apiKey in: header name: X-API-Key description: | API key for server-to-server communication. Obtain your key from the [Developer Dashboard](https://dashboard.example.com). Include in requests as: ``` X-API-Key: <your-api-key> ``` security: - BearerAuth: [] - ApiKeyAuth: []
Reusable Responses
components: responses: BadRequest: description: Invalid request parameters content: application/json: schema: $ref: '#/components/schemas/Error' examples: validation_error: summary: Validation error value: error: code: "VALIDATION_ERROR" message: "Request validation failed" details: - field: "email" message: "Must be a valid email address" missing_field: summary: Missing required field value: error: code: "MISSING_FIELD" message: "Required field 'email' is missing" Unauthorized: description: Missing or invalid authentication content: application/json: schema: $ref: '#/components/schemas/Error' example: error: code: "UNAUTHORIZED" message: "Invalid or expired authentication token" Forbidden: description: Insufficient permissions content: application/json: schema: $ref: '#/components/schemas/Error' example: error: code: "FORBIDDEN" message: "You don't have permission to access this resource" NotFound: description: Resource not found content: application/json: schema: $ref: '#/components/schemas/Error' example: error: code: "NOT_FOUND" message: "The requested resource was not found" RateLimited: description: Rate limit exceeded headers: X-RateLimit-Limit: schema: type: integer description: Request limit per minute X-RateLimit-Remaining: schema: type: integer description: Remaining requests in current window X-RateLimit-Reset: schema: type: integer description: Unix timestamp when the rate limit resets content: application/json: schema: $ref: '#/components/schemas/Error' example: error: code: "RATE_LIMITED" message: "Too many requests. Please retry after 60 seconds"
Markdown Documentation
Endpoint Reference Template
# Create User Create a new user account. ## Endpoint
POST /v1/users
## Authentication Requires API key with `users:write` permission. ## Request Body | Field | Type | Required | Description | |-------|------|----------|-------------| | `email` | string | Yes | User's email address (must be unique) | | `name` | string | No | Display name (max 100 characters) | | `metadata` | object | No | Custom key-value pairs | ### Example Request ```bash curl -X POST https://api.example.com/v1/users \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "email": "jane@example.com", "name": "Jane Doe" }'
Response
Success (201 Created)
{ "id": "usr_abc123", "email": "jane@example.com", "name": "Jane Doe", "status": "pending", "created_at": "2024-01-15T10:30:00Z" }
Errors
| Status | Code | Description |
|---|---|---|
| 400 | | Invalid email format or missing required field |
| 401 | | Invalid or missing authentication |
| 409 | | User with this email already exists |
| 429 | | Too many requests |
Error Example
{ "error": { "code": "USER_EXISTS", "message": "A user with this email already exists" } }
## Code Examples ### Multi-Language Examples ```markdown ## Code Examples ### cURL ```bash curl -X GET "https://api.example.com/v1/users?limit=10" \ -H "Authorization: Bearer YOUR_TOKEN"
JavaScript (fetch)
const response = await fetch('https://api.example.com/v1/users?limit=10', { headers: { 'Authorization': 'Bearer YOUR_TOKEN' } }); const data = await response.json(); console.log(data);
JavaScript (axios)
import axios from 'axios'; const { data } = await axios.get('https://api.example.com/v1/users', { params: { limit: 10 }, headers: { 'Authorization': 'Bearer YOUR_TOKEN' } });
Python
import requests response = requests.get( 'https://api.example.com/v1/users', params={'limit': 10}, headers={'Authorization': 'Bearer YOUR_TOKEN'} ) data = response.json() print(data)
Ruby
require 'net/http' require 'json' uri = URI('https://api.example.com/v1/users?limit=10') request = Net::HTTP::Get.new(uri) request['Authorization'] = 'Bearer YOUR_TOKEN' response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| http.request(request) end data = JSON.parse(response.body) puts data
Go
package main import ( "encoding/json" "fmt" "net/http" ) func main() { req, _ := http.NewRequest("GET", "https://api.example.com/v1/users?limit=10", nil) req.Header.Set("Authorization", "Bearer YOUR_TOKEN") client := &http.Client{} resp, _ := client.Do(req) defer resp.Body.Close() var data map[string]interface{} json.NewDecoder(resp.Body).Decode(&data) fmt.Println(data) }
## Error Documentation ### Error Code Reference ```markdown # Error Codes All API errors follow a consistent format: ```json { "error": { "code": "ERROR_CODE", "message": "Human-readable description", "details": [] // Optional additional information } }
Authentication Errors
| Code | HTTP Status | Description | Resolution |
|---|---|---|---|
| 401 | Missing or invalid token | Include a valid header |
| 401 | Token has expired | Obtain a new token via |
| 401 | API key not recognized | Check your API key in the dashboard |
| 403 | Insufficient permissions | Request appropriate scopes for your token |
Validation Errors
| Code | HTTP Status | Description | Resolution |
|---|---|---|---|
| 400 | Request body validation failed | Check the array for specific fields |
| 400 | Required field not provided | Include all required fields |
| 400 | Field format is incorrect | Match the expected format (see schema) |
Resource Errors
| Code | HTTP Status | Description | Resolution |
|---|---|---|---|
| 404 | Resource doesn't exist | Verify the resource ID is correct |
| 409 | Resource already exists | Use a different identifier or update existing |
| 409 | State conflict | Refresh and retry the operation |
Rate Limiting
| Code | HTTP Status | Description | Resolution |
|---|---|---|---|
| 429 | Too many requests | Wait and retry (see header) |
## Changelog Documentation ### API Changelog Format ```markdown # API Changelog ## 2024-01-15 - v1.2.0 ### Added - `GET /users/{id}/activity` - Retrieve user activity history - `metadata` field on User object for custom data storage ### Changed - Pagination now 1-indexed (previously 0-indexed) - Rate limits increased: Free tier 100 → 200 req/min ### Deprecated - `GET /users/search` - Use `GET /users` with query parameters instead - Will be removed in v2.0.0 ### Fixed - `created_at` now correctly returns UTC timezone --- ## 2024-01-01 - v1.1.0 ### Added - Webhook support for user events - `status` filter on `GET /users` ### Security - API keys now support IP allowlisting
Interactive Documentation
Swagger UI Configuration
// swagger-config.js const swaggerUiOptions = { customCss: '.swagger-ui .topbar { display: none }', customSiteTitle: 'API Documentation', customfavIcon: '/favicon.ico', swaggerOptions: { persistAuthorization: true, displayRequestDuration: true, filter: true, tryItOutEnabled: true, }, };
Redoc Configuration
# redoc.yaml x-tagGroups: - name: Getting Started tags: - Authentication - name: Core Resources tags: - Users - Items - name: Utilities tags: - Webhooks - Health x-logo: url: 'https://example.com/logo.png' altText: 'API Logo'
Documentation Checklist
Per Endpoint
- Summary (one line)
- Description (detailed explanation)
- All parameters documented with types and examples
- All response codes with examples
- Error codes with remediation steps
- Code examples in at least 2 languages
- Authentication requirements stated
Overall API
- Getting started guide
- Authentication guide with examples
- Rate limiting documentation
- Pagination patterns
- Error handling guide
- Changelog maintained
- Versioning strategy documented
- SDK/library links
Developer Experience
- Interactive "Try It" functionality
- Copy-paste ready examples
- Consistent terminology
- Search functionality
- Mobile-friendly rendering
Tools Integration
Generate from Code
# From Express/Node.js routes npx swagger-jsdoc -d swaggerDef.js -o openapi.yaml # From TypeScript types npx openapi-typescript-codegen --input openapi.yaml --output ./sdk
Validate OpenAPI
# Validate spec npx @redocly/cli lint openapi.yaml # Preview documentation npx @redocly/cli preview-docs openapi.yaml
When to Use This Skill
Invoke this skill when:
- Creating new API documentation from scratch
- Adding documentation for new endpoints
- Writing OpenAPI/Swagger specifications
- Creating code examples for multiple languages
- Documenting authentication flows
- Building developer portals
- Improving existing API documentation
- Setting up interactive documentation (Swagger UI, Redoc)