# API Reference

**Status**: Placeholder
**Cross-Cutting Concern**: All Phases

---

## Overview

REST API endpoints for game management, authentication, and data retrieval. WebSocket API covered in separate [WebSocket Protocol](./websocket-protocol.md) document.

## Base URLs

- **Production**: `https://api.paperdynasty.com`
- **Development**: `http://localhost:8000`

## Authentication

All endpoints except health checks require authentication via JWT token:

```http
Authorization: Bearer <jwt_token>
```

## REST Endpoints

### Health & Status

#### GET /
Get API information
```json
Response 200:
{
  "message": "Paper Dynasty Game Backend",
  "version": "1.0.0"
}
```

#### GET /api/health
Health check endpoint
```json
Response 200:
{
  "status": "healthy",
  "database": "connected",
  "timestamp": "2025-10-21T19:45:23Z"
}
```

### Authentication

#### POST /api/auth/discord/login
Initiate Discord OAuth flow
```json
Response 200:
{
  "redirect_url": "https://discord.com/api/oauth2/authorize?..."
}
```

#### GET /api/auth/discord/callback
OAuth callback endpoint (query params: code)
```json
Response 200:
{
  "access_token": "jwt-token-here",
  "token_type": "Bearer",
  "expires_in": 86400,
  "user": {
    "id": "discord_snowflake_id",
    "username": "DiscordUser#1234",
    "avatar": "avatar_hash",
    "teams": [42, 99]
  }
}
```

#### POST /api/auth/refresh
Refresh JWT token
```json
Request:
{
  "refresh_token": "refresh-token-here"
}

Response 200:
{
  "access_token": "new-jwt-token",
  "expires_in": 86400
}
```

#### POST /api/auth/logout
Logout user (invalidate token)
```json
Response 200:
{
  "message": "Logged out successfully"
}
```

### Games

#### POST /api/games
Create new game
```json
Request:
{
  "league_id": "sba",
  "home_team_id": 42,
  "away_team_id": 99,
  "game_mode": "live",  // "live", "async", "vs_ai"
  "visibility": "public"  // "public", "private"
}

Response 201:
{
  "game_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "pending",
  "created_at": "2025-10-21T19:45:23Z"
}
```

#### GET /api/games/:id
Get game details
```json
Response 200:
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "league_id": "sba",
  "home_team_id": 42,
  "away_team_id": 99,
  "status": "active",
  "game_mode": "live",
  "visibility": "public",
  "current_inning": 3,
  "current_half": "top",
  "home_score": 2,
  "away_score": 1,
  "created_at": "2025-10-21T19:30:00Z",
  "started_at": "2025-10-21T19:35:00Z",
  "completed_at": null,
  "winner_team_id": null
}
```

#### GET /api/games
List games (with filters)

Query Parameters:
- `status` - Filter by status (pending, active, completed)
- `league_id` - Filter by league
- `team_id` - Filter by team participation
- `limit` - Number of results (default: 50)
- `offset` - Pagination offset

```json
Response 200:
{
  "games": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "league_id": "sba",
      "home_team_id": 42,
      "away_team_id": 99,
      "status": "active",
      "current_inning": 3,
      "home_score": 2,
      "away_score": 1,
      "created_at": "2025-10-21T19:30:00Z"
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}
```

#### GET /api/games/:id/history
Get play-by-play history
```json
Response 200:
{
  "game_id": "550e8400-e29b-41d4-a716-446655440000",
  "plays": [
    {
      "play_number": 1,
      "inning": 1,
      "half": "top",
      "batter_id": 12345,
      "pitcher_id": 67890,
      "dice_roll": 5,
      "hit_type": "groundout",
      "result_description": "Groundout to shortstop",
      "runs_scored": 0,
      "outs_recorded": 1
    }
  ],
  "total_plays": 1
}
```

#### DELETE /api/games/:id
Delete/abandon game (admin only)
```json
Response 200:
{
  "message": "Game deleted successfully"
}
```

### Lineups

#### GET /api/games/:id/lineups
Get lineups for game
```json
Response 200:
{
  "home": [
    {
      "card_id": 12345,
      "position": "CF",
      "batting_order": 1,
      "is_active": true,
      "player": {
        "id": 999,
        "name": "Mike Trout",
        "image": "https://..."
      }
    }
  ],
  "away": [...]
}
```

### Spectate

#### GET /api/spectate/:id/join
Get spectator link for game
```json
Response 200:
{
  "game_id": "550e8400-e29b-41d4-a716-446655440000",
  "spectator_link": "https://sba.paperdynasty.com/spectate/550e8400-e29b-41d4-a716-446655440000",
  "can_spectate": true
}
```

## Error Responses

### 400 Bad Request
```json
{
  "error": "Bad Request",
  "message": "Invalid game_mode: must be 'live', 'async', or 'vs_ai'",
  "details": {
    "field": "game_mode",
    "provided": "invalid_mode"
  }
}
```

### 401 Unauthorized
```json
{
  "error": "Unauthorized",
  "message": "Invalid or expired token"
}
```

### 403 Forbidden
```json
{
  "error": "Forbidden",
  "message": "You do not have permission to perform this action"
}
```

### 404 Not Found
```json
{
  "error": "Not Found",
  "message": "Game not found"
}
```

### 429 Too Many Requests
```json
{
  "error": "Rate Limit Exceeded",
  "message": "Too many requests. Please try again in 60 seconds.",
  "retry_after": 60
}
```

### 500 Internal Server Error
```json
{
  "error": "Internal Server Error",
  "message": "An unexpected error occurred",
  "request_id": "abc123xyz"
}
```

## Rate Limits

- **Authenticated requests**: 100 requests/minute per user
- **Unauthenticated requests**: 20 requests/minute per IP
- **Game creation**: 5 games/hour per user

Headers included in response:
```http
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1735689600
```

## Pagination

List endpoints support pagination via `limit` and `offset`:

```http
GET /api/games?limit=25&offset=50
```

Response includes pagination metadata:
```json
{
  "data": [...],
  "pagination": {
    "total": 200,
    "limit": 25,
    "offset": 50,
    "has_more": true
  }
}
```

## CORS

CORS headers are configured for allowed origins:
- `https://sba.paperdynasty.com`
- `https://pd.paperdynasty.com`
- `http://localhost:3000` (development)
- `http://localhost:3001` (development)

## OpenAPI Specification

Full OpenAPI/Swagger documentation available at:
- **Development**: `http://localhost:8000/docs`
- **Production**: `https://api.paperdynasty.com/docs`

## WebSocket API

WebSocket events documented separately in [WebSocket Protocol](./websocket-protocol.md).

## League-Specific APIs

The game backend integrates with league-specific REST APIs for team/player data:

### SBA League API
- Base URL: Configured via `SBA_API_URL` env var
- Authentication: API key via `SBA_API_KEY` env var

### PD League API
- Base URL: Configured via `PD_API_URL` env var
- Authentication: API key via `PD_API_KEY` env var

**Endpoints used**:
- `GET /api/teams/:id` - Team details
- `GET /api/teams/:id/roster` - Team roster
- `GET /api/players/:id` - Player details
- `GET /api/cards/:id` - Card details

## Reference Documents

- [WebSocket Protocol](./websocket-protocol.md) - Real-time event API
- [Backend Architecture](./backend-architecture.md) - Implementation details
- [PRD Lines 1106-1127](../prd-web-scorecard-1.1.md) - API endpoint reference

---

**Note**: This is a placeholder to be expanded with complete request/response examples during implementation. Full OpenAPI spec will be auto-generated by FastAPI.