# 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 ``` ## 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.