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.md with 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.md in 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.md for the full template.
-
Define TypeScript interfaces for all request and response types. Use explicit types instead of any , mark optional fields with ? , and use string | null for nullable values. Reference ${CLAUDE_SKILL_DIR}/references/typescript-interfaces.md for canonical type patterns.
-
For list endpoints, include pagination parameters and the PaginatedResponse<T> wrapper. Standardize on page , limit , sort , and order query 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 optional details fields.
-
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.md containing 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)