api-design-reviewer/SKILL.md
REST API design review and best practices. Naming conventions, HTTP methods, pagination, error formats, versioning, breaking change detection, rate limiting, HATEOAS. Use when designing or reviewing APIs.
npx skillsauth add lidge-jun/cli-jaw-skills api-design-reviewerInstall 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.
Comprehensive API design analysis for REST conventions, consistency, and industry standards.
✅ Good: ❌ Bad:
/api/v1/users /api/v1/getUsers
/api/v1/user-profiles /api/v1/user_profiles
/api/v1/orders/123/line-items /api/v1/orders/123/lineItems
Rules: Plural nouns for collections. Kebab-case for multi-word resources. CamelCase for JSON fields. Use HTTP methods instead of verbs in URLs.
| Method | Purpose | Idempotent | Safe | |--------|---------|------------|------| | GET | Retrieve resources | Yes | Yes | | POST | Create new resources | No | No | | PUT | Replace entire resource | Yes | No | | PATCH | Partial update | No | No | | DELETE | Remove resource | Yes | No |
Collection: /api/v1/users
Individual: /api/v1/users/123
Nested: /api/v1/users/123/orders
Action: /api/v1/users/123/activate (POST)
Filtering: /api/v1/users?status=active&role=admin
{
"data": [...],
"pagination": {
"nextCursor": "eyJpZCI6MTIzfQ==",
"hasMore": true
}
}
Implementation tip: fetch LIMIT + 1 rows to determine hasMore without a separate count query.
{
"data": [...],
"pagination": { "offset": 20, "limit": 10, "total": 150, "hasMore": true }
}
| Use Case | Pagination Type | Why | |----------|----------------|-----| | Admin dashboards, small datasets (<10K) | Offset | Users expect page numbers | | Infinite scroll, feeds, large datasets | Cursor | Consistent performance at any depth | | Public APIs | Cursor (default), offset (optional) | Scalable by default | | Search results | Offset | Users expect "page N of M" |
{
"error": {
"code": "VALIDATION_ERROR",
"message": "The request contains invalid parameters",
"details": [
{ "field": "email", "code": "INVALID_FORMAT", "message": "Email address is not valid" }
],
"requestId": "req-123456",
"timestamp": "2024-02-16T13:00:00Z"
}
}
| Code | Meaning | |------|---------| | 200 | Success (GET, PUT, PATCH) | | 201 | Created (POST) | | 204 | No Content (DELETE) | | 400 | Validation error | | 401 | Authentication required | | 403 | Permission denied | | 404 | Resource not found | | 409 | Conflict (duplicate, version mismatch) | | 422 | Semantic errors (valid syntax, bad logic) | | 429 | Rate limit exceeded | | 500 | Internal server error |
| Strategy | Example | Pros | Cons |
|----------|---------|------|------|
| URL (recommended) | /api/v1/users | Clear, easy to route | URL proliferation |
| Header | Accept: application/vnd.api+json;version=1 | Clean URLs | Less visible |
| Query parameter | /api/users?version=1 | Simple | Not RESTful |
1. Start with /api/v1/ — version only when breaking changes arise
2. Maintain at most 2 active versions (current + previous)
3. Deprecation timeline (public APIs):
- Announce deprecation with 6 months notice
- Add Sunset header: Sunset: Sat, 01 Jan 2026 00:00:00 GMT
- Return 410 Gone after sunset date
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1640995200
{ "error": { "code": "RATE_LIMIT_EXCEEDED", "message": "Too many requests", "retryAfter": 3600 } }
| Tier | Limit | Window | Use Case | |------|-------|--------|----------| | Anonymous | 30/min | Per IP | Public endpoints | | Authenticated | 100/min | Per user | Standard API access | | Premium | 1000/min | Per API key | Paid API plans | | Internal | 10000/min | Per service | Service-to-service |
# Equality filters
GET /api/v1/orders?status=active&customer_id=abc-123
# Comparison operators (bracket notation)
GET /api/v1/products?price[gte]=10&price[lte]=100
# Multiple values (comma-separated)
GET /api/v1/products?category=electronics,clothing
# Sorting (prefix - for descending, comma for multi-field)
GET /api/v1/products?sort=-created_at,price
# Full-text search
GET /api/v1/products?q=wireless+headphones
# Sparse fieldsets (reduce payload)
GET /api/v1/users?fields=id,name,email
| Pattern | Header | Use Case |
|---------|--------|----------|
| Bearer Token | Authorization: Bearer <token> | JWT, OAuth 2.0 |
| API Key | X-API-Key: <key> | Service-to-service |
| Basic Auth | Authorization: Basic <base64> | Simple auth (with HTTPS) |
For non-idempotent operations (POST), use idempotency keys:
POST /api/v1/payments
Idempotency-Key: 123e4567-e89b-12d3-a456-426614174000
| Anti-Pattern | Fix |
|---|---|
| Verb-based URLs (/getUsers) | Use nouns + HTTP methods |
| Inconsistent response shapes | Standardize envelope format |
| Deep nesting (/a/1/b/2/c/3/d) | Limit to 2 levels; use query params |
| Ignoring status codes | Use specific codes per error type |
| Missing pagination | Always paginate lists |
| No versioning | Plan for API evolution from day one |
| Exposing internal structure | Design for external consumption |
tools
Use only on the Codex CLI for native image generation or image editing without an API key. Save final PNG files under ~/.cli-jaw/uploads, report web-ready absolute-path markdown, and send to Telegram or Discord only when explicitly requested.
tools
Ranked repository structure map via `cli-jaw map`. Use for codebase overview, structure map, symbol overview, unfamiliar codebase exploration, architecture orientation. Triggers: repo map, structure map, codebase overview, 와꾸, project structure, unfamiliar code.
tools
cli-jaw Design workspace: create, preview, run, and export design pages from the right sidebar. Covers panel UX, direct-write workflow, artifact lifecycle, wireframe generation, design system, and Open Design adapter.
development
MUST USE for infrastructure and delivery work — container builds, deploy pipelines, Kubernetes, Infrastructure as Code, SRE foundations, edge/serverless, ML infrastructure. Triggers: Dockerfile, K8s manifests, CI/CD pipeline, Terraform/IaC, release/deploy, devops/infra/deploy or release_cd task_tags.