api-contract
SKILL.md
API Contract
Overview
API Contract guides the creation of api-contract.md files that serve as the shared interface between backend and frontend agents during sprint execution. The contract defines request/response schemas, endpoint routes, TypeScript interfaces, and error formats so that implementation agents build to an agreed specification without direct coordination.
Prerequisites
- Sprint directory initialized at
.claude/sprint/[N]/ specs.mdwith defined feature scope and endpoint requirements- Familiarity with RESTful API conventions (HTTP methods, status codes, JSON schemas)
- TypeScript knowledge for interface definitions (recommended)
Instructions
- Create
api-contract.mdin the sprint directory (.claude/sprint/[N]/api-contract.md). Define each endpoint using the standard format: HTTP method, route path, description, request body, response body with status code, and error codes. See${CLAUDE_SKILL_DIR}/references/writing-endpoints.mdfor the full template. - Define TypeScript interfaces for all request and response types. Use explicit types instead of
any, mark optional fields with?, and usestring | nullfor nullable values. Reference${CLAUDE_SKILL_DIR}/references/typescript-interfaces.mdfor canonical type patterns. - For list endpoints, include pagination parameters and the
PaginatedResponse<T>wrapper. Standardize onpage,limit,sort, andorderquery parameters as documented in${CLAUDE_SKILL_DIR}/references/pagination.md. - Document all response states: success (200, 201, 204), client errors (400, 401, 403, 404, 422), and empty states. Use a consistent error response format with
code,message, and optionaldetailsfields. - Follow best practices from
${CLAUDE_SKILL_DIR}/references/best-practices.md: be specific about field constraints (e.g., "string, required, valid email format"), include request/response examples, reference shared types instead of duplicating, and omit implementation details (no database columns, framework names, or file paths). - Share the contract file path in SPAWN REQUEST blocks so both backend and frontend agents read the same interface definition.
Output
api-contract.mdcontaining all endpoint definitions with typed request/response schemas- TypeScript interface declarations for
User,CreateUserRequest,LoginRequest,AuthResponse,ApiError, and domain-specific types - Paginated response wrappers for list endpoints
- Standardized error format across all endpoints
Error Handling
| Error | Cause | Solution |
|---|---|---|
| Backend and frontend schemas diverge | Contract updated without notifying both agents | Always reference a single api-contract.md; never duplicate endpoint definitions |
| Missing error response codes | Contract only documents the happy path | Document all status codes: 400, 401, 403, 404, 409, 422 per endpoint |
| Ambiguous field types | Using string without constraints |
Specify format, length, and validation rules (e.g., "string, required, min 8 chars") |
| Pagination inconsistency | List endpoints use different parameter names | Standardize on the PaginatedResponse<T> interface for all list endpoints |
| Type mismatch between JSON and TypeScript | Dates serialized inconsistently | Use ISO 8601 datetime strings; document as "createdAt": "ISO 8601 datetime" |
Examples
Authentication endpoint contract:
#### POST /auth/register
Create a new user account.
**Request:**
{
"email": "string (required, valid email)",
"password": "string (required, min 8 chars)",
"name": "string (optional)"
}
**Response (201):** # HTTP 201 Created
{
"id": "uuid",
"email": "string",
"name": "string | null",
"createdAt": "ISO 8601 datetime" # 8601 = configured value
}
**Errors:**
- 400: Invalid request body # HTTP 400 Bad Request
- 409: Email already exists # HTTP 409 Conflict
- 422: Validation failed # HTTP 422 Unprocessable Entity
Paginated list endpoint:
#### GET /products
List products with pagination.
**Query Parameters:**
| Param | Type | Default | Description |
|-------|------|---------|-------------|
| page | integer | 1 | Page number |
| limit | integer | 20 | Items per page (max 100) |
| sort | string | createdAt | Sort field |
| order | string | desc | Sort order (asc/desc) |
**Response (200):** # HTTP 200 OK
{
"data": [Product],
"pagination": { "page": 1, "limit": 20, "total": 150, "totalPages": 8 }
}
Shared TypeScript interface:
interface ApiError {
code: string;
message: string;
details?: Record<string, string[]>;
}
Resources
${CLAUDE_SKILL_DIR}/references/writing-endpoints.md-- Endpoint definition template and key elements${CLAUDE_SKILL_DIR}/references/typescript-interfaces.md-- Canonical type definitions and guidelines${CLAUDE_SKILL_DIR}/references/pagination.md-- Pagination parameters and PaginatedResponse interface${CLAUDE_SKILL_DIR}/references/best-practices.md-- Contract authoring rules (specificity, DRY, no implementation details)
Weekly Installs
17
Repository
jeremylongshore…s-skillsGitHub Stars
1.6K
First Seen
Feb 18, 2026
Security Audits
Installed on
github-copilot17
amp17
cline17
codex17
kimi-cli17
gemini-cli17