API Design Review
Evaluate API design for correctness, consistency, usability, and security.
Cross-reference: api/knowledge-rest-principles for REST constraints and resource modeling.
When to Use
- Before merging new or modified API endpoints
- When reviewing OpenAPI/Swagger specs or GraphQL schemas
- When evaluating API backward compatibility
- During API design reviews before implementation
Severity Levels
| Level |
Meaning |
| CRITICAL |
Breaking change, security hole, or correctness issue — fix before merge |
| WARNING |
Inconsistency or poor usability that will cause client developer friction — fix soon |
| SUGGESTION |
Polish that improves developer experience — consider for next iteration |
Review Checklist
1. Resource Design
| Check |
Severity if violated |
Resources are nouns, not verbs (/users, not /getUsers) |
WARNING |
Consistent pluralization (/users, /orders) |
WARNING |
Nested resources reflect real ownership (/users/{id}/orders) |
WARNING |
Nesting doesn't exceed 2 levels (/a/{id}/b max, not /a/{id}/b/{id}/c/{id}/d) |
WARNING |
| No resource naming collisions or ambiguity |
WARNING |
| Collection and item endpoints are distinct |
WARNING |
2. HTTP Semantics
| Check |
Severity if violated |
| GET is safe and idempotent (no side effects) |
CRITICAL |
| POST used for creation, returns 201 with Location header |
WARNING |
| PUT replaces entire resource, PATCH for partial update |
WARNING |
| DELETE is idempotent (second call returns 204 or 404, no error) |
WARNING |
| No state mutation via GET or query parameters |
CRITICAL |
| Correct status codes: 200/201/204 for success, 4xx for client error, 5xx for server error |
WARNING |
Status code quick reference:
| Code |
When to use |
| 200 |
Successful GET, PUT, PATCH |
| 201 |
Successful POST (resource created) |
| 204 |
Successful DELETE or action with no body |
| 400 |
Malformed request / validation failure |
| 401 |
Not authenticated |
| 403 |
Authenticated but not authorized |
| 404 |
Resource doesn't exist |
| 409 |
Conflict (duplicate, state violation) |
| 422 |
Semantically invalid (valid syntax, bad data) |
| 429 |
Rate limited |
| 500 |
Unexpected server error |
3. Error Handling
| Check |
Severity if violated |
| Errors use a consistent envelope format |
WARNING |
| Error response includes: code, message, and optionally field-level details |
WARNING |
| Error messages are actionable (not just "Bad Request") |
WARNING |
| No stack traces or internal details leaked in production errors |
CRITICAL |
| Validation errors return all failures, not just the first |
SUGGESTION |
Standard error format:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{ "field": "email", "message": "Must be a valid email address" }
]
}
}
4. Pagination, Filtering, and Sorting
| Check |
Severity if violated |
| Collection endpoints are paginated (no unbounded lists) |
CRITICAL |
| Pagination style is consistent (cursor-based preferred for large/real-time data) |
WARNING |
| Page metadata included (total count or has_next indicator) |
WARNING |
Filtering uses query parameters (?status=active) |
WARNING |
Sorting is explicit (?sort=created_at&order=desc) |
SUGGESTION |
| Default page size is reasonable and documented |
SUGGESTION |
5. Versioning
| Check |
Severity if violated |
| Versioning strategy exists (URL prefix, header, or content negotiation) |
WARNING |
| Breaking changes increment the version |
CRITICAL |
| Deprecated endpoints have sunset dates communicated |
WARNING |
| Multiple versions can coexist during migration |
SUGGESTION |
6. Security
| Check |
Severity if violated |
| Authentication required on all non-public endpoints |
CRITICAL |
| Authorization checked at resource level, not just endpoint |
CRITICAL |
| Rate limiting configured |
WARNING |
| Input validated and sanitized |
CRITICAL |
| CORS configured restrictively |
WARNING |
| No sensitive data in URLs (tokens, passwords in query strings) |
CRITICAL |
7. Backward Compatibility
| Check |
Severity if violated |
| New fields are optional (existing clients don't break) |
CRITICAL |
| Removed fields go through deprecation cycle |
CRITICAL |
| Enum values are only added, not removed or renamed |
CRITICAL |
| Response shape changes are additive only |
CRITICAL |
| URL/path changes maintain old routes as redirects or aliases |
WARNING |
8. Documentation
| Check |
Severity if violated |
| All endpoints documented with request/response examples |
WARNING |
| Auth requirements documented per endpoint |
WARNING |
| Error codes and their meaning documented |
WARNING |
| Rate limits documented |
SUGGESTION |
| OpenAPI/Swagger spec is up to date with implementation |
WARNING |
| Changelog maintained for API changes |
SUGGESTION |
Output Format
## API Review: [API/Endpoint Name]
**Scope**: [Endpoints reviewed]
**Overall**: [PASS | PASS WITH WARNINGS | FAIL]
### Findings
#### Design
##### [WARNING] Verb in resource name
**Location**: `POST /api/createUser`
**Issue**: Resource uses verb instead of noun
**Fix**: `POST /api/users` — the HTTP method implies creation
#### Security
##### [CRITICAL] Missing auth on admin endpoint
**Location**: `GET /api/admin/users`
**Issue**: No authentication middleware
**Fix**: Add auth middleware and admin role check
...
### Summary
| Category | Critical | Warning | Suggestion |
|----------|----------|---------|------------|
| Design | 0 | 2 | 1 |
| HTTP Semantics | 0 | 1 | 0 |
| Error Handling | 0 | 1 | 0 |
| Pagination | 1 | 0 | 1 |
| Security | 1 | 1 | 0 |
| Compatibility | 0 | 0 | 0 |
| Documentation | 0 | 2 | 0 |
| **Total** | **2** | **7** | **2** |
### Recommendations
1. <Prioritized by impact>
2. ...
1---2name: review-api3description: Evaluate API design for consistency, correct HTTP semantics, error handling, pagination, versioning, security, and documentation quality. Covers REST and GraphQL.4---56# API Design Review78Evaluate API design for correctness, consistency, usability, and security.910**Cross-reference**: `api/knowledge-rest-principles` for REST constraints and resource modeling.1112## When to Use1314- Before merging new or modified API endpoints15- When reviewing OpenAPI/Swagger specs or GraphQL schemas16- When evaluating API backward compatibility17- During API design reviews before implementation1819## Severity Levels2021| Level | Meaning |22|-------|---------|23| **CRITICAL** | Breaking change, security hole, or correctness issue — fix before merge |24| **WARNING** | Inconsistency or poor usability that will cause client developer friction — fix soon |25| **SUGGESTION** | Polish that improves developer experience — consider for next iteration |2627## Review Checklist2829### 1. Resource Design3031| Check | Severity if violated |32|-------|---------------------|33| Resources are nouns, not verbs (`/users`, not `/getUsers`) | WARNING |34| Consistent pluralization (`/users`, `/orders`) | WARNING |35| Nested resources reflect real ownership (`/users/{id}/orders`) | WARNING |36| Nesting doesn't exceed 2 levels (`/a/{id}/b` max, not `/a/{id}/b/{id}/c/{id}/d`) | WARNING |37| No resource naming collisions or ambiguity | WARNING |38| Collection and item endpoints are distinct | WARNING |3940### 2. HTTP Semantics4142| Check | Severity if violated |43|-------|---------------------|44| GET is safe and idempotent (no side effects) | CRITICAL |45| POST used for creation, returns 201 with Location header | WARNING |46| PUT replaces entire resource, PATCH for partial update | WARNING |47| DELETE is idempotent (second call returns 204 or 404, no error) | WARNING |48| No state mutation via GET or query parameters | CRITICAL |49| Correct status codes: 200/201/204 for success, 4xx for client error, 5xx for server error | WARNING |5051**Status code quick reference**:5253| Code | When to use |54|------|------------|55| 200 | Successful GET, PUT, PATCH |56| 201 | Successful POST (resource created) |57| 204 | Successful DELETE or action with no body |58| 400 | Malformed request / validation failure |59| 401 | Not authenticated |60| 403 | Authenticated but not authorized |61| 404 | Resource doesn't exist |62| 409 | Conflict (duplicate, state violation) |63| 422 | Semantically invalid (valid syntax, bad data) |64| 429 | Rate limited |65| 500 | Unexpected server error |6667### 3. Error Handling6869| Check | Severity if violated |70|-------|---------------------|71| Errors use a consistent envelope format | WARNING |72| Error response includes: code, message, and optionally field-level details | WARNING |73| Error messages are actionable (not just "Bad Request") | WARNING |74| No stack traces or internal details leaked in production errors | CRITICAL |75| Validation errors return all failures, not just the first | SUGGESTION |7677**Standard error format**:78```json79{80 "error": {81 "code": "VALIDATION_ERROR",82 "message": "Request validation failed",83 "details": [84 { "field": "email", "message": "Must be a valid email address" }85 ]86 }87}88```8990### 4. Pagination, Filtering, and Sorting9192| Check | Severity if violated |93|-------|---------------------|94| Collection endpoints are paginated (no unbounded lists) | CRITICAL |95| Pagination style is consistent (cursor-based preferred for large/real-time data) | WARNING |96| Page metadata included (total count or has_next indicator) | WARNING |97| Filtering uses query parameters (`?status=active`) | WARNING |98| Sorting is explicit (`?sort=created_at&order=desc`) | SUGGESTION |99| Default page size is reasonable and documented | SUGGESTION |100101### 5. Versioning102103| Check | Severity if violated |104|-------|---------------------|105| Versioning strategy exists (URL prefix, header, or content negotiation) | WARNING |106| Breaking changes increment the version | CRITICAL |107| Deprecated endpoints have sunset dates communicated | WARNING |108| Multiple versions can coexist during migration | SUGGESTION |109110### 6. Security111112| Check | Severity if violated |113|-------|---------------------|114| Authentication required on all non-public endpoints | CRITICAL |115| Authorization checked at resource level, not just endpoint | CRITICAL |116| Rate limiting configured | WARNING |117| Input validated and sanitized | CRITICAL |118| CORS configured restrictively | WARNING |119| No sensitive data in URLs (tokens, passwords in query strings) | CRITICAL |120121### 7. Backward Compatibility122123| Check | Severity if violated |124|-------|---------------------|125| New fields are optional (existing clients don't break) | CRITICAL |126| Removed fields go through deprecation cycle | CRITICAL |127| Enum values are only added, not removed or renamed | CRITICAL |128| Response shape changes are additive only | CRITICAL |129| URL/path changes maintain old routes as redirects or aliases | WARNING |130131### 8. Documentation132133| Check | Severity if violated |134|-------|---------------------|135| All endpoints documented with request/response examples | WARNING |136| Auth requirements documented per endpoint | WARNING |137| Error codes and their meaning documented | WARNING |138| Rate limits documented | SUGGESTION |139| OpenAPI/Swagger spec is up to date with implementation | WARNING |140| Changelog maintained for API changes | SUGGESTION |141142## Output Format143144```markdown145## API Review: [API/Endpoint Name]146147**Scope**: [Endpoints reviewed]148**Overall**: [PASS | PASS WITH WARNINGS | FAIL]149150### Findings151152#### Design153##### [WARNING] Verb in resource name154**Location**: `POST /api/createUser`155**Issue**: Resource uses verb instead of noun156**Fix**: `POST /api/users` — the HTTP method implies creation157158#### Security159##### [CRITICAL] Missing auth on admin endpoint160**Location**: `GET /api/admin/users`161**Issue**: No authentication middleware162**Fix**: Add auth middleware and admin role check163164...165166### Summary167| Category | Critical | Warning | Suggestion |168|----------|----------|---------|------------|169| Design | 0 | 2 | 1 |170| HTTP Semantics | 0 | 1 | 0 |171| Error Handling | 0 | 1 | 0 |172| Pagination | 1 | 0 | 1 |173| Security | 1 | 1 | 0 |174| Compatibility | 0 | 0 | 0 |175| Documentation | 0 | 2 | 0 |176| **Total** | **2** | **7** | **2** |177178### Recommendations1791. <Prioritized by impact>1802. ...181```