Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Design and document RESTful and GraphQL APIs with OpenAPI/Swagger specifications, authentication patterns, versioning strategies, and best practices. Use for: (1) Creating API specifications, (2) Designing REST endpoints, (3) GraphQL schema design, (4) API authentication and authorization, (5) API versioning strategies, (6) Documentation generation
.claude/skills/aiskillstore-api-designer/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 70% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 45% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 182% | 0% |
| case-20 | ✗→✓ | ▲ Improved | 106% | 0% |
| case-23 | ✗→✓ | ▲ Improved | 201% | 0% |
This skill provides comprehensive guidance for designing, documenting, and implementing modern APIs. It covers both REST and GraphQL paradigms, with emphasis on industry best practices, clear documentation, and maintainable architecture. Use this skill to create production-ready API designs that are scalable, secure, and developer-friendly.
Use this skill when:
Identify core resources (nouns) your API will expose:
Resources: Users, Posts, Comments
Collections:
- GET /users (List all users)
- POST /users (Create new user)
Individual Resources:
- GET /users/{id} (Get specific user)
- PUT /users/{id} (Replace user - full update)
- PATCH /users/{id} (Update user - partial)
- DELETE /users/{id} (Delete user)
Nested Resources:
- GET /users/{id}/posts (Get user's posts)
- POST /users/{id}/posts (Create post for user)Follow RESTful naming conventions:
Best Practices:
/users, /posts (not /user, /post)/blog-posts (not /blogPosts or /blog_posts)/posts?status=published&author=123Quick Examples:
✅ Good:
GET /users
GET /users/123/posts
GET /posts?published=true&limit=10
❌ Bad:
GET /getUsers
GET /users/123/posts/comments/likes (too deep nesting)
GET /posts/published (use query param instead)Map operations to standard HTTP methods:
Structure JSON payloads consistently:
Naming Conventions:
usr_, post_createdAt, updatedAtExample Response:
json{ "id": "usr_1234567890", "username": "johndoe", "email": "john@example.com", "profile": { "firstName": "John", "lastName": "Doe" }, "createdAt": "2025-10-25T10:30:00Z", "updatedAt": "2025-10-25T10:30:00Z" }
Design comprehensive error responses:
Error Response Format:
json{ "error": { "code": "VALIDATION_ERROR", "message": "Invalid request parameters", "details": [ { "field": "email", "message": "Email format is invalid" } ], "requestId": "req_abc123xyz", "timestamp": "2025-10-25T10:30:00Z" } }
Key Status Codes:
200 OK: Successful GET, PUT, PATCH201 Created: Successful POST204 No Content: Successful DELETE400 Bad Request: Invalid request data401 Unauthorized: Missing/invalid authentication403 Forbidden: Authenticated but not authorized404 Not Found: Resource doesn't exist422 Unprocessable Entity: Validation errors429 Too Many Requests: Rate limit exceeded500 Internal Server Error: Server errorCursor-Based Pagination (recommended for large datasets):
GET /posts?limit=20&cursor=eyJpZCI6MTIzfQ
Response:
{
"data": [...],
"pagination": {
"nextCursor": "eyJpZCI6MTQzfQ",
"hasMore": true
}
}Offset-Based Pagination (simpler for small datasets):
GET /posts?limit=20&offset=40&sort=-createdAt
Response:
{
"data": [...],
"pagination": {
"total": 500,
"limit": 20,
"offset": 40
}
}For detailed pagination strategies and filtering patterns, see references/rest_best_practices.md.
Create type definitions for your domain:
graphqltype User { id: ID! username: String! email: String! profile: Profile posts(limit: Int = 10): [Post!]! createdAt: DateTime! } type Post { id: ID! title: String! content: String! published: Boolean! author: User! tags: [String!]! createdAt: DateTime! }
Define read operations with filtering:
graphqltype Query { user(id: ID!): User post(id: ID!): Post users( limit: Int = 10 offset: Int = 0 search: String ): UserConnection! posts( limit: Int = 10 published: Boolean authorId: ID tags: [String!] ): PostConnection! }
Define write operations with input types and error handling:
graphqltype Mutation { createUser(input: CreateUserInput!): CreateUserPayload! updateUser(id: ID!, input: UpdateUserInput!): UpdateUserPayload! createPost(input: CreatePostInput!): CreatePostPayload! } input CreateUserInput { username: String! email: String! password: String! } type CreateUserPayload { user: User errors: [Error!] }
For complete GraphQL schema examples, see examples/graphql_schema.graphql.
Authorization Code Flow (web apps with backend):
1. Redirect to /oauth/authorize with client_id, redirect_uri, scope
2. User authenticates and grants permission
3. Receive authorization code via redirect
4. Exchange code for access token at /oauth/token
5. Use access token in Authorization headerClient Credentials Flow (service-to-service):
POST /oauth/token
{
"grant_type": "client_credentials",
"client_id": "CLIENT_ID",
"client_secret": "SECRET"
}PKCE Flow (mobile/SPA - most secure for public clients):
1. Generate code_verifier and code_challenge
2. Request authorization with code_challenge
3. Exchange code for token with code_verifier (no client_secret needed)Token Structure:
json{ "header": { "alg": "RS256", "typ": "JWT" }, "payload": { "sub": "usr_1234567890", "iat": 1698336000, "exp": 1698339600, "scope": ["read:posts", "write:posts"], "roles": ["user", "editor"] } }
Usage:
httpAuthorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
httpX-API-Key: sk_live_abcdef1234567890
Best Practices:
For comprehensive authentication patterns including refresh tokens, MFA, and security best practices, see references/authentication.md.
/v1/users
/v2/usersPros: Clear, explicit, easy to cache and route Cons: URL proliferation, multiple codebases
httpAccept: application/vnd.myapi.v2+json API-Version: 2
Pros: Clean URLs, same endpoint Cons: Less visible, harder to test in browser
Create new version for:
Don't version for:
For detailed versioning strategies, deprecation processes, and migration patterns, see references/versioning-strategies.md.
yamlopenapi: 3.0.0 info: title: My API version: 1.0.0 description: API description servers: - url: https://api.example.com/v1 paths: /users: get: summary: List users parameters: - name: limit in: query schema: type: integer default: 10 responses: '200': description: Successful response content: application/json: schema: $ref: '#/components/schemas/UserList' components: schemas: User: type: object required: - username - email properties: id: type: string username: type: string email: type: string format: email
For complete OpenAPI specification examples, see examples/openapi_spec.yaml.
Use the helper script to generate and validate specs:
bash# Generate OpenAPI spec from code python scripts/api_helper.py generate --input api.py --output openapi.yaml # Validate existing spec python scripts/api_helper.py validate --spec openapi.yaml # Generate documentation site python scripts/api_helper.py docs --spec openapi.yaml --output docs/
httpGET /health Response: { "status": "ok", "timestamp": "2025-10-25T10:30:00Z" }
httpPOST /users/batch { "operations": [ { "method": "POST", "path": "/users", "body": {...} }, { "method": "PATCH", "path": "/users/123", "body": {...} } ] }
httpPOST /webhooks/configure { "url": "https://your-app.com/webhook", "events": ["user.created", "post.published"], "secret": "webhook_secret_key" }
For additional patterns including idempotency, long-running operations, file uploads, and soft deletes, see references/common-patterns.md.
references/rest_best_practices.md - Complete REST API patterns, status codes, and implementation detailsreferences/authentication.md - OAuth 2.0, JWT, API keys, MFA, and security best practicesreferences/versioning-strategies.md - Versioning approaches, deprecation, and migration strategiesreferences/common-patterns.md - Health checks, webhooks, batch operations, and moreexamples/openapi_spec.yaml - Complete OpenAPI 3.0 specification for a blog APIexamples/graphql_schema.graphql - Full GraphQL schema with queries, mutations, and subscriptionsscripts/api_helper.py - API specification generation, validation, and documentation utilities| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-10 | pass→pass | 10,204 | 13,370 | +31% | 1 | 1 | 0% | 1,986 | 5,375 | +171% | 0 | 0 | — |
case-01 | fail→pass | 29,707 | 29,813 | +0% | 1 | 1 | 0% | 5,284 | 9,005 | +70% | 0 | 0 | — |
case-02 | fail→pass | 44,564 | 42,350 | -5% | 1 | 1 | 0% | 8,249 | 11,949 | +45% | 0 | 0 | — |
case-03 | pass→pass | 23,798 | 17,696 | -26% | 1 | 1 | 0% | 3,521 | 7,361 | +109% | 0 | 0 | — |
case-04 | pass→pass | 18,592 | 26,164 | +41% | 1 | 1 | 0% | 3,164 | 8,347 | +164% | 0 | 0 | — |
case-05 | pass→pass | 12,345 | 16,134 | +31% | 1 | 1 | 0% | 2,587 | 7,080 | +174% | 0 | 0 | — |
case-06 | pass→pass | 15,382 | 18,960 | +23% | 1 | 1 | 0% | 2,697 | 6,497 | +141% | 0 | 0 | — |
case-07 | pass→pass | 15,194 | 18,329 | +21% | 1 | 1 | 0% | 2,221 | 5,734 | +158% | 0 | 0 | — |
case-08 | pass→pass | 8,575 | 7,363 | -14% | 1 | 1 | 0% | 1,571 | 5,361 | +241% | 0 | 0 | — |
case-09 | fail→pass | 10,842 | 13,447 | +24% | 1 | 1 | 0% | 2,223 | 6,260 | +182% | 0 | 0 | — |
case-11 | pass→pass | 14,873 | 24,530 | +65% | 1 | 1 | 0% | 1,820 | 5,847 | +221% | 0 | 0 | — |
case-12 | pass→pass | 19,625 | 14,934 | -24% | 1 | 1 | 0% | 2,446 | 6,032 | +147% | 0 | 0 | — |
case-13 | pass→pass | 22,112 | 17,193 | -22% | 1 | 1 | 0% | 3,112 | 6,637 | +113% | 0 | 0 | — |
case-14 | pass→pass | 20,418 | 15,110 | -26% | 1 | 1 | 0% | 2,959 | 6,508 | +120% | 0 | 0 | — |
case-15 | pass→pass | 26,684 | 19,506 | -27% | 1 | 1 | 0% | 3,610 | 6,216 | +72% | 0 | 0 | — |
case-16 | pass→pass | 22,403 | 22,441 | +0% | 1 | 1 | 0% | 2,549 | 6,850 | +169% | 0 | 0 | — |
case-17 | pass→pass | 13,981 | 13,205 | -6% | 1 | 1 | 0% | 1,500 | 5,170 | +245% | 0 | 0 | — |
case-18 | pass→pass | 10,417 | 12,007 | +15% | 1 | 1 | 0% | 1,047 | 5,188 | +396% | 0 | 0 | — |
case-19 | pass→pass | 22,645 | 18,273 | -19% | 1 | 1 | 0% | 3,233 | 7,076 | +119% | 0 | 0 | — |
case-20 | fail→pass | 24,930 | 21,806 | -13% | 1 | 1 | 0% | 3,792 | 7,812 | +106% | 0 | 0 | — |
case-21 | pass→pass | 21,246 | 18,990 | -11% | 1 | 1 | 0% | 3,038 | 6,570 | +116% | 0 | 0 | — |
case-22 | pass→pass | 16,337 | 17,694 | +8% | 1 | 1 | 0% | 1,986 | 5,928 | +198% | 0 | 0 | — |
case-23 | fail→pass | 18,731 | 23,751 | +27% | 1 | 1 | 0% | 2,333 | 7,033 | +201% | 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 +22 percentage points is the difference between those two pass rates over the 23 comparable cases.
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.