# API Patterns

> REST API design patterns, authentication, and error handling for this SaaS application Use when this capability is needed.

- Skill: `tomevault-io/api-patterns-11` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/api-patterns-11`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/api-patterns-11/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/api-patterns-11

---


# API Patterns

## Authentication

### JWT Token Structure

```typescript
interface JWTPayload {
  sub: string;        // User ID
  email: string;
  role: 'user' | 'admin';
  iat: number;
  exp: number;
}
```

### Auth Middleware

```typescript
// Always use authMiddleware for protected routes
import { authMiddleware } from '@/middleware/auth';

router.get('/protected', authMiddleware, handler);
```

## Error Handling

### Standard Error Codes

| Code | HTTP Status | Description |
|------|-------------|-------------|
| AUTH_REQUIRED | 401 | Missing or invalid token |
| FORBIDDEN | 403 | Insufficient permissions |
| NOT_FOUND | 404 | Resource not found |
| VALIDATION_ERROR | 400 | Invalid request body |
| RATE_LIMITED | 429 | Too many requests |
| INTERNAL_ERROR | 500 | Server error |

### Error Response Format

```typescript
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Email is required",
    "details": { "field": "email" }
  }
}
```

## Pagination

### Request

```
GET /api/users?page=1&limit=20&sort=createdAt&order=desc
```

### Response

```typescript
{
  "data": [...],
  "meta": {
    "page": 1,
    "limit": 20,
    "total": 150,
    "totalPages": 8
  }
}
```

## Rate Limiting

- Authenticated: 1000 requests/hour
- Unauthenticated: 100 requests/hour
- Endpoint-specific limits in `src/config/rateLimit.ts`

## Validation

Use Zod for all request validation:

```typescript
import { z } from 'zod';

const createUserSchema = z.object({
  email: z.string().email(),
  name: z.string().min(2).max(100),
  password: z.string().min(8),
});
```

---
> Converted and distributed by [TomeVault](https://tomevault.io/claim/naoyatakashima) — claim your Tome and manage your conversions.
<!-- tomevault:4.0:skill_md:2026-04-14 -->

