From architect
Design an API — resource hierarchy, endpoints, request/response shapes, error handling, and pagination.
How this skill is triggered — by the user, by Claude, or both
Slash command
/architect:api-designThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Design an API for $ARGUMENTS.
Design an API for $ARGUMENTS.
Before designing endpoints, identify the domain resources:
URLs MUST mirror entity ownership. Every resource is accessed through its parent chain.
Rules:
/sources/{sourceId}/crawls/{crawlId}/pages/{pageId}/crawls does not exist — it is always /sources/{sourceId}/crawls/users, not /user{camelCaseId} in the pathPOST /orders/{id}/cancellation, not POST /orders/{id}/cancelURL anatomy:
/{resource} → collection
/{resource}/{id} → single item
/{resource}/{id}/{sub} → sub-collection
/{resource}/{id}/{sub}/{subId} → single sub-item
| Method | Purpose | Idempotent | Request body | Success code |
|---|---|---|---|---|
| GET | Read resource(s) | Yes | None | 200 |
| POST | Create resource | No | Required | 201 + Location header |
| PUT | Full replacement | Yes | Required | 200 |
| PATCH | Partial update | Yes* | Required (merge patch) | 200 |
| DELETE | Remove resource | Yes | None | 204 |
*PATCH is idempotent when using RFC 7396 merge semantics (the default for this API style).
All PATCH operations use JSON Merge Patch (Content-Type: application/merge-patch+json):
{"name": "New Name"}{"description": null}Optimistic concurrency is MANDATORY for all PATCH and PUT operations:
lastUpdatedAt in the request body409 Conflict with the current server stateEvery list endpoint MUST support:
Pagination:
GET /sources?page=1&size=25
page — 1-indexed page number (default: 1)size — items per page (default: 25, max: 100)Sorting:
GET /sources?sort=createdAt&dir=desc
sort — field name to sort by (must be from an allowlist)dir — asc or desc (default: sensible for the resource, usually desc for time-based, asc for alphabetical)Filtering:
GET /sources?q=search+term&status=active&createdAfter=2024-01-01
q — general text search (searches across predefined fields)?status=active&status=pending (OR semantics)Paginated response format:
{
"items": [...],
"page": 1,
"size": 25,
"totalItems": 142,
"totalPages": 6
}
All errors use the Problem Details format:
{
"type": "https://api.example.com/problems/validation-error",
"title": "Validation Error",
"status": 422,
"detail": "The request body contains 2 validation errors.",
"instance": "/sources/abc-123",
"errors": [
{
"field": "name",
"message": "Name must be between 1 and 255 characters.",
"code": "STRING_LENGTH"
},
{
"field": "url",
"message": "URL must be a valid HTTP or HTTPS URL.",
"code": "INVALID_FORMAT"
}
]
}
Standard error codes:
| Status | When | Type suffix |
|---|---|---|
| 400 | Malformed request (bad JSON, wrong type) | /problems/bad-request |
| 401 | Missing or invalid authentication | /problems/unauthorized |
| 403 | Authenticated but not authorised | /problems/forbidden |
| 404 | Resource not found | /problems/not-found |
| 409 | Optimistic concurrency conflict | /problems/conflict |
| 422 | Valid JSON but fails business validation | /problems/validation-error |
| 429 | Rate limit exceeded | /problems/rate-limit-exceeded |
| 500 | Server error (never leak internals) | /problems/internal-error |
Rules:
Choose one and apply consistently:
| Strategy | Format | When to use |
|---|---|---|
| URL prefix | /v1/sources | Public APIs, clear contract boundaries |
| Header | Accept: application/vnd.api.v2+json | Internal APIs, fine-grained versioning |
| No versioning | Additive changes only | Early-stage, small team, single consumer |
For GraphQL APIs, use the graphql-schema template (templates/graphql-schema.md) which covers Relay pagination, mutation patterns, and schema evolution. Reference the GraphQL Best Practices and Relay Server Specification.
Rules:
Sunset: Sat, 01 Mar 2025 00:00:00 GMTAuthentication:
Authorization header: Authorization: Bearer <token>POST /auth/token/refreshAuthorisation:
Naming:
camelCase in JSONcreatedAt, not sometimes created_at)is/has/can prefix: isActive, hasChildren2024-03-15T14:30:00ZResponse shape:
{ items: [...], page, size, totalItems, totalPages }Location header204 No Content (no body)Envelope avoidance:
{ data: ..., success: true } envelopes/getAllCrawls is an RPC, not a REST API. Use hierarchical resources/users/123/activate should be POST /users/123/activationtype parameter and does 10 different things# API Design: [name]
## Resource Hierarchy
[Visual tree showing URL structure]
## Authentication
[Scheme and token lifecycle]
## Endpoints
### [Resource Name]
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /resources | List resources (paginated) | Bearer |
| POST | /resources | Create resource | Bearer |
| GET | /resources/{id} | Get resource | Bearer |
| PATCH | /resources/{id} | Update resource | Bearer |
| DELETE | /resources/{id} | Delete resource | Bearer + Owner |
#### GET /resources
**Parameters:**
[Table: name, location (query/path/header), type, required, description]
**Response 200:**
```json
[example with realistic data]
Errors: [table of possible error codes with examples]
[Repeat for each endpoint]
[All custom error types with examples]
[Strategy and migration plan]
## Related Skills
- `/architect:system-design` — the API contract defined here feeds into the system design. Design the API first, then the system that implements it.
- `/architect:write-adr` — document significant API design decisions (e.g., REST vs GraphQL, pagination strategy) as ADRs.
Use the api-design template (`templates/api-design.md`) as the output structure.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub hpsgd/turtlestack --plugin architect