plugins/api-documentation/skills/api-doc-patterns/SKILL.md
# API Documentation Patterns ## Operation Documentation ### summary vs description `summary` is the one-line entry in navigation and index tables. `description` is the full explanation. Both matter. ```yaml # Bad: summary that restates the method and path summary: GET user by ID # Good: summary that describes intent summary: Retrieve a user # description adds what summary cannot: description: | Returns a single active user. Suspended users still return 200 with `status: suspended`. Dele
npx skillsauth add hermeticormus/librecopy-claude-code plugins/api-documentation/skills/api-doc-patternsInstall 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.
summary is the one-line entry in navigation and index tables. description is the full explanation. Both matter.
# Bad: summary that restates the method and path
summary: GET user by ID
# Good: summary that describes intent
summary: Retrieve a user
# description adds what summary cannot:
description: |
Returns a single active user. Suspended users still return 200 with
`status: suspended`. Deleted users return 404.
If the authenticated user does not have `read:users` scope, returns 403.
Every parameter needs description, example, and schema constraints.
parameters:
- name: user_id
in: path
required: true
description: Unique identifier of the user. Format is UUID v4.
schema:
type: string
format: uuid
example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
- name: include
in: query
description: |
Comma-separated list of related resources to embed in the response.
Supported values: `profile`, `settings`, `subscriptions`.
schema:
type: string
pattern: '^[a-z_]+(,[a-z_]+)*$'
example: "profile,settings"
- name: X-Idempotency-Key
in: header
description: |
Client-generated UUID to make the request idempotent. If a request
with this key was already processed, the original response is returned
without re-processing. Required for POST /payments.
schema:
type: string
format: uuid
required: false
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateOrderRequest'
examples:
digital_product:
summary: Order for a digital product
value:
items:
- product_id: "prod_abc123"
quantity: 1
payment_method_id: "pm_xyz789"
physical_with_shipping:
summary: Order requiring shipping address
value:
items:
- product_id: "prod_def456"
quantity: 2
shipping_address:
line1: "123 Main St"
city: "Austin"
state: "TX"
postal_code: "78701"
country: "US"
Every operation should document at minimum:
responses:
'201':
description: Order created successfully
headers:
Location:
description: URL of the created order resource
schema:
type: string
format: uri
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
'422':
description: Validation failed
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ValidationProblem'
example:
type: "https://api.acme.com/errors/validation-failed"
title: "Validation Failed"
status: 422
errors:
- field: "items[0].quantity"
code: "out_of_range"
message: "Quantity must be between 1 and 99"
'429':
description: Rate limit exceeded
headers:
Retry-After:
description: Seconds until the rate limit resets
schema:
type: integer
X-RateLimit-Remaining:
schema:
type: integer
Use standard formats for tooling support (validation, mock generation, SDK typing):
properties:
id:
type: string
format: uuid
created_at:
type: string
format: date-time # ISO 8601 with timezone
birth_date:
type: string
format: date # YYYY-MM-DD
webhook_url:
type: string
format: uri
email:
type: string
format: email
amount:
type: integer
description: Amount in cents (USD). $10.00 = 1000
currency:
type: string
pattern: '^[A-Z]{3}$'
description: ISO 4217 currency code
example: "USD"
/users/{user_id}:
get:
x-codeSamples:
- lang: Shell
label: curl
source: |
curl -X GET https://api.acme.com/v2/users/usr_abc123 \
-H "Authorization: Bearer $API_TOKEN"
- lang: JavaScript
label: Node.js
source: |
const response = await fetch('https://api.acme.com/v2/users/usr_abc123', {
headers: { 'Authorization': `Bearer ${process.env.API_TOKEN}` },
});
const user = await response.json();
- lang: Python
label: Python
source: |
import httpx
client = httpx.Client(headers={"Authorization": f"Bearer {api_token}"})
user = client.get("https://api.acme.com/v2/users/usr_abc123").json()
# Bad
description: The user object
# Good
description: |
Authenticated user making the request. Includes profile data but
excludes payment methods. Use GET /users/{id}/payments for payment access.
# Bad: oneOf without discriminator - clients cannot determine which schema applies
schema:
oneOf:
- $ref: '#/components/schemas/CreditCardPayment'
- $ref: '#/components/schemas/BankTransferPayment'
# Good
schema:
oneOf:
- $ref: '#/components/schemas/CreditCardPayment'
- $ref: '#/components/schemas/BankTransferPayment'
discriminator:
propertyName: method
mapping:
card: '#/components/schemas/CreditCardPayment'
bank_transfer: '#/components/schemas/BankTransferPayment'
# Bad
example:
id: "string"
email: "[email protected]"
created_at: "2024-01-01"
# Good: realistic example usable for testing
example:
id: "usr_01HX4K9Z2MVNPGR8TQ3W7Y5B6C"
email: "[email protected]"
created_at: "2024-03-15T14:32:07.891Z"
status: "active"
plan: "pro"
# Bad: inline - cannot be reused, hard to maintain
responses:
'200':
content:
application/json:
schema:
type: object
properties:
id:
type: string
# Good: named schema
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/User'
tools
# User Doc Patterns > Patterns for writing clear, accessible end-user documentation. ## Knowledge Base ### User Documentation vs Developer Documentation | User Docs | Developer Docs | |-----------|---------------| | Task-oriented ("How do I...") | Concept-oriented ("How does it work...") | | Plain language | Technical language | | Screenshots and visual aids | Code examples | | Step-by-step procedures | API references | | Feature names and UI labels | Function signatures and parameters | | A
tools
# Tutorial Structures > Pedagogical patterns and frameworks for creating effective technical tutorials. ## Knowledge Base ### The Tutorial Spectrum Tutorials exist on a spectrum between two extremes: | Recipe | Concept Guide | |--------|--------------| | "Do exactly this" | "Understand this idea" | | Step-by-step | Explanation-heavy | | Fast to complete | Deep understanding | | Low retention | High retention | The best tutorials blend both: steps for doing, explanations for understanding.
tools
# Tutorial Patterns ## Tutorial vs. How-to Guide: The Critical Distinction Before writing, identify which document is actually needed: | Tutorial | How-to Guide | |----------|-------------| | "Build a REST API in Node.js" | "Add JWT authentication to your Express API" | | For someone new to this | For someone who knows the domain | | Explains why each step is done | Steps are efficient, minimal explanation | | Has checkpoints, explores | Numbered steps, no detours | | Learner reaches a comple
tools
# Tech Blogging Patterns ## The Developer Reading Pattern Developers do not read technical posts linearly. They scan in this order: 1. Headline (is this relevant to me?) 2. Code blocks (is this real code I can use?) 3. Headers (what does this cover?) 4. First paragraph (what's the point?) 5. Key takeaways / conclusion (is it worth reading fully?) Design for scanning first, reading second. Put real code within the first 25% of the post. ## The Before/After Pattern The contrast between a pain