Patterns and structure for writing API reference documentation including endpoint descriptions, request/response schemas, and error documentation.
Scanned 5/27/2026
Install via CLI
openskills install LerianStudio/ring---
name: ring:write-api
description: |
Patterns and structure for writing API reference documentation including
endpoint descriptions, request/response schemas, and error documentation.
---
# Writing API Reference Documentation
## When to use
- Documenting REST API endpoints
- Writing request/response examples
- Documenting error codes
- Creating API field descriptions
## Skip when
- Writing conceptual guides → use write-guide
- Reviewing documentation → use review-docs
- Writing code → use dev-team agents
## Sequence
**Runs before:** ring:review-docs
## Related
**Similar:** ring:write-guide
**Complementary:** ring:documentation-structure
API reference documents what each endpoint does, its parameters, request/response formats, and error conditions. Focus on the "what" not the "why."
## API Reference Principles
- **RESTful and Predictable:** Standard HTTP methods, consistent URL patterns, idempotency documented
- **Consistent Formats:** JSON requests/responses, clear typing, standard error format
- **Explicit Versioning:** Version in URL path, backward compatibility notes, deprecated fields marked
## Endpoint Documentation Structure
| Section | Content |
|---------|---------|
| **Title** | Endpoint name |
| **Description** | What the endpoint does |
| **HTTP Method + Path** | `POST /v1/organizations/{orgId}/ledgers/{ledgerId}/accounts` |
| **Path Parameters** | Table: Parameter, Type, Required, Description |
| **Query Parameters** | Table: Parameter, Type, Default, Description |
| **Request Body** | JSON example + fields table |
| **Success Response** | Status code + JSON example + fields table |
| **Errors** | Table: Status Code, Error Code, Description |
## Field Descriptions
Every field needs: purpose, type, required (request only), constraints, example.
| Type | Pattern | Example |
|------|---------|---------|
| UUID | "The unique identifier of the [Entity]" | `id: uuid — The unique identifier of the Account` |
| String | "[Purpose] (constraints)" | `code: string — Asset code (max 10 chars, uppercase, e.g., "BRL")` |
| Enum | "[Purpose]: `val1`, `val2`, `val3`" | `type: enum — Asset type: \`currency\`, \`crypto\`, \`commodity\`` |
| Boolean | "If `true`, [what happens]. Default: `[value]`" | `allowSending: boolean — If \`true\`, sending permitted. Default: \`true\`` |
| Integer | "[Purpose] (range)" | `scale: integer — Decimal places (0-18)` |
| Timestamp | "Timestamp of [event] (UTC)" | `createdAt: timestamptz — Timestamp of creation (UTC)` |
| Array | "List of [what it contains]" | `operations: array — List of operations in the transaction` |
## Request/Response Table Format
```markdown
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| id | uuid | — | The unique identifier of the Account |
| name | string | Yes | The display name of the Account (max 255 chars) |
| status | enum | — | Account status: `ACTIVE`, `INACTIVE`, `BLOCKED` |
```
Use `—` for response-only fields. Mark deprecated fields: `**[Deprecated]** Use \`route\` instead`
## Data Types Reference
| Type | Description | Example |
|------|-------------|---------|
| `uuid` | UUID v4 identifier | `3172933b-50d2-4b17-96aa-9b378d6a6eac` |
| `string` | Text value | `"Customer Account"` |
| `integer` | Whole number | `42` |
| `boolean` | True/false | `true` |
| `timestamptz` | ISO 8601 (UTC) | `2024-01-15T10:30:00Z` |
| `jsonb` | JSON object | `{"key": "value"}` |
| `array` | List of values | `["item1", "item2"]` |
| `enum` | Predefined values | `currency`, `crypto` |
## Errors
Standard format:
```json
{
"code": "ACCOUNT_NOT_FOUND",
"message": "The specified account does not exist",
"details": { "accountId": "invalid-uuid" }
}
```
Error table:
| Status | Code | Description | Resolution |
|--------|------|-------------|------------|
| 400 | INVALID_REQUEST | Validation failed | Check request format |
| 401 | UNAUTHORIZED | Missing/invalid auth | Provide valid API key |
| 403 | FORBIDDEN | Insufficient permissions | Contact admin |
| 404 | NOT_FOUND | Resource doesn't exist | Verify resource ID |
| 409 | CONFLICT | Resource already exists | Use different identifier |
| 422 | UNPROCESSABLE_ENTITY | Business rule violation | Check constraints |
| 500 | INTERNAL_ERROR | Server error | Retry or contact support |
## HTTP Status Codes
**Success:** 200 (GET/PUT/PATCH), 201 (POST creates), 204 (DELETE)
**Client errors:** 400 (malformed), 401 (no auth), 403 (no permission), 404 (not found), 409 (conflict), 422 (invalid semantics)
**Server errors:** 500 (internal)
## Example Endpoint Documentation
```markdown
## Create Account
Create a new Account in a Ledger.
**POST** `/v1/organizations/{orgId}/ledgers/{ledgerId}/accounts`
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| orgId | uuid | Yes | Organization ID |
| ledgerId | uuid | Yes | Ledger ID |
### Request Body
```json
{
"name": "My Bank Account",
"code": "ACC001",
"status": "ACTIVE"
}
```
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| name | string | Yes | Display name (max 255 chars) |
| code | string | Yes | Account code (max 50 chars, uppercase) |
| status | enum | No | `ACTIVE`, `INACTIVE`. Default: `ACTIVE` |
### Success Response
**200 OK**
```json
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "My Bank Account",
"code": "ACC001",
"status": "ACTIVE",
"createdAt": "2024-01-15T10:30:00Z"
}
```
| Field | Type | Description |
|-------|------|-------------|
| id | uuid | The unique identifier of the Account |
| name | string | The display name of the Account |
| code | string | The account code |
| status | enum | Account status: `ACTIVE`, `INACTIVE`, `BLOCKED` |
| createdAt | timestamptz | Timestamp of creation (UTC) |
### Errors
| Status | Code | Description |
|--------|------|-------------|
| 400 | INVALID_REQUEST | Validation failed (e.g., missing name) |
| 401 | UNAUTHORIZED | Missing or invalid API key |
| 409 | CONFLICT | Account code already exists in this Ledger |
| 500 | INTERNAL_ERROR | Server error |
```
## Pagination
For paginated endpoints, document:
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| limit | integer | 10 | Results per page (max 100) |
| page | integer | 1 | Page number |
Response: `items`, `page`, `limit`, `totalItems`, `totalPages`
## Quality Checklist
- [ ] HTTP method and path correct
- [ ] All path parameters documented
- [ ] All query parameters documented
- [ ] All request body fields documented with types
- [ ] All response fields documented with types
- [ ] Required vs optional clear
- [ ] Realistic request/response examples included
- [ ] All error codes documented
- [ ] Deprecated fields marked
- [ ] Links to related endpoints included
No comments yet. Be the first to comment!