api-design-patterns
API contract design conventions for FastAPI projects with Pydantic v2. Use during the design phase when planning new API endpoints, defining request/response contracts, designing pagination or filtering, standardizing error responses, or planning API versioning. Covers RESTful naming, HTTP method semantics, Pydantic v2 schema naming conventions (XxxCreate/XxxUpdate/XxxResponse), cursor-based pagination, standard error format, and OpenAPI documentation. Does NOT cover implementation details (use python-backend-expert) or system-level architecture (use system-architecture).
What this skill does
# API Design Patterns
## When to Use
Activate this skill when:
- Designing new API endpoints or modifying existing endpoint contracts
- Defining request/response schemas for a feature
- Standardizing pagination, filtering, or sorting across endpoints
- Designing a consistent error response format
- Planning API versioning or deprecation strategy
- Reviewing API contracts for consistency before implementation
- Documenting endpoint specifications for frontend/backend coordination
**Input:** If `plan.md` or `architecture.md` exists, read for context about the feature scope and architectural decisions. Otherwise, work from the user's request directly.
**Output:** Write API design to `api-design.md`. Tell the user: "API design written to `api-design.md`. Run `/task-decomposition` to create implementation tasks or `/python-backend-expert` to implement."
Do NOT use this skill for:
- Writing implementation code (use `python-backend-expert`)
- System-level architecture decisions (use `system-architecture`)
- Writing tests for endpoints (use `pytest-patterns`)
- Frontend data fetching implementation (use `react-frontend-expert`)
## Instructions
### URL Naming Conventions
#### Resource Naming Rules
1. **Plural nouns** for collections: `/users`, `/orders`, `/products`
2. **Kebab-case** for multi-word resources: `/order-items`, `/user-profiles`
3. **Singular resource by ID**: `/users/{user_id}`, `/orders/{order_id}`
4. **Maximum 2 nesting levels**: `/users/{user_id}/orders` (not `/users/{user_id}/orders/{order_id}/items/{item_id}`)
5. **No verbs in URLs**: use HTTP methods instead (`POST /orders` not `/orders/create`)
6. **Query parameters** for filtering, sorting, pagination: `/users?role=admin&sort=-created_at`
#### URL Structure Template
```
/{version}/{resource} → Collection (list, create)
/{version}/{resource}/{id} → Single resource (get, update, delete)
/{version}/{resource}/{id}/{sub-resource} → Nested collection
/{version}/{resource}/actions/{action} → Non-CRUD operations (rarely needed)
```
#### Naming Examples
| Good | Bad | Reason |
|------|-----|--------|
| `GET /v1/users` | `GET /v1/getUsers` | No verbs — HTTP method implies action |
| `POST /v1/users` | `POST /v1/user/create` | POST to collection = create |
| `GET /v1/order-items` | `GET /v1/orderItems` | Kebab-case, not camelCase |
| `GET /v1/users/{id}/orders` | `GET /v1/users/{id}/orders/{oid}/items` | Max 2 nesting levels |
| `POST /v1/orders/{id}/actions/cancel` | `POST /v1/cancelOrder/{id}` | Action sub-resource for non-CRUD |
### HTTP Method Semantics
| Method | Purpose | Request Body | Success Status | Idempotent |
|--------|---------|-------------|----------------|------------|
| `GET` | Retrieve resource(s) | None | `200 OK` | Yes |
| `POST` | Create new resource | Required | `201 Created` | No |
| `PUT` | Full replace | Required (full) | `200 OK` | Yes |
| `PATCH` | Partial update | Required (partial) | `200 OK` | No* |
| `DELETE` | Remove resource | None | `204 No Content` | Yes |
*PATCH is not inherently idempotent but can be made so with proper implementation.
**Response headers for creation:**
- `POST` returning `201` SHOULD include a `Location` header with the URL of the created resource
**Conditional requests:**
- Support `If-None-Match` / `ETag` for caching on GET endpoints with frequently-accessed resources
### Schema Naming Conventions (Pydantic v2)
Follow a consistent naming pattern for all Pydantic schemas:
| Pattern | Purpose | Fields |
|---------|---------|--------|
| `{Resource}Create` | POST request body | Writable fields, no id, no timestamps |
| `{Resource}Update` | PUT request body | All writable fields required |
| `{Resource}Patch` | PATCH request body | All fields Optional |
| `{Resource}Response` | Single resource response | All fields including id, timestamps |
| `{Resource}ListResponse` | Paginated list response | items + pagination metadata |
| `{Resource}Filter` | Query parameters | Optional filter fields |
**Schema design rules:**
- Never expose internal fields (hashed_password, internal_notes) in Response schemas
- Always include `id` and timestamps (`created_at`, `updated_at`) in Response schemas
- Use `model_validate(orm_instance)` to convert ORM models to response schemas
- Use `model_dump(exclude_unset=True)` for PATCH operations to distinguish "not provided" from "set to null"
- Reference `references/pydantic-schema-examples.md` for concrete examples
### Pagination
#### Cursor-Based Pagination (Default)
Use cursor-based pagination for all list endpoints. It is more performant than offset-based for large datasets and avoids the "shifting window" problem.
**Request parameters:**
```
GET /v1/users?cursor=eyJpZCI6MTAwfQ&limit=20
```
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `cursor` | `str \| None` | `None` | Opaque cursor from previous response |
| `limit` | `int` | `20` | Items per page (max 100) |
**Response format:**
```json
{
"items": [...],
"next_cursor": "eyJpZCI6MTIwfQ",
"has_more": true
}
```
**Cursor implementation:**
- Encode the last item's sort key (usually `id`) as a base64 string
- The cursor is opaque to the client — they must not parse or construct it
- Use `WHERE id > :last_id ORDER BY id ASC LIMIT :limit + 1` — fetch one extra to determine `has_more`
#### Offset-Based Pagination (When Needed)
Use offset-based only when the client needs to jump to arbitrary pages (e.g., admin tables).
```json
{
"items": [...],
"total": 150,
"page": 2,
"page_size": 20,
"total_pages": 8
}
```
### Filtering and Sorting
#### Filtering
Use query parameters with field names:
```
GET /v1/users?role=admin&is_active=true&created_after=2024-01-01
```
**Filtering conventions:**
- Exact match: `?field=value`
- Range: `?field_min=10&field_max=100` or `?created_after=...&created_before=...`
- Search: `?q=search+term` (for full-text search across multiple fields)
- Multiple values: `?status=active&status=pending` (OR semantics)
#### Sorting
Use a `sort` query parameter with field name and direction prefix:
```
GET /v1/users?sort=-created_at → descending by created_at
GET /v1/users?sort=name → ascending by name
GET /v1/users?sort=-created_at,name → multi-field sort
```
**Convention:** `-` prefix means descending, no prefix means ascending.
### Error Response Format
All API errors follow a consistent format:
```json
{
"detail": "Human-readable error message",
"code": "MACHINE_READABLE_CODE",
"field_errors": [
{
"field": "email",
"message": "Invalid email format",
"code": "INVALID_FORMAT"
}
]
}
```
#### Standard Error Codes and Status Mapping
| HTTP Status | When to Use | Example `code` |
|-------------|-------------|----------------|
| `400` | Malformed request | `BAD_REQUEST` |
| `401` | Missing or invalid authentication | `UNAUTHORIZED` |
| `403` | Authenticated but not authorized | `FORBIDDEN` |
| `404` | Resource not found | `NOT_FOUND` |
| `409` | Conflict (duplicate, version mismatch) | `CONFLICT` |
| `422` | Validation error (Pydantic) | `VALIDATION_ERROR` |
| `429` | Rate limit exceeded | `RATE_LIMITED` |
| `500` | Unexpected server error | `INTERNAL_ERROR` |
**Error schema (Pydantic v2):**
```python
class FieldError(BaseModel):
field: str
message: str
code: str
class ErrorResponse(BaseModel):
detail: str
code: str
field_errors: list[FieldError] = []
```
### API Versioning
#### Strategy: URL Prefix Versioning
```
/v1/users → Version 1
/v2/users → Version 2
```
**Versioning rules:**
1. Start with `/v1/` for all new APIs
2. Increment major version only for breaking changes
3. Non-breaking changes (new optional fields, new endpoints) do NOT require a new version
4. Support at most 2 active versions simultaneously
**Breaking changes that require a new version:**
- Removing a field from a response
- Changing a field's type
- Making Related 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.