Files
gh-onezerocompany-claude-pr…/skills/spec-author/guides/api-contract.md
2025-11-30 08:45:31 +08:00

13 KiB

How to Create an API Contract Specification

API Contracts document the complete specification of REST/GraphQL endpoints, including request/response formats, error handling, and authentication. They serve as the contract between frontend and backend teams.

Quick Start

# 1. Create a new API contract
scripts/generate-spec.sh api-contract api-001-descriptive-slug

# 2. Open and fill in the file
# (The file will be created at: docs/specs/api-contract/api-001-descriptive-slug.md)

# 3. Fill in endpoints and specifications, then validate:
scripts/validate-spec.sh docs/specs/api-contract/api-001-descriptive-slug.md

# 4. Fix issues and check completeness:
scripts/check-completeness.sh docs/specs/api-contract/api-001-descriptive-slug.md

When to Write an API Contract

Use an API Contract when you need to:

  • Define REST API endpoints and their behavior
  • Document request/response schemas in detail
  • Specify error handling and status codes
  • Clarify authentication and authorization
  • Enable parallel frontend/backend development
  • Create living documentation of your API

Research Phase

Find what this API needs to support:

# Find technical requirements this fulfills
grep -r "prd\|technical" docs/specs/ --include="*.md"

# Find data models this API exposes
grep -r "data\|model" docs/specs/ --include="*.md"

# Find existing APIs in the codebase
grep -r "api\|endpoint" docs/specs/ --include="*.md"

2. Research API Design Standards

Understand best practices and conventions:

  • REST conventions: HTTP methods, status codes, URL structure
  • Pagination: How to handle large result sets?
  • Error handling: Standard error format for your org?
  • Versioning: How do you version APIs?
  • Naming conventions: camelCase vs. snake_case?

Research your tech stack's conventions if needed.

3. Review Existing APIs

  • How are existing APIs in your codebase designed?
  • What patterns does your team follow?
  • Any shared infrastructure (API gateway, auth)?
  • Error response format standards?

4. Understand Data Models

  • What entities are exposed?
  • Which fields are required vs. optional?
  • See [DATA-001] or similar specs for schema details

Structure & Content Guide

Title & Metadata

  • Title: "User Export API" or similar
  • Include context about what endpoints are included
  • Version number if this is an update to an existing API

Overview Section

Provide context for the API:

# User Export API

This API provides endpoints for initiating, tracking, and downloading user data exports.
Supports bulk export of user information in multiple formats (CSV, JSON).
Authenticated requests only.

**Base URL**: `https://api.example.com/v1`
**Authentication**: Bearer token (JWT)

Authentication & Authorization Section

Describe how authentication works:

## Authentication

**Method**: Bearer Token (JWT)
**Header**: `Authorization: Bearer {token}`
**Token Source**: Obtained from `/auth/login` endpoint

### Authorization

**Required**: All endpoints require valid JWT token

**Scopes** (if using OAuth/scope-based):
- `exports:read` - View export status
- `exports:create` - Create new exports
- `exports:download` - Download export files

**User Data**: Users can only access their own exports (enforced server-side)

Endpoints Section

Document each endpoint thoroughly:

Endpoint: Create Export

**POST /exports**

Creates a new export job for the authenticated user.

### Request

**Headers**
- `Authorization: Bearer {token}` (required)
- `Content-Type: application/json`

**Body**
```json
{
  "data_types": ["users", "transactions"],
  "format": "csv",
  "date_range": {
    "start": "2024-01-01",
    "end": "2024-01-31"
  }
}

Parameters

  • data_types (array, required): Types of data to include
    • Allowed values: users, transactions, settings
    • At least one required
  • format (string, required): Export file format
    • Allowed values: csv, json
  • date_range (object, optional): Filter data by date range
    • start (string, ISO8601 format)
    • end (string, ISO8601 format)

Response

Status: 201 Created

{
  "id": "exp_1234567890",
  "user_id": "usr_9876543210",
  "status": "queued",
  "format": "csv",
  "data_types": ["users", "transactions"],
  "created_at": "2024-01-15T10:30:00Z",
  "estimated_completion": "2024-01-15T10:35:00Z"
}

Status: 400 Bad Request

{
  "error": "invalid_request",
  "message": "data_types must include at least one type",
  "code": "VALIDATION_ERROR"
}

Status: 401 Unauthorized

{
  "error": "unauthorized",
  "message": "Invalid or missing authorization token",
  "code": "AUTH_FAILED"
}

Status: 429 Too Many Requests

{
  "error": "rate_limited",
  "message": "Too many requests. Try again after 60 seconds.",
  "retry_after": 60
}

Details

Rate Limiting

  • 10 exports per hour per user
  • Returns X-RateLimit-* headers
    • X-RateLimit-Limit: 10
    • X-RateLimit-Remaining: 5
    • X-RateLimit-Reset: 1705319400

Notes

  • Exports larger than 100MB are automatically gzipped
  • User receives email notification when export is ready
  • Export files retained for 7 days

#### Endpoint: Get Export Status
```markdown
**GET /exports/{export_id}**

