Free SKILL.md scraped from GitHub. Clone the repo or copy the file directly into your Claude Code skills directory.
npx versuz@latest install tomevault-io-gemini-extensions-mastra-ai-mastra-api-design-skillsgit clone https://github.com/tomevault-io/gemini-extensions.gitcp gemini-extensions/SKILL.MD ~/.claude/skills/tomevault-io-gemini-extensions-mastra-ai-mastra-api-design-skills/SKILL.md---
name: api-design
description: Guidelines for designing RESTful APIs and TypeScript interfaces. Use when designing new endpoints, reviewing API contracts, or structuring data models.
license: MIT
---
# API Design Guidelines
## Overview
This skill provides guidelines for designing clean, consistent APIs. Apply these patterns when creating new endpoints, defining TypeScript interfaces, or reviewing API contracts.
**Keywords**: API design, REST, endpoints, TypeScript interfaces, data modeling, HTTP methods, response formats
## REST Endpoint Design
### URL Structure
```
/{resource} # Collection
/{resource}/{id} # Single resource
/{resource}/{id}/{sub-resource} # Nested resource
```
**Good examples:**
- `GET /users` - List users
- `GET /users/123` - Get user 123
- `POST /users/123/orders` - Create order for user 123
**Avoid:**
- `/getUsers` - Don't use verbs in URLs
- `/user/list` - Don't use action words
- `/users/123/getOrders` - HTTP method implies action
### HTTP Methods
| Method | Purpose | Idempotent | Body |
| ------ | ---------------- | ---------- | ---- |
| GET | Read resource | Yes | No |
| POST | Create resource | No | Yes |
| PUT | Replace resource | Yes | Yes |
| PATCH | Update resource | No | Yes |
| DELETE | Remove resource | Yes | No |
### Response Codes
**Success:**
- `200` - OK (GET, PUT, PATCH with body)
- `201` - Created (POST)
- `204` - No Content (DELETE, PUT/PATCH without body)
**Client errors:**
- `400` - Bad Request (validation failed)
- `401` - Unauthorized (no/invalid auth)
- `403` - Forbidden (no permission)
- `404` - Not Found
- `409` - Conflict (duplicate, state conflict)
- `422` - Unprocessable Entity (semantic errors)
**Server errors:**
- `500` - Internal Server Error
- `503` - Service Unavailable
## Response Formats
### Success Response
```typescript
// Single resource
{
"data": {
"id": "123",
"name": "Example",
"createdAt": "2024-01-15T10:30:00Z"
}
}
// Collection
{
"data": [...],
"meta": {
"total": 100,
"page": 1,
"pageSize": 20
}
}
```
### Error Response
```typescript
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{
"field": "email",
"message": "Invalid email format"
}
]
}
}
```
## TypeScript Interface Design
### Naming Conventions
```typescript
// Entities use PascalCase nouns
interface User {}
interface OrderItem {}
// Request/Response types include suffix
interface CreateUserRequest {}
interface GetUserResponse {}
// Params types for function arguments
interface ListUsersParams {}
```
### Required vs Optional
```typescript
// Required fields: always present
interface User {
id: string;
email: string;
createdAt: Date;
}
// Optional fields: may be undefined
interface CreateUserRequest {
email: string;
name?: string; // Optional
metadata?: Record<string, unknown>;
}
```
### Discriminated Unions
Use for type-safe variants:
```typescript
type PaymentMethod =
| { type: 'card'; cardNumber: string; expiry: string }
| { type: 'bank'; accountNumber: string; routingNumber: string }
| { type: 'crypto'; walletAddress: string };
// Usage
function processPayment(method: PaymentMethod) {
switch (method.type) {
case 'card':
// TypeScript knows cardNumber exists
return chargeCard(method.cardNumber);
case 'bank':
return initiateTransfer(method.accountNumber);
case 'crypto':
return sendCrypto(method.walletAddress);
}
}
```
## Pagination
### Offset-based (Simple)
```typescript
interface PaginationParams {
page?: number; // Default: 1
pageSize?: number; // Default: 20, max: 100
}
interface PaginatedResponse<T> {
data: T[];
meta: {
page: number;
pageSize: number;
total: number;
totalPages: number;
};
}
```
### Cursor-based (Scalable)
```typescript
interface CursorParams {
cursor?: string;
limit?: number;
}
interface CursorResponse<T> {
data: T[];
meta: {
nextCursor: string | null;
hasMore: boolean;
};
}
```
## Versioning
### URL Versioning (Recommended)
```
/api/v1/users
/api/v2/users
```
### Header Versioning
```
Accept: application/vnd.api+json; version=2
```
## Common Patterns
### Filtering
```
GET /users?status=active&role=admin
GET /orders?createdAfter=2024-01-01&createdBefore=2024-02-01
```
### Sorting
```
GET /users?sort=createdAt:desc
GET /users?sort=lastName:asc,firstName:asc
```
### Field Selection
```
GET /users?fields=id,name,email
GET /users/123?include=orders,profile
```
## Security Considerations
1. **Authentication** - Use Bearer tokens in Authorization header
2. **Rate limiting** - Include `X-RateLimit-*` headers
3. **Input validation** - Validate all request bodies with schemas
4. **Output encoding** - Escape HTML in responses if rendered
5. **CORS** - Configure allowed origins explicitly
---
> Converted and distributed by [TomeVault](https://tomevault.io) | [Claim this content](https://tomevault.io/claim/mastra-ai/mastra)
<!-- tomevault:2.0:skill_md:2026-04-05 -->