API Designer
Protocols
!
cat skills/_shared/protocols/ux-protocol.md 2>/dev/null || true
!
cat skills/_shared/protocols/input-validation.md 2>/dev/null || true
!
cat skills/_shared/protocols/tool-efficiency.md 2>/dev/null || true
!
cat .production-grade.yaml 2>/dev/null || echo "No config — using defaults"
!
cat .forgewright/codebase-context.md 2>/dev/null || true
Fallback (if protocols not loaded): Use notify_user with options (never open-ended), "Chat about this" last, recommended first. Work continuously. Print progress constantly. Validate inputs before starting — classify missing as Critical (stop), Degraded (warn, continue partial), or Optional (skip silently). Use parallel tool calls for independent reads. Use view_file_outline before full Read.
Engagement Mode
!
cat .forgewright/settings.md 2>/dev/null || echo "No settings — using Standard"
| Mode | Behavior |
|---|
| Express | Fully autonomous. Design APIs using best practices. Report decisions in output. |
| Standard | Surface API style choice (REST vs GraphQL vs gRPC), pagination strategy, and versioning approach. Auto-resolve everything else. |
| Thorough | Present full API design document before implementation. Walk through resource modeling and endpoint design. Show error code taxonomy. Ask about consumer needs. |
| Meticulous | Walk through each resource individually. User reviews endpoint signatures, request/response schemas, and error responses. Show API mock for consumer validation. |
Brownfield Awareness
If
.forgewright/codebase-context.md
exists and mode is
:
- READ existing API patterns first — understand current URL structure, naming conventions, error format
- MATCH existing conventions — if they use camelCase, don't switch to snake_case
- BACKWARD COMPATIBLE — new endpoints only. Never break existing consumers
- Document existing patterns — capture conventions in the API style guide before extending
Overview
Dedicated API design pipeline: from domain modeling through resource design, endpoint specification, error taxonomy, and API documentation. Produces OpenAPI/AsyncAPI specs and API style guides. Works upstream of
Phase 4 for API-heavy projects, or standalone when designing individual APIs.
Input Classification
| Category | Inputs | Behavior if Missing |
|---|
| Critical | Domain entities, user stories, or feature requirements | STOP — cannot design API without knowing the domain |
| Degraded | Existing API patterns (brownfield), consumer requirements, scale expectations | WARN — will design using best practices as defaults |
| Optional | Authentication strategy (from ), rate limit requirements, compliance constraints | Continue — use sensible defaults |
Process Flow
dot
digraph api_designer {
rankdir=TB;
"API Request" [shape=doublecircle];
"Phase 1: Domain Modeling" [shape=box];
"Phase 2: Resource Design" [shape=box];
"Phase 3: Endpoint Specification" [shape=box];
"Phase 4: Error & Edge Cases" [shape=box];
"Phase 5: Documentation & Governance" [shape=box];
"Done" [shape=doublecircle];
"API Request" -> "Phase 1: Domain Modeling";
"Phase 1: Domain Modeling" -> "Phase 2: Resource Design";
"Phase 2: Resource Design" -> "Phase 3: Endpoint Specification";
"Phase 3: Endpoint Specification" -> "Phase 4: Error & Edge Cases";
"Phase 4: Error & Edge Cases" -> "Phase 5: Documentation & Governance";
"Phase 5: Documentation & Governance" -> "Done";
}
Parallel Execution
After Phase 2 (Resource Design), Phases 3-4 can run in parallel:
python
Execute sequentially: Design REST/GraphQL endpoint specifications following Phase 3. Write to api/openapi/.
Execute sequentially: Design error taxonomy and edge cases following Phase 4. Write to api/errors/.
Wait for both, then run Phase 5 (Documentation) sequentially.
Phase 1 — Domain Modeling
Goal: Identify API resources from domain entities and their relationships.
Actions:
-
Extract entities from BRD/domain (User, Order, Product, etc.)
-
Identify relationships: one-to-one, one-to-many, many-to-many
-
Classify entities:
- Primary resources — have their own endpoints (, )
- Sub-resources — nested under parent ()
- Lookup/reference — read-only, rarely change (, )
- Action resources — represent operations, not data ()
-
Map CRUD operations to HTTP methods (standard REST mapping, use
header for POST idempotency)
Output: Entity-relationship diagram, resource hierarchy.
Phase 2 — Resource Design
Goal: Design URL structure, naming conventions, and resource representation.
URL naming rules:
- Plural nouns for collections: , (not , )
- Kebab-case for multi-word: (not or )
- No verbs in URLs: is a POST action (not )
- Max 3 levels of nesting: ✓,
/users/{id}/orders/{oid}/items/{iid}/reviews
✗
- Use query params for filtering:
/orders?status=pending&sort=-created_at
Request/Response conventions:
- Request bodies: camelCase JSON (matches JavaScript convention)
- Response envelopes: consistent wrapper structure:
json
{
"data": { ... }, // Single resource or array
"meta": { // Pagination, totals
"total": 150,
"page": 1,
"perPage": 20
},
"links": { // HATEOAS navigation
"self": "/api/v1/orders?page=1",
"next": "/api/v1/orders?page=2"
}
}
Pagination strategies:
| Strategy | Pros | Cons | Use When |
|---|
| Cursor-based | Consistent with concurrent writes, efficient | Can't jump to page N | Default for production APIs. Most common pattern. |
| Offset/Limit | Simple, familiar, can jump to any page | Inconsistent with concurrent writes, slow at large offsets | Admin dashboards, internal tools |
| Keyset | Efficient for large datasets, consistent | Requires sortable unique column | Time-series data, logs |
Default: cursor-based pagination with
and
in response.
Gate: Validate resource inventory covers all domain entities before proceeding.
Output: URL inventory, request/response schemas.
Phase 3 — Endpoint Specification
Goal: Write complete endpoint specifications in OpenAPI 3.1 format.
Per-endpoint requirements:
- Summary — one-line description
- Description — detailed behavior, business rules, side effects
- Parameters — path, query, header params with types and validation
- Request body — JSON schema with required/optional fields, examples
- Responses — all status codes (200, 201, 400, 401, 403, 404, 409, 422, 500) with schemas
- Authentication — which auth method (Bearer token, API key, OAuth2 scope)
- Rate limiting — per-endpoint limits if different from default
- Idempotency — whether is supported/required
Standard headers:
| Header | Direction | Purpose |
|---|
| Request | Bearer token or API key |
| Request | Client-generated request tracking ID |
| Request | Prevent duplicate mutations |
| Both | |
| Response | Requests allowed per window |
| Response | Requests remaining in window |
| Response | Window reset time (Unix timestamp) |
| Response | Echo or server-generated trace ID |
Versioning strategy:
- URL path versioning (recommended): ,
- Version in URL is explicit, cacheable, and easy to route
- Support N-1 version minimum (current + previous)
- Deprecation: header + 6 months notice + migration guide
Gate: Run OpenAPI linter on generated spec before proceeding.
Output: OpenAPI 3.1 spec files in
.
Phase 4 — Error Design & Edge Cases
Goal: Design a comprehensive, consistent error handling system.
Standard error response:
json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "The request body contains invalid fields.",
"details": [
{
"field": "email",
"issue": "must be a valid email address",
"value": "not-an-email"
}
],
"requestId": "req_abc123",
"documentation": "https://docs.example.com/errors/VALIDATION_ERROR"
}
}
Error code taxonomy:
| HTTP Status | Error Code | When |
|---|
| 400 | | Malformed JSON, missing required params |
| 400 | | Field validation failures (with array) |
| 401 | | Missing or invalid auth token |
| 403 | | Valid auth but insufficient permissions |
| 404 | | Resource doesn't exist |
| 409 | | Duplicate creation, stale update (optimistic locking) |
| 422 | | Valid format but business rule violation |
| 429 | | Too many requests (include header) |
| 500 | | Unexpected server error (never expose stack traces) |
| 503 | | Temporary outage (include header) |
Edge cases to design for:
- Concurrent updates (optimistic locking with /)
- Partial failures in batch operations (return per-item results)
- Large payloads (413 with max size documentation)
- Slow responses (timeout handling, async operations with 202 + status endpoint)
- Deleted resources (410 Gone vs 404 Not Found)
Output: Error taxonomy document, error response schemas.
Phase 5 — Documentation & Governance
Goal: Generate API documentation and governance rules.
API style guide (write to
):
- Naming conventions (URL, fields, query params)
- Pagination standard
- Error format standard
- Authentication patterns
- Versioning policy
- Deprecation process
- Breaking vs non-breaking changes
Breaking change definition:
| Breaking ✗ | Non-Breaking ✓ |
|---|
| Removing a field from response | Adding a new optional field to response |
| Changing a field type | Adding a new endpoint |
| Removing an endpoint | Adding a new optional query parameter |
| Making an optional field required | Adding a new error code |
| Changing URL structure | Adding a new header |
API changelog (append to
):
- Every API change logged with version, date, breaking/non-breaking, and migration guide
Output: API style guide, governance rules, changelog entries.
Output Structure
Project Root
api/
├── openapi/
│ ├── openapi.yaml # Main OpenAPI 3.1 spec
│ └── components/
│ ├── schemas/ # Reusable JSON schemas
│ ├── responses/ # Standard error responses
│ └── parameters/ # Common query parameters
├── errors/
│ └── error-taxonomy.md # Error code reference
└── graphql/ # (if GraphQL chosen)
├── schema.graphql
└── resolvers.md
docs/api/
├── style-guide.md # API conventions and standards
├── versioning-policy.md # How versions are managed
└── migration-guides/ # Per-version migration docs
Workspace
.forgewright/api-designer/
├── domain-model.md # Entity relationship analysis
├── resource-inventory.md # URL inventory with methods
└── design-decisions.md # API design rationale
Common Mistakes
| Mistake | Fix |
|---|
| Verbs in URLs (, ) | Use nouns + HTTP methods: , |
| Inconsistent naming ( vs vs ) | Pick one convention (camelCase recommended) and enforce everywhere |
| No pagination on list endpoints | EVERY list endpoint must paginate. Default: cursor-based, 20 items. |
| Generic error messages ("Something went wrong") | Specific codes + details: with field-level issues |
| Exposing internal IDs (auto-increment) | Use UUIDs or opaque IDs. Auto-increment leaks data volume. |
| No versioning from the start | Add from day one. Retrofitting is painful. |
| Inconsistent response envelope | Same wrapper for all endpoints: |
| Missing idempotency for mutations | Support header for POST/PATCH endpoints |
| Deeply nested URLs (> 3 levels) | Flatten with query params: instead of |
| No rate limiting | Every API needs rate limits. Document them. Return with . |