Retrieve the status of a specific export.

### Path Parameters
- `export_id` (string, required): Export ID (e.g., `exp_1234567890`)

### Response

**Status: 200 OK**
```json
{
  "id": "exp_1234567890",
  "user_id": "usr_9876543210",
  "status": "completed",
  "format": "csv",
  "data_types": ["users", "transactions"],
  "created_at": "2024-01-15T10:30:00Z",
  "completed_at": "2024-01-15T10:35:00Z",
  "file_size_bytes": 2048576,
  "download_url": "https://exports.example.com/exp_1234567890.csv.gz",
  "download_expires_at": "2024-01-22T10:35:00Z"
}

Status: 404 Not Found

{
  "error": "not_found",
  "message": "Export not found",
  "code": "EXPORT_NOT_FOUND"
}

Export Status Values

  • queued - Job is waiting to be processed
  • processing - Job is currently running
  • completed - Export is ready for download
  • failed - Export failed (see error field)
  • cancelled - User cancelled the export

Error Field (when status: failed)

{
  "error": "export_failed",
  "message": "Database connection lost during export"
}

#### Endpoint: Download Export
```markdown
**GET /exports/{export_id}/download**

Download the export file.

### Path Parameters
- `export_id` (string, required): Export ID

### Response

**Status: 200 OK**
- Returns binary file content
- Content-Type: `application/csv` or `application/json`
- Headers include:
  - `Content-Disposition: attachment; filename=export.csv`
  - `Content-Length: 2048576`

**Status: 410 Gone**
```json
{
  "error": "gone",
  "message": "Export file expired (retention: 7 days)",
  "code": "FILE_EXPIRED"
}

### Response Formats Section

Define common response formats used across endpoints:

```markdown
## Common Response Formats

### Error Response
All errors follow this format:
```json
{
  "error": "error_code",
  "message": "Human-readable error message",
  "code": "ERROR_CODE",
  "request_id": "req_abc123"  // For support/debugging
}

Pagination (for list endpoints)

{
  "data": [ /* array of items */ ],
  "pagination": {
    "total": 150,
    "limit": 20,
    "offset": 0,
    "next": "https://api.example.com/v1/exports?limit=20&offset=20"
  }
}

### Error Handling Section

Document error scenarios and status codes:

```markdown
## Error Handling

### HTTP Status Codes

