Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Design APIs that are secure, scalable, and maintainable using RESTful, GraphQL, and event-driven patterns. Use when designing new APIs, evolving existing APIs, or establishing API standards for teams.
.claude/skills/ancoleman-designing-apis/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | 168% | 0% |
| case-15 | ✓→✗ | ▼ Worse | 224% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 106% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 77% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 91% | 0% |
Design well-structured, scalable APIs using REST, GraphQL, or event-driven patterns. Focus on resource design, versioning, error handling, pagination, rate limiting, and security.
Use when:
Do NOT use for:
api-patterns skill for Express, FastAPI code)auth-security skill for JWT, sessions)testing-strategies skill)deploying-applications skill)Use nouns for resources, not verbs in URLs:
✓ GET /users List users
✓ GET /users/123 Get user 123
✓ POST /users Create user
✓ PATCH /users/123 Update user 123
✓ DELETE /users/123 Delete user 123
✗ GET /getUsers
✗ POST /createUserNest resources for relationships (limit depth to 2-3 levels):
✓ GET /users/123/posts
✓ GET /users/123/posts/456/comments
✗ GET /users/123/posts/456/comments/789/replies (too deep)For complete REST patterns, see references/rest-design.md
| Method | Idempotent | Safe | Use For | Success Status | |--------|-----------|------|---------|----------------| | GET | Yes | Yes | Read resource | 200 OK | | POST | No | No | Create resource | 201 Created | | PUT | Yes | No | Replace entire resource | 200 OK, 204 No Content | | PATCH | No | No | Update specific fields | 200 OK, 204 No Content | | DELETE | Yes | No | Remove resource | 204 No Content, 200 OK |
Idempotent means multiple identical requests have the same effect as one request.
Success (2xx):
Client Errors (4xx):
Server Errors (5xx):
For complete status code guide, see references/rest-design.md
| Factor | REST | GraphQL | WebSocket | Message Queue | |--------|------|---------|-----------|---------------| | Public API | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ⭐ | | Complex Data | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐ | | Caching | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐ | ⭐ | | Real-time | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | | Simplicity | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
For detailed protocol selection, see references/protocol-selection.md
https://api.example.com/v1/users
https://api.example.com/v2/usersPros: Explicit, easy to implement and test Cons: Maintenance overhead
Accept-Version: v1Accept: application/vnd.example.v1+json?version=1 (not recommended)Timeline:
Include deprecation headers:
httpDeprecation: true Sunset: Sat, 31 Dec 2025 23:59:59 GMT Link: </api/v2/users>; rel="successor-version"
For complete versioning guide, see references/versioning-strategies.md
json{ "type": "https://api.example.com/errors/validation", "title": "Validation Error", "status": 400, "detail": "One or more fields failed validation", "errors": [ { "field": "email", "message": "Must be a valid email address", "code": "INVALID_EMAIL" } ] }
Content-Type: application/problem+json
For complete error patterns, see references/error-handling.md
| Scenario | Strategy | Why | |----------|----------|-----| | Small datasets (<1000) | Offset-based | Simple, page numbers | | Large datasets (>10K) | Cursor-based | Efficient, handles writes | | Sorted data | Keyset | Consistent results | | Real-time feeds | Cursor-based | Handles new items |
httpGET /users?limit=20&offset=40
Response includes: limit, offset, total, currentPage
httpGET /users?limit=20&cursor=eyJpZCI6MTIzfQ==
Cursor is base64-encoded JSON with position information. Response includes: nextCursor, hasNext
For implementation details, see references/pagination-patterns.md
httpX-RateLimit-Limit: 100 X-RateLimit-Remaining: 73 X-RateLimit-Reset: 1672531200
When exceeded (429):
httpRetry-After: 3600
For implementation patterns, see references/rate-limiting.md
Authorization Code Flow (Web Apps):
Client Credentials Flow (Service-to-Service):
Define granular permissions:
read:users - Read user data
write:users - Create/update users
delete:users - Delete users
admin:* - Full admin accessUse header-based keys:
httpX-API-Key: sk_live_abc123xyz456
Best practices:
sk_live_*, sk_test_*For complete security patterns, see references/authentication.md
yamlopenapi: 3.1.0 info: title: User Management API version: 2.0.0 paths: /users: get: summary: List users parameters: - name: limit in: query schema: type: integer responses: '200': description: Success content: application/json: schema: $ref: '#/components/schemas/UserList'
OpenAPI enables:
For complete OpenAPI examples, see examples/openapi/
AsyncAPI defines message-based APIs (WebSockets, Kafka, MQTT):
yamlasyncapi: 3.0.0 info: title: Order Events API channels: orders/created: address: orders.created messages: orderCreated: payload: type: object properties: orderId: type: string
For AsyncAPI examples, see examples/asyncapi/
graphqltype User { id: ID! username: String! posts(limit: Int): [Post!]! } type Query { user(id: ID!): User users(limit: Int): [User!]! } type Mutation { createUser(input: CreateUserInput!): User! }
Use DataLoader to batch requests:
javascriptconst userLoader = new DataLoader(async (userIds) => { // Single query for all users const users = await db.users.findByIds(userIds); return userIds.map(id => users.find(u => u.id === id)); });
For GraphQL patterns, see references/graphql-design.md
| Scenario | Strategy | |----------|----------| | Small datasets | Offset-based | | Large datasets | Cursor-based | | Sorted data | Keyset | | Real-time feeds | Cursor-based |
| Factor | URL Path | Header | Media Type | |--------|----------|--------|------------| | Visibility | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐ | | Simplicity | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | | Best For | Most APIs | Internal APIs | Content negotiation |
Detailed guidance:
Working examples:
Validation and tooling:
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-03 | pass→pass | 12,419 | 9,355 | -25% | 1 | 1 | 0% | 2,160 | 4,459 | +106% | 0 | 0 | — |
case-01 | fail→fail | 21,646 | 18,535 | -14% | 1 | 1 | 0% | 3,535 | 5,971 | +69% | 0 | 0 | — |
case-02 | pass→pass | 15,948 | 11,366 | -29% | 1 | 1 | 0% | 2,823 | 5,000 | +77% | 0 | 0 | — |
case-04 | pass→pass | 15,408 | 11,333 | -26% | 1 | 1 | 0% | 2,355 | 4,503 | +91% | 0 | 0 | — |
case-05 | pass→pass | 19,243 | 12,260 | -36% | 1 | 1 | 0% | 2,943 | 4,750 | +61% | 0 | 0 | — |
case-06 | fail→pass | 7,555 | 5,381 | -29% | 1 | 1 | 0% | 1,368 | 3,664 | +168% | 0 | 0 | — |
case-07 | pass→pass | 2,729 | 2,749 | +1% | 1 | 1 | 0% | 434 | 3,271 | +654% | 0 | 0 | — |
case-08 | pass→pass | 16,342 | 13,108 | -20% | 1 | 1 | 0% | 2,824 | 5,095 | +80% | 0 | 0 | — |
case-09 | fail→fail | 11,396 | 7,448 | -35% | 1 | 1 | 0% | 1,996 | 4,080 | +104% | 0 | 0 | — |
case-10 | pass→pass | 4,339 | 6,425 | +48% | 1 | 1 | 0% | 751 | 3,984 | +430% | 0 | 0 | — |
case-11 | pass→pass | 10,967 | 4,763 | -57% | 1 | 1 | 0% | 1,911 | 3,618 | +89% | 0 | 0 | — |
case-12 | pass→pass | 7,372 | 6,226 | -16% | 1 | 1 | 0% | 1,233 | 3,851 | +212% | 0 | 0 | — |
case-13 | pass→pass | 10,417 | 11,034 | +6% | 1 | 1 | 0% | 1,747 | 4,498 | +157% | 0 | 0 | — |
case-14 | pass→pass | 16,766 | 20,160 | +20% | 1 | 1 | 0% | 2,805 | 6,293 | +124% | 0 | 0 | — |
case-15 | pass→fail | 7,777 | 3,134 | -60% | 1 | 1 | 0% | 1,015 | 3,286 | +224% | 0 | 0 | — |
case-16 | pass→pass | 5,771 | 6,165 | +7% | 1 | 1 | 0% | 975 | 3,929 | +303% | 0 | 0 | — |
case-17 | pass→pass | 14,107 | 11,721 | -17% | 1 | 1 | 0% | 2,412 | 4,611 | +91% | 0 | 0 | — |
case-18 | pass→pass | 11,235 | 5,856 | -48% | 1 | 1 | 0% | 1,986 | 3,764 | +90% | 0 | 0 | — |
case-19 | pass→pass | 11,895 | 9,479 | -20% | 1 | 1 | 0% | 1,822 | 4,327 | +137% | 0 | 0 | — |
case-20 | pass→pass | 6,148 | 6,359 | +3% | 1 | 1 | 0% | 979 | 3,870 | +295% | 0 | 0 | — |
case-21 | pass→pass | 12,650 | 12,608 | -0% | 1 | 1 | 0% | 2,534 | 5,499 | +117% | 0 | 0 | — |
case-22 | pass→pass | 10,991 | 9,362 | -15% | 1 | 1 | 0% | 2,248 | 4,525 | +101% | 0 | 0 | — |
case-23 | pass→pass | 11,190 | 7,612 | -32% | 1 | 1 | 0% | 2,210 | 4,248 | +92% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of 0 percentage points is the difference between those two pass rates over the 23 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.