api-documentation-writer

API Documentation Writer Skill

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 "api-documentation-writer" with this command: npx skills add eddiebe147/claude-settings/eddiebe147-claude-settings-api-documentation-writer

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:

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

FieldTypeRequiredDescription
emailstringYesUser's email address (must be unique)
namestringNoDisplay name (max 100 characters)
metadataobjectNoCustom key-value pairs

Example Request

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
VALIDATION_ERROR

Invalid email format or missing required field

401
UNAUTHORIZED

Invalid or missing authentication

409
USER_EXISTS

User with this email already exists

429
RATE_LIMITED

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

UNAUTHORIZED

401
Missing or invalid token
Include a valid Authorization
 header

TOKEN_EXPIRED

401
Token has expired
Obtain a new token via /auth/token

INVALID_API_KEY

401
API key not recognized
Check your API key in the dashboard

FORBIDDEN

403
Insufficient permissions
Request appropriate scopes for your token

Validation Errors

Code
HTTP Status
Description
Resolution

VALIDATION_ERROR

400
Request body validation failed
Check the details
 array for specific fields

MISSING_FIELD

400
Required field not provided
Include all required fields

INVALID_FORMAT

400
Field format is incorrect
Match the expected format (see schema)

Resource Errors

Code
HTTP Status
Description
Resolution

NOT_FOUND

404
Resource doesn't exist
Verify the resource ID is correct

ALREADY_EXISTS

409
Resource already exists
Use a different identifier or update existing

CONFLICT

409
State conflict
Refresh and retry the operation

Rate Limiting

Code
HTTP Status
Description
Resolution

RATE_LIMITED

429
Too many requests
Wait and retry (see Retry-After
 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)

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.

General

supabase-expert

No summary provided by upstream source.

Repository SourceNeeds Review
General

landing-page-designer

No summary provided by upstream source.

Repository SourceNeeds Review
General

appstore-readiness

No summary provided by upstream source.

Repository SourceNeeds Review