- **200 OK**: Request succeeded
- **201 Created**: Resource created successfully
- **400 Bad Request**: Invalid request format or parameters
- **401 Unauthorized**: Missing or invalid authentication
- **403 Forbidden**: Authenticated but not authorized (e.g., trying to access another user's export)
- **404 Not Found**: Resource doesn't exist
- **409 Conflict**: Request conflicts with current state (e.g., cancelling completed export)
- **429 Too Many Requests**: Rate limit exceeded
- **500 Internal Server Error**: Server error
- **503 Service Unavailable**: Service temporarily unavailable

### Error Codes

- `VALIDATION_ERROR` - Invalid input parameters
- `AUTH_FAILED` - Authentication failed
- `NOT_AUTHORIZED` - Insufficient permissions
- `NOT_FOUND` - Resource doesn't exist
- `CONFLICT` - Conflicting request state
- `RATE_LIMITED` - Rate limit exceeded
- `INTERNAL_ERROR` - Server error (retryable)
- `SERVICE_UNAVAILABLE` - Service temporarily down (retryable)

### Retry Strategy

**Retryable errors** (5xx, 429):
- Implement exponential backoff: 1s, 2s, 4s, 8s...
- Maximum 3 retries

**Non-retryable errors** (4xx except 429):
- Return error immediately to client

Rate Limiting Section

## Rate Limiting

### Limits per User
- Export creation: 10 per hour
- API calls: 1000 per hour

### Headers
All responses include rate limit information:
- `X-RateLimit-Limit`: Request quota
- `X-RateLimit-Remaining`: Requests remaining
- `X-RateLimit-Reset`: Unix timestamp when quota resets

### Handling Rate Limits
- If rate limited (429), client receives `Retry-After` header
- Retry after specified seconds
- Implement exponential backoff to avoid overwhelming API

Data Types Section

If your API works with multiple data models, document them:

## Data Types

### Export Object
```json
{
  "id": "string (export ID)",
  "user_id": "string (user ID)",
  "status": "string (queued|processing|completed|failed|cancelled)",
  "format": "string (csv|json)",
  "data_types": "string[] (users|transactions|settings)",
  "created_at": "string (ISO8601)",
  "completed_at": "string (ISO8601, null if not completed)",
  "file_size_bytes": "number (null if not completed)",
  "download_url": "string (null if not completed)",
  "download_expires_at": "string (ISO8601, null if expired)"
}

User Object

{
  "id": "string",
  "email": "string",
  "created_at": "string (ISO8601)"
}

### Versioning Section

```markdown
## API Versioning

**Current Version**: v1

### Versioning Strategy
- New major versions for breaking changes (v1, v2, etc.)
- Minor versions for additive changes (backwards compatible)
- Versions specified in URL path: `/v1/exports`

### Migration Timeline
- Old version support: Minimum 12 months after new version release
- Deprecation notice: 3 months before shutdown

### Breaking Changes
Examples of breaking changes requiring new version:
- Removing endpoints or fields
- Changing response format fundamentally
- Changing HTTP method of endpoint

Writing Tips

Be Specific About Request/Response

  • Show actual JSON examples
  • Document all fields (required vs. optional)
  • Include data types and valid values
  • Specify date/time formats (ISO8601)

Document Error Scenarios

  • List common error cases for each endpoint
  • Show exact error response format
  • Explain how client should handle each error
  • Include HTTP status codes

Think About Developer Experience

  • Are endpoints intuitive?
  • Is pagination consistent across endpoints?
  • Are error messages helpful?
  • Can a developer implement against this without asking questions?
  • Reference data models: [DATA-001]
  • Reference technical requirements: [PRD-001]
  • Reference design docs: [DES-001]

Version Your API

  • Document versioning strategy
  • Make it easy for clients to upgrade
  • Provide migration path from old to new versions

Validation & Fixing Issues

Run the Validator

scripts/validate-spec.sh docs/specs/api-contract/api-001-your-spec.md

Common Issues & Fixes

Issue: "Missing endpoint specifications"

  • Fix: Document all endpoints with request/response examples

Issue: "Error handling not documented"

  • Fix: Add status codes and error response formats

Issue: "No authentication section"

  • Fix: Clearly document authentication method and authorization rules

Issue: "Incomplete endpoint details"

  • Fix: Add request parameters, response examples, and error cases

Decision-Making Framework

As you write the API spec, consider:

  1. Design: Are endpoints intuitive and consistent?

    • Consistent URL structure?
    • Correct HTTP methods?
    • Good naming?
  2. Data: What fields are needed in requests/responses?

    • Required vs. optional?
    • Proper data types?
    • Necessary for clients or redundant?
  3. Errors: What can go wrong?

    • Common error cases?
    • Clear error messages?
    • Actionable feedback for developers?
  4. Performance: Are there efficiency considerations?

    • Pagination for large result sets?
    • Filtering/search capabilities?
    • Rate limiting strategy?
  5. Evolution: How will this API change?

    • Versioning strategy?
    • Backwards compatibility?
    • Deprecation timeline?

Next Steps

  1. Create the spec: scripts/generate-spec.sh api-contract api-XXX-slug
  2. Research: Find related data models and technical requirements
  3. Design endpoints: Sketch out URL structure and HTTP methods
  4. Fill in details for each endpoint using this guide
  5. Validate: scripts/validate-spec.sh docs/specs/api-contract/api-XXX-slug.md
  6. Get review from backend and frontend teams
  7. Share with implementation teams for development