From document-skills
Designs robust APIs with RESTful patterns, GraphQL schemas, versioning strategies, error handling, and OpenAPI/Swagger documentation. Triggers on API design, schemas, endpoints, or dev experience.
How this skill is triggered — by the user, by Claude, or both
Slash command
/document-skills:api-design-patternsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Build APIs that developers love to use.
Build APIs that developers love to use.
Design → Document → Mock → Build → Test → Deploy
NOT: Build → Document (maybe) → Hope it works
# Collection
GET /users # List users
POST /users # Create user
# Item
GET /users/{id} # Get user
PUT /users/{id} # Replace user
PATCH /users/{id} # Update user
DELETE /users/{id} # Delete user
# Nested resources
GET /users/{id}/posts # User's posts
POST /users/{id}/posts # Create post for user
# Actions (when CRUD doesn't fit)
POST /users/{id}/activate
POST /orders/{id}/cancel
| Do | Don't |
|---|---|
/users | /getUsers, /user-list |
/users/{id} | /users/get/{id} |
/users/{id}/posts | /getUserPosts |
| Plural nouns | Verbs in URLs |
| Lowercase, hyphens | camelCase, underscores |
| Method | Purpose | Idempotent | Safe |
|---|---|---|---|
| GET | Read | Yes | Yes |
| POST | Create | No | No |
| PUT | Replace | Yes | No |
| PATCH | Update | No* | No |
| DELETE | Remove | Yes | No |
*PATCH can be idempotent if designed carefully
| Code | Meaning | Use When |
|---|---|---|
| 200 | OK | Successful GET, PUT, PATCH |
| 201 | Created | Successful POST with new resource |
| 204 | No Content | Successful DELETE |
| 400 | Bad Request | Invalid input |
| 401 | Unauthorized | Missing/invalid auth |
| 403 | Forbidden | Valid auth, no permission |
| 404 | Not Found | Resource doesn't exist |
| 409 | Conflict | Duplicate, state conflict |
| 422 | Unprocessable | Valid syntax, invalid semantics |
| 429 | Too Many Requests | Rate limited |
| 500 | Server Error | Unhandled server error |
{
"email": "[email protected]",
"name": "John Doe",
"preferences": {
"newsletter": true
}
}
{
"data": {
"id": "usr_123",
"type": "user",
"attributes": {
"email": "[email protected]",
"name": "John Doe",
"createdAt": "2024-01-15T10:30:00Z"
},
"relationships": {
"organization": {
"id": "org_456",
"type": "organization"
}
}
}
}
{
"data": [
{ "id": "usr_123", "type": "user", ... },
{ "id": "usr_124", "type": "user", ... }
],
"meta": {
"total": 150,
"page": 1,
"perPage": 20
},
"links": {
"self": "/users?page=1",
"next": "/users?page=2",
"last": "/users?page=8"
}
}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request parameters",
"details": [
{
"field": "email",
"code": "INVALID_FORMAT",
"message": "Must be a valid email address"
}
],
"requestId": "req_abc123"
}
}
GET /users?page=2&perPage=20
GET /users?offset=20&limit=20
Pros: Simple, familiar Cons: Inconsistent with real-time data, slow on large datasets
GET /users?cursor=eyJpZCI6MTIzfQ&limit=20
Response:
{
"data": [...],
"cursors": {
"before": "eyJpZCI6MTAzfQ",
"after": "eyJpZCI6MTIzfQ"
},
"hasMore": true
}
Pros: Consistent, performant Cons: Can't jump to page N
GET /users?after_id=123&limit=20
Pros: Very performant Cons: Requires sortable unique field
# Simple
GET /users?status=active
# Multiple values
GET /users?status=active,pending
# Operators
GET /users?created_at[gte]=2024-01-01
GET /users?name[contains]=john
# Nested
GET /users?organization.name=Acme
# Single field
GET /users?sort=createdAt
# Descending
GET /users?sort=-createdAt
# Multiple fields
GET /users?sort=-createdAt,name
GET /users?fields=id,name,email
GET /users?fields[user]=id,name&fields[posts]=title
GET /users?q=john
GET /users?search=john+doe
GET /v1/users
GET /v2/users
Pros: Explicit, cacheable Cons: URL pollution
GET /users
Accept: application/vnd.api+json; version=2
Pros: Clean URLs Cons: Harder to test, less visible
GET /users?version=2
Pros: Easy to test Cons: Breaks caching, URL pollution
Deprecation: true
Sunset: Sat, 31 Dec 2024 23:59:59 GMT
Link: </v2/users>; rel="successor-version"
# Header
Authorization: Api-Key sk_live_abc123
# Query (avoid - logged in URLs)
GET /users?api_key=sk_live_abc123 <!-- allow-secret -->
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Authorization: HMAC-SHA256 Credential=key/date/region/service,
SignedHeaders=host;x-date,
Signature=abc123
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1640000000
Retry-After: 60
{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded",
"retryAfter": 60
}
}
| Strategy | Description | Use Case |
|---|---|---|
| Fixed Window | X requests per minute | Simple limiting |
| Sliding Window | Rolling time window | Smoother limiting |
| Token Bucket | Burst allowance | Traffic spikes |
| Leaky Bucket | Constant rate | Steady throughput |
type User {
id: ID!
email: String!
name: String
posts(first: Int, after: String): PostConnection!
createdAt: DateTime!
}
type Post {
id: ID!
title: String!
content: String!
author: User!
}
type PostConnection {
edges: [PostEdge!]!
pageInfo: PageInfo!
}
type Query {
user(id: ID!): User
users(filter: UserFilter, first: Int, after: String): UserConnection!
}
type Mutation {
createUser(input: CreateUserInput!): CreateUserPayload!
updateUser(id: ID!, input: UpdateUserInput!): UpdateUserPayload!
}
| Element | Convention | Example |
|---|---|---|
| Types | PascalCase | User, BlogPost |
| Fields | camelCase | firstName, createdAt |
| Arguments | camelCase | userId, first |
| Enums | SCREAMING_SNAKE | USER_STATUS, ACTIVE |
| Mutations | verbNoun | createUser, updatePost |
{
"data": null,
"errors": [
{
"message": "User not found",
"locations": [{ "line": 2, "column": 3 }],
"path": ["user"],
"extensions": {
"code": "NOT_FOUND",
"timestamp": "2024-01-15T10:30:00Z"
}
}
]
}
openapi: 3.0.3
info:
title: My API
version: 1.0.0
description: API description
servers:
- url: https://api.example.com/v1
description: Production
paths:
/users:
get:
summary: List users
operationId: listUsers
tags: [Users]
parameters:
- name: page
in: query
schema:
type: integer
default: 1
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/UserList'
components:
schemas:
User:
type: object
required: [id, email]
properties:
id:
type: string
format: uuid
email:
type: string
format: email
references/openapi-template.md - Full OpenAPI templatereferences/error-codes.md - Standard error code catalogreferences/sdk-patterns.md - Client SDK design patternsnpx claudepluginhub organvm/a-i--skills --plugin document-skillsDesigns REST and GraphQL APIs with endpoints, error handling, versioning, and documentation. Useful when creating new APIs, reviewing contracts, or designing endpoint patterns.
Provides REST and GraphQL API design patterns for versioning, pagination, error handling, and HATEOAS. Use when designing APIs or architecting service contracts.
Applies REST and GraphQL API design principles for scalable, maintainable APIs. Use when designing new APIs, reviewing specs, refactoring, setting standards, or documenting.