api-best-practices
REST API design patterns, OpenAPI specifications, versioning strategies, authentication, error handling, and security best practices. Use when designing APIs, creating endpoints, documenting APIs, or implementing backend services that expose HTTP APIs.
What this skill does
# API Best Practices
This skill provides comprehensive guidance for designing, implementing, and documenting RESTful APIs following industry best practices.
## RESTful Design Principles
### Resource-Oriented Design
APIs should be designed around resources (nouns), not actions (verbs):
**Good**:
```http
GET /api/v1/users
POST /api/v1/users
GET /api/v1/users/{id}
PUT /api/v1/users/{id}
DELETE /api/v1/users/{id}
```
**Bad**:
```http
GET /api/v1/getUsers
POST /api/v1/createUser
POST /api/v1/updateUser
POST /api/v1/deleteUser
```
### HTTP Methods and Their Meanings
- **GET**: Retrieve a resource (safe, idempotent, cacheable)
- **POST**: Create a new resource (not idempotent)
- **PUT**: Replace entire resource (idempotent)
- **PATCH**: Partial update (not necessarily idempotent)
- **DELETE**: Remove a resource (idempotent)
### HTTP Status Codes
**Success (2xx)**:
- `200 OK`: Successful GET, PUT, PATCH, DELETE
- `201 Created`: Successful POST with resource creation
- `202 Accepted`: Request accepted for async processing
- `204 No Content`: Successful DELETE or update with no response body
**Client Errors (4xx)**:
- `400 Bad Request`: Malformed request, validation error
- `401 Unauthorized`: Authentication required
- `403 Forbidden`: Authenticated but not authorized
- `404 Not Found`: Resource doesn't exist
- `409 Conflict`: Resource conflict (duplicate, version mismatch)
- `422 Unprocessable Entity`: Valid syntax but semantic errors
- `429 Too Many Requests`: Rate limit exceeded
**Server Errors (5xx)**:
- `500 Internal Server Error`: Unexpected server error
- `502 Bad Gateway`: Upstream service failure
- `503 Service Unavailable`: Temporary overload or maintenance
- `504 Gateway Timeout`: Upstream timeout
## API Versioning
### URL Versioning (Recommended)
```http
GET /api/v1/users
GET /api/v2/users
```
**Pros**: Clear, easy to route, visible in logs
**Cons**: Duplicate code across versions
### Header Versioning
```http
GET /api/users
Accept: application/vnd.myapi.v1+json
```
**Pros**: Clean URLs
**Cons**: Harder to test, less visible
### Version Management Rules
1. Never break backwards compatibility in same version
2. Deprecate old versions with advance notice (6-12 months)
3. Document migration guides between versions
4. Support at least 2 major versions simultaneously
## Request/Response Patterns
### Standard Request Format
**JSON Request Body**:
```json
{
"email": "[email protected]",
"name": "John Doe",
"preferences": {
"newsletter": true,
"notifications": false
}
}
```
**Query Parameters** (for filtering, pagination, sorting):
```http
GET /api/v1/users?role=admin&status=active&page=2&limit=20&sort=-created_at
```
### Standard Response Format
**Success Response**:
```json
{
"data": {
"id": "user_123",
"email": "[email protected]",
"name": "John Doe",
"createdAt": "2025-10-16T10:30:00Z"
}
}
```
**Error Response**:
```json
{
"error": {
"code": "INVALID_EMAIL",
"message": "Email address is invalid",
"field": "email",
"details": "Email must contain @ symbol"
}
}
```
**Collection Response with Pagination**:
```json
{
"data": [
{ "id": 1, "name": "User 1" },
{ "id": 2, "name": "User 2" }
],
"pagination": {
"page": 2,
"limit": 20,
"total": 156,
"totalPages": 8,
"hasNext": true,
"hasPrev": true
},
"links": {
"self": "/api/v1/users?page=2",
"next": "/api/v1/users?page=3",
"prev": "/api/v1/users?page=1",
"first": "/api/v1/users?page=1",
"last": "/api/v1/users?page=8"
}
}
```
## Authentication Patterns
### JWT (JSON Web Tokens)
**Login Flow**:
```http
POST /api/v1/auth/login
{
"email": "[email protected]",
"password": "SecurePassword123"
}
Response (200):
{
"accessToken": "eyJhbGc...",
"refreshToken": "eyJhbGc...",
"expiresIn": 900
}
```
**Using Access Token**:
```http
GET /api/v1/users/me
Authorization: Bearer eyJhbGc...
```
**Token Refresh**:
```http
POST /api/v1/auth/refresh
{
"refreshToken": "eyJhbGc..."
}
Response (200):
{
"accessToken": "eyJhbGc...",
"expiresIn": 900
}
```
### API Keys
**Header-based** (recommended):
```http
GET /api/v1/data
X-API-Key: sk_live_abc123xyz
```
**Query parameter** (less secure, use only for public data):
```http
GET /api/v1/public-data?api_key=sk_live_abc123xyz
```
### OAuth 2.0 Flows
**Authorization Code Flow** (for web apps):
1. Redirect to `/oauth/authorize`
2. User grants permission
3. Receive authorization code
4. Exchange code for access token at `/oauth/token`
5. Use access token for API requests
**Client Credentials Flow** (for server-to-server):
```http
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=abc&client_secret=xyz
```
## Error Handling
### Validation Errors
```json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"errors": [
{
"field": "email",
"message": "Email is required"
},
{
"field": "age",
"message": "Age must be at least 18"
}
]
}
}
```
### Business Logic Errors
```json
{
"error": {
"code": "INSUFFICIENT_FUNDS",
"message": "Account balance too low for this transaction",
"details": {
"balance": 50.00,
"required": 100.00,
"currency": "USD"
}
}
}
```
### Rate Limiting Errors
```http
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1634400000
Retry-After: 3600
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "API rate limit exceeded",
"retryAfter": 3600
}
}
```
## Pagination Strategies
### Offset Pagination (Simple)
```http
GET /api/v1/users?offset=40&limit=20
```
**Pros**: Simple, allows jumping to any page
**Cons**: Performance degrades with large offsets, inconsistent if data changes
### Cursor Pagination (Recommended for large datasets)
```http
GET /api/v1/users?cursor=eyJpZCI6MTIzfQ&limit=20
Response:
{
"data": [...],
"pagination": {
"nextCursor": "eyJpZCI6MTQzfQ",
"hasMore": true
}
}
```
**Pros**: Consistent results, performant at any scale
**Cons**: Can't jump to specific page
### Page-Number Pagination (User-friendly)
```http
GET /api/v1/users?page=3&limit=20
```
**Pros**: User-friendly, easy to understand
**Cons**: Same issues as offset pagination
## Rate Limiting
### Implementation Pattern
**Headers to include**:
```http
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1634400000
```
**Tiered Limits**:
- Anonymous: 100 requests/hour
- Basic tier: 1,000 requests/hour
- Pro tier: 10,000 requests/hour
- Enterprise: Custom limits
### Rate Limiting Algorithms
**Token Bucket** (recommended):
- Allows bursts
- Smooth long-term rate
- Most flexible
**Fixed Window**:
- Simple to implement
- Can allow double limit at window boundaries
- Less flexible
**Sliding Window**:
- More accurate than fixed window
- More complex to implement
- Better user experience
## API Security Best Practices
### 1. Always Use HTTPS
Never send sensitive data over HTTP. Enforce HTTPS at the load balancer level.
### 2. Validate All Inputs
```python
from pydantic import BaseModel, EmailStr, constr
class UserCreate(BaseModel):
email: EmailStr
password: constr(min_length=8, max_length=100)
name: constr(min_length=1, max_length=100)
```
### 3. Sanitize Outputs
Prevent injection attacks by escaping output:
```python
import html
safe_output = html.escape(user_input)
```
### 4. Use Parameterized Queries
```python
# ✅ SAFE - Parameterized
cursor.execute("SELECT * FROM users WHERE email = ?", (email,))
# ❌ UNSAFE - String concatenation
cursor.execute(f"SELECT * FROM users WHERE email = '{email}'")
```
### 5. Implement CORS Properly
```python
# Be specific with origins
CORS(app, origins=["https://myapp.com", "https://app.myapp.com"])
# ❌ NEVER use wildcard in production
# CORS(app, origins=["*"]) # DARelated in Design
contribute
IncludedLocal-only OSS contribution command center. Auto-refreshes the user's in-flight PR and issue state on invoke so conversations start with full context — no need to brief Claude on what's in flight. Helps the user find issues to contribute to on GitHub, builds per-repo dossiers of what each upstream expects (CLA, DCO, branch convention, AI policy, draft-first, review bots, issue templates), runs deterministic gates before any external action so AI-assisted contributions don't reach maintainers as slop. State is markdown-only: candidate files at ~/.contribute-system/candidates/, repo dossiers at ~/.contribute-system/research/, append-only event log at ~/.contribute-system/log.jsonl. No database, no cloud calls. Use when the user asks about their PRs / issues / contributions, wants to find new work to take on, claim an issue, build/refresh a repo's dossier, or draft a Design Issue or PR. Trigger with "/contribute", "what's my PR status", "find a contribution", "claim issue X", "draft a Design Issue for Y", "refresh dossier for Z".
architectural-analysis
IncludedUser-triggered deep architectural analysis of a codebase or scoped subtree across eight modes — information architecture, data flow, integration points, UI surfaces, interaction patterns, data model, control flow, and failure modes. This skill should be used when the user asks to "diagram this codebase," "map the architecture," "show the data flow," "give me an ERD," "trace control flow," "find the integration points," "verify the layout pattern," "audit the UX architecture," or any similar request whose primary deliverable is mermaid diagrams plus cited reports under docs/architecture/. Dispatches haiku/sonnet sub-agents in parallel for per-mode exploration, then verifies every citation mechanically before any node lands in a diagram. Not for one-off prose explanations of code (use code-explanation) or for high-level system design from scratch (use system-design).
mcp
IncludedModel Context Protocol (MCP) server development and tool management. Languages: Python, TypeScript. Capabilities: build MCP servers, integrate external APIs, discover/execute MCP tools, manage multi-server configs, design agent-centric tools. Actions: create, build, integrate, discover, execute, configure MCP servers/tools. Keywords: MCP, Model Context Protocol, MCP server, MCP tool, stdio transport, SSE transport, tool discovery, resource provider, prompt template, external API integration, Gemini CLI MCP, Claude MCP, agent tools, tool execution, server config. Use when: building MCP servers, integrating external APIs as MCP tools, discovering available MCP tools, executing MCP capabilities, configuring multi-server setups, designing tools for AI agents.
react-native-skia
IncludedDesign, build, debug, and optimise high-polish animated graphics in React Native or Expo using @shopify/react-native-skia, Reanimated, and Gesture Handler. Use when the user wants canvas-driven UI, shaders, paths, rich text, image filters, sprite fields, Skottie, video frames, snapshots, web CanvasKit setup, or performance tuning for custom motion-heavy elements such as loaders, hero art, cards, charts, progress indicators, particle systems, or gesture-driven surfaces. Also use when the user asks for fluid, glow, glass, blob, parallax, 60fps/120fps, or GPU-friendly animated effects in React Native, even if they do not explicitly say "Skia". Do not use for ordinary form/layout work with standard views.
plaid
IncludedProduct Led AI Development — guides founders from idea to launched product. Six capabilities: Idea (discover a product idea), Validate (pressure-test the idea against fatal flaws, problem reality, competition, and 2-week MVP feasibility), Plan (vision intake + document generation), Design (translate image references into a design.md spec), Launch (go-to-market strategy), and Build (roadmap execution). Use when someone says "PLAID", "plaid idea", "help me find an idea", "product idea", "idea from my business", "idea from my expertise", "plaid validate", "validate my idea", "pressure-test", "is this idea good", "find fatal flaws", "validate the problem", "plan a product", "define my vision", "generate a PRD", "product strategy", "plaid design", "design from image", "translate image to design", "create design.md", "extract design tokens", "plaid launch", "go-to-market", "launch plan", "GTM strategy", "launch playbook", "plaid build", "build the app", "start building", or "execute the roadmap".
nextjs-framer-motion-animations
IncludedAdds production-safe Motion for React or Framer Motion animations to Next.js apps, including reveal, hover and tap micro-interactions, whileInView, stagger, AnimatePresence, layout and layoutId transitions, reorder, scroll-linked UI, and lightweight route-content transitions. Use when the user asks to add, refactor, or debug Motion or Framer Motion in App Router or Pages Router codebases, especially around server/client boundaries, reduced motion, LazyMotion, bundle size, hydration, or route transitions. Avoid for GSAP-style timelines, WebGL or 3D scenes, heavy scroll storytelling, or CSS-only effects unless Motion is explicitly requested.