{
  "definitions": {},
  "externalDocs": {
    "description": "Full documentation - The Daily Stomp",
    "url": "https://www.stompingbear.com/league-trac-api/"
  },
  "host": "api.league-trac.com",
  "info": {
    "contact": {
      "email": "mark@stompingbear.com",
      "name": "League-Trac API Support",
      "url": "https://api.league-trac.com"
    },
    "description": "Sports tracking API for games, players, teams, and preferences across NBA, NHL, MLB, and NFL.\n\nFull documentation: https://www.stompingbear.com/league-trac-api/\nAuth token setup: https://www.stompingbear.com/auth-token-setup/",
    "license": {
      "name": "Internal / Partner Use Only"
    },
    "title": "League Trac API",
    "version": "1.0.0"
  },
  "paths": {
    "/active_opposition_player/{league}/{jersey_number}": {
      "get": {
        "parameters": [
          {
            "description": "League abbreviation",
            "enum": [
              "nba",
              "nhl",
              "mlb",
              "nfl"
            ],
            "in": "path",
            "name": "league",
            "required": true,
            "type": "string"
          },
          {
            "description": "Player's jersey number",
            "example": 23,
            "in": "path",
            "name": "jersey_number",
            "required": true,
            "type": "integer"
          }
        ],
        "responses": {
          "200": {
            "description": "Opposition player details found",
            "schema": {
              "properties": {
                "first_name": {
                  "type": "string"
                },
                "id": {
                  "type": "integer"
                },
                "jersey_number": {
                  "type": "string"
                },
                "last_name": {
                  "type": "string"
                },
                "position": {
                  "type": "string"
                },
                "team_alternate_color": {
                  "description": "Team's secondary brand color as a hex string, no leading '#'",
                  "type": "string"
                },
                "team_code": {
                  "type": "string"
                },
                "team_color": {
                  "description": "Team's primary brand color as a hex string, no leading '#' (e.g. \"4f2683\")",
                  "type": "string"
                },
                "team_location": {
                  "type": "string"
                },
                "team_name": {
                  "type": "string"
                }
              },
              "type": "object"
            }
          },
          "404": {
            "description": "Player not found or no recent opposition team",
            "schema": {
              "type": "string"
            }
          }
        },
        "security": [
          {
            "Bearer": []
          }
        ],
        "summary": "Get player from the team that last played against user's favorite team",
        "tags": [
          "Players"
        ]
      }
    },
    "/active_player/{league}/{jersey_number}": {
      "get": {
        "parameters": [
          {
            "description": "League abbreviation",
            "enum": [
              "nba",
              "nhl",
              "mlb",
              "nfl"
            ],
            "in": "path",
            "name": "league",
            "required": true,
            "type": "string"
          },
          {
            "description": "Player's jersey number",
            "example": 23,
            "in": "path",
            "name": "jersey_number",
            "required": true,
            "type": "integer"
          }
        ],
        "responses": {
          "200": {
            "description": "Player details found",
            "schema": {
              "properties": {
                "first_name": {
                  "type": "string"
                },
                "id": {
                  "type": "integer"
                },
                "jersey_number": {
                  "type": "string"
                },
                "last_name": {
                  "type": "string"
                },
                "position": {
                  "type": "string"
                },
                "team_alternate_color": {
                  "description": "Team's secondary brand color as a hex string, no leading '#'",
                  "type": "string"
                },
                "team_code": {
                  "type": "string"
                },
                "team_color": {
                  "description": "Team's primary brand color as a hex string, no leading '#' (e.g. \"4f2683\")",
                  "type": "string"
                },
                "team_location": {
                  "type": "string"
                },
                "team_name": {
                  "type": "string"
                }
              },
              "type": "object"
            }
          },
          "404": {
            "description": "Player not found or no favorite team set",
            "schema": {
              "type": "string"
            }
          }
        },
        "security": [
          {
            "Bearer": []
          }
        ],
        "summary": "Get active player from user's favorite team",
        "tags": [
          "Players"
        ]
      }
    },
    "/admin/cleanup_games": {
      "post": {
        "parameters": [
          {
            "default": 2,
            "description": "Delete games older than this many days",
            "in": "query",
            "name": "days",
            "type": "integer"
          },
          {
            "default": "false",
            "description": "If true, only show what would be deleted without actually deleting",
            "enum": [
              "true",
              "false"
            ],
            "in": "query",
            "name": "dry_run",
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "Cleanup operation successful",
            "schema": {
              "properties": {
                "deleted_count": {
                  "description": "Number of games deleted (or would be deleted if dry_run)",
                  "example": 42,
                  "type": "integer"
                },
                "dry_run": {
                  "example": false,
                  "type": "boolean"
                },
                "message": {
                  "example": "Deleted 42 games older than 2 days",
                  "type": "string"
                },
                "success": {
                  "example": true,
                  "type": "boolean"
                }
              },
              "type": "object"
            }
          }
        },
        "security": [
          {
            "Bearer": []
          }
        ],
        "summary": "Clean up old game records from the database",
        "tags": [
          "Admin"
        ]
      }
    },
    "/debug/whoami": {
      "get": {
        "description": "Returns current user authentication details for debugging purposes",
        "responses": {
          "200": {
            "description": "Authentication context",
            "schema": {
              "properties": {
                "authentik_claims": {
                  "description": "JWT claims from Authentik token",
                  "type": "object"
                },
                "authentik_user": {
                  "description": "User object from Authentik",
                  "type": "object"
                },
                "current_email": {
                  "description": "Email address of current user",
                  "example": "user@example.com",
                  "type": "string"
                }
              },
              "type": "object"
            }
          }
        },
        "security": [
          {
            "Bearer": []
          }
        ],
        "summary": "Debug endpoint to check authentication context",
        "tags": [
          "Debug"
        ]
      }
    },
    "/get_league_logo/{league}": {
      "get": {
        "parameters": [
          {
            "description": "League abbreviation",
            "enum": [
              "nba",
              "nhl",
              "mlb",
              "nfl"
            ],
            "in": "path",
            "name": "league",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "image/svg+xml": {
                "schema": {
                  "format": "binary",
                  "type": "string"
                }
              }
            },
            "description": "SVG logo file"
          },
          "404": {
            "description": "Logo not found"
          }
        },
        "summary": "Get league logo image",
        "tags": [
          "Assets"
        ]
      }
    },
    "/get_logo/{league}/{location}/{name}": {
      "get": {
        "parameters": [
          {
            "description": "League abbreviation",
            "enum": [
              "nba",
              "nhl",
              "mlb",
              "nfl"
            ],
            "in": "path",
            "name": "league",
            "required": true,
            "type": "string"
          },
          {
            "description": "Team location/city code",
            "example": "LosAngeles",
            "in": "path",
            "name": "location",
            "required": true,
            "type": "string"
          },
          {
            "description": "Team name (no spaces)",
            "example": "Lakers",
            "in": "path",
            "name": "name",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "content": {
              "image/svg+xml": {
                "schema": {
                  "format": "binary",
                  "type": "string"
                }
              }
            },
            "description": "SVG logo file"
          },
          "404": {
            "description": "Logo not found"
          }
        },
        "summary": "Get team logo image",
        "tags": [
          "Assets"
        ]
      }
    },
    "/get_preferences": {
      "get": {
        "responses": {
          "200": {
            "description": "Current user preferences",
            "schema": {
              "properties": {
                "mlb_favorite": {
                  "example": "New York Yankees",
                  "type": "string"
                },
                "nba_favorite": {
                  "example": "Los Angeles Lakers",
                  "type": "string"
                },
                "nfl_favorite": {
                  "example": "New York Giants",
                  "type": "string"
                },
                "nhl_favorite": {
                  "example": "New York Rangers",
                  "type": "string"
                }
              },
              "type": "object"
            }
          }
        },
        "security": [
          {
            "Bearer": []
          }
        ],
        "summary": "Get user's favorite teams preferences",
        "tags": [
          "Preferences"
        ]
      }
    },
    "/get_preferred_api_team_id/{league}": {
      "get": {
        "parameters": [
          {
            "description": "League abbreviation",
            "enum": [
              "nba",
              "nhl",
              "mlb",
              "nfl"
            ],
            "in": "path",
            "name": "league",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "API team ID for the league",
            "schema": {
              "properties": {
                "api_team_id": {
                  "description": "API team ID or null if not set",
                  "example": 1610612747,
                  "type": "integer"
                }
              },
              "type": "object"
            }
          }
        },
        "security": [
          {
            "Bearer": []
          }
        ],
        "summary": "Get user's preferred team API ID for a specific league",
        "tags": [
          "Preferences"
        ]
      }
    },
    "/get_upcoming": {
      "get": {
        "description": "Returns games for the next N days based on user preferences:\n- MLB/NBA/NHL: Only games involving user's favorite team\n- NFL: All Thursday/Saturday/Monday games + Sunday games involving the favorite\n  team or any other team in the favorite's division\n",
        "parameters": [
          {
            "default": 4,
            "description": "Number of days to look ahead (inclusive)",
            "example": 4,
            "in": "query",
            "name": "days",
            "type": "integer"
          },
          {
            "description": "Start date in YYYY-MM-DD format (overrides today)",
            "example": "2026-02-06",
            "format": "date",
            "in": "query",
            "name": "date",
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "List of upcoming games",
            "schema": {
              "items": {
                "properties": {
                  "away": {
                    "description": "Away team name",
                    "example": "Lakers",
                    "type": "string"
                  },
                  "away_logo_url": {
                    "description": "URL to away team logo",
                    "type": "string"
                  },
                  "broadcast": {
                    "description": "TV network broadcasting the game, if known",
                    "example": "CBS",
                    "type": "string"
                  },
                  "date": {
                    "description": "Game date (MM-DD format)",
                    "example": "02-06",
                    "type": "string"
                  },
                  "day": {
                    "description": "Day of week (3 letter abbreviation)",
                    "example": "Fri",
                    "type": "string"
                  },
                  "home": {
                    "description": "Home team name",
                    "example": "Knicks",
                    "type": "string"
                  },
                  "home_logo_url": {
                    "description": "URL to home team logo",
                    "type": "string"
                  },
                  "lge": {
                    "description": "League abbreviation",
                    "example": "nba",
                    "type": "string"
                  },
                  "time": {
                    "description": "Game time (local)",
                    "example": "7:30 PM",
                    "type": "string"
                  },
                  "venue_name": {
                    "example": "Madison Square Garden",
                    "type": "string"
                  }
                },
                "type": "object"
              },
              "type": "array"
            }
          },
          "400": {
            "description": "Invalid date format",
            "schema": {
              "properties": {
                "message": {
                  "example": "Invalid date format. Use YYYY-MM-DD.",
                  "type": "string"
                }
              },
              "type": "object"
            }
          }
        },
        "security": [
          {
            "Bearer": []
          }
        ],
        "summary": "Get upcoming games based on user's favorite teams",
        "tags": [
          "Games"
        ]
      }
    },
    "/health": {
      "get": {
        "description": "Minimal health check for external monitoring (Uptime Kuma, etc.). No authentication required.",
        "responses": {
          "200": {
            "description": "Service is healthy",
            "schema": {
              "properties": {
                "status": {
                  "enum": [
                    "ok"
                  ],
                  "example": "ok",
                  "type": "string"
                },
                "timestamp": {
                  "example": "2026-02-06T12:00:00Z",
                  "format": "date-time",
                  "type": "string"
                }
              },
              "type": "object"
            }
          },
          "503": {
            "description": "Service is unhealthy",
            "schema": {
              "properties": {
                "status": {
                  "enum": [
                    "unhealthy"
                  ],
                  "type": "string"
                },
                "timestamp": {
                  "format": "date-time",
                  "type": "string"
                }
              },
              "type": "object"
            }
          }
        },
        "summary": "Public health check endpoint",
        "tags": [
          "System"
        ]
      }
    },
    "/internal/health": {
      "get": {
        "description": "Authenticated health check with detailed diagnostics including database status and uptime",
        "responses": {
          "200": {
            "description": "Service is healthy",
            "schema": {
              "properties": {
                "checks": {
                  "properties": {
                    "database": {
                      "properties": {
                        "error": {
                          "description": "Error message if database is unreachable",
                          "type": "string"
                        },
                        "latency_ms": {
                          "example": 5.23,
                          "type": "number"
                        },
                        "ok": {
                          "example": true,
                          "type": "boolean"
                        },
                        "tables_accessible": {
                          "example": true,
                          "type": "boolean"
                        },
                        "team_count": {
                          "example": 124,
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                },
                "environment": {
                  "example": "production",
                  "type": "string"
                },
                "status": {
                  "enum": [
                    "healthy",
                    "degraded"
                  ],
                  "example": "healthy",
                  "type": "string"
                },
                "timestamp": {
                  "example": "2026-02-06T12:00:00Z",
                  "format": "date-time",
                  "type": "string"
                },
                "uptime_seconds": {
                  "description": "Seconds since API startup",
                  "example": 3600,
                  "type": "integer"
                },
                "user": {
                  "description": "Email of authenticated user",
                  "example": "user@example.com",
                  "type": "string"
                }
              },
              "type": "object"
            }
          },
          "503": {
            "description": "Service is degraded",
            "schema": {
              "type": "object"
            }
          }
        },
        "security": [
          {
            "Bearer": []
          }
        ],
        "summary": "Detailed internal health check",
        "tags": [
          "System"
        ]
      }
    },
    "/player/{league}/{jersey_number}": {
      "get": {
        "parameters": [
          {
            "description": "League abbreviation",
            "enum": [
              "nba",
              "nhl",
              "mlb",
              "nfl"
            ],
            "in": "path",
            "name": "league",
            "required": true,
            "type": "string"
          },
          {
            "description": "Player's jersey number",
            "example": 23,
            "in": "path",
            "name": "jersey_number",
            "required": true,
            "type": "integer"
          },
          {
            "description": "Optional team search name (overrides user preference)",
            "example": "lakers",
            "in": "query",
            "name": "search_name",
            "required": false,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "Player details found",
            "schema": {
              "properties": {
                "age": {
                  "type": "integer"
                },
                "bats": {
                  "description": "Batting hand abbreviation (baseball only; null otherwise)",
                  "type": "string"
                },
                "birth_day": {
                  "type": "integer"
                },
                "birth_month": {
                  "type": "integer"
                },
                "birth_year": {
                  "type": "integer"
                },
                "city": {
                  "type": "string"
                },
                "college": {
                  "description": "College attended (football/baseball only; null otherwise)",
                  "type": "string"
                },
                "country": {
                  "type": "string"
                },
                "debut_year": {
                  "type": "integer"
                },
                "first_name": {
                  "type": "string"
                },
                "hand": {
                  "description": "Shooting/throwing hand",
                  "type": "string"
                },
                "headshot_url": {
                  "type": "string"
                },
                "height_inches": {
                  "type": "integer"
                },
                "id": {
                  "type": "integer"
                },
                "injury_status": {
                  "description": "Current injury status if any; null if not currently injured",
                  "type": "string"
                },
                "jersey_number": {
                  "type": "string"
                },
                "last_name": {
                  "type": "string"
                },
                "position": {
                  "type": "string"
                },
                "roster_id": {
                  "type": "integer"
                },
                "salary": {
                  "description": "Current season salary in dollars (basketball, football and hockey; null otherwise)",
                  "type": "integer"
                },
                "slug": {
                  "type": "string"
                },
                "state": {
                  "type": "string"
                },
                "team_alternate_color": {
                  "description": "Team's secondary brand color as a hex string, no leading '#'",
                  "type": "string"
                },
                "team_code": {
                  "type": "string"
                },
                "team_color": {
                  "description": "Team's primary brand color as a hex string, no leading '#' (e.g. \"4f2683\")",
                  "type": "string"
                },
                "team_location": {
                  "type": "string"
                },
                "team_name": {
                  "type": "string"
                },
                "throws": {
                  "description": "Throwing hand abbreviation (baseball only; null otherwise)",
                  "type": "string"
                },
                "weight_pounds": {
                  "type": "integer"
                },
                "years_experience": {
                  "type": "integer"
                }
              },
              "type": "object"
            }
          },
          "404": {
            "description": "Player not found or preference not set",
            "schema": {
              "type": "string"
            }
          }
        },
        "security": [
          {
            "Bearer": []
          }
        ],
        "summary": "Get player details by league and jersey number",
        "tags": [
          "Players"
        ]
      }
    },
    "/player/{league}/{team_code}/{jersey}": {
      "get": {
        "parameters": [
          {
            "description": "League abbreviation",
            "enum": [
              "nba",
              "nhl",
              "mlb",
              "nfl"
            ],
            "in": "path",
            "name": "league",
            "required": true,
            "type": "string"
          },
          {
            "description": "Team code (e.g. pit, min)",
            "in": "path",
            "name": "team_code",
            "required": true,
            "type": "string"
          },
          {
            "description": "Player's jersey number",
            "in": "path",
            "name": "jersey",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "Player details found"
          },
          "404": {
            "description": "Team or player not found"
          }
        },
        "security": [
          {
            "Bearer": []
          }
        ],
        "summary": "Get player details by league, team code, and jersey number",
        "tags": [
          "Players"
        ]
      }
    },
    "/search_players": {
      "get": {
        "parameters": [
          {
            "description": "Player last name (exact match first, then partial)",
            "example": "hughes",
            "in": "query",
            "name": "name",
            "required": true,
            "type": "string"
          },
          {
            "description": "League abbreviation (omit to search all leagues)",
            "enum": [
              "nba",
              "nhl",
              "mlb",
              "nfl"
            ],
            "example": "nhl",
            "in": "query",
            "name": "league",
            "required": false,
            "type": "string"
          },
          {
            "description": "Optional first name filter",
            "example": "jack",
            "in": "query",
            "name": "first_name",
            "required": false,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "List of matching players",
            "schema": {
              "properties": {
                "match_type": {
                  "description": "exact or partial",
                  "type": "string"
                },
                "results": {
                  "items": {
                    "properties": {
                      "first_name": {
                        "type": "string"
                      },
                      "jersey_number": {
                        "type": "string"
                      },
                      "last_name": {
                        "type": "string"
                      },
                      "league": {
                        "type": "string"
                      },
                      "position": {
                        "type": "string"
                      },
                      "team_code": {
                        "type": "string"
                      },
                      "team_location": {
                        "type": "string"
                      },
                      "team_name": {
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "type": "array"
                }
              },
              "type": "object"
            }
          },
          "400": {
            "description": "Missing required parameter"
          }
        },
        "security": [
          {
            "Bearer": []
          }
        ],
        "summary": "Search for players by last name across one or all leagues",
        "tags": [
          "Players"
        ]
      }
    },
    "/set_preferences": {
      "put": {
        "parameters": [
          {
            "in": "body",
            "name": "body",
            "required": true,
            "schema": {
              "properties": {
                "mlb_favorite": {
                  "description": "MLB team search name",
                  "example": "yankees",
                  "type": "string"
                },
                "nba_favorite": {
                  "description": "NBA team search name",
                  "example": "lakers",
                  "type": "string"
                },
                "nfl_favorite": {
                  "description": "NFL team search name",
                  "example": "giants",
                  "type": "string"
                },
                "nhl_favorite": {
                  "description": "NHL team search name",
                  "example": "rangers",
                  "type": "string"
                }
              },
              "type": "object"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Preferences updated successfully",
            "schema": {
              "properties": {
                "mlb_favorite": {
                  "example": "New York Yankees",
                  "type": "string"
                },
                "nba_favorite": {
                  "example": "Los Angeles Lakers",
                  "type": "string"
                },
                "nfl_favorite": {
                  "example": "New York Giants",
                  "type": "string"
                },
                "nhl_favorite": {
                  "example": "New York Rangers",
                  "type": "string"
                }
              },
              "type": "object"
            }
          },
          "404": {
            "description": "Team not found",
            "schema": {
              "type": "string"
            }
          }
        },
        "security": [
          {
            "Bearer": []
          }
        ],
        "summary": "Set user's favorite teams preferences",
        "tags": [
          "Preferences"
        ]
      }
    },
    "/team_codes/{league}": {
      "get": {
        "parameters": [
          {
            "description": "League abbreviation",
            "enum": [
              "nba",
              "nhl",
              "mlb",
              "nfl"
            ],
            "in": "path",
            "name": "league",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "List of teams",
            "schema": {
              "items": {
                "properties": {
                  "team_code": {
                    "type": "string"
                  },
                  "team_location": {
                    "type": "string"
                  },
                  "team_name": {
                    "type": "string"
                  }
                },
                "type": "object"
              },
              "type": "array"
            }
          }
        },
        "security": [
          {
            "Bearer": []
          }
        ],
        "summary": "Get all team codes for a league",
        "tags": [
          "Teams"
        ]
      }
    },
    "/team_game/{league}/{team_code}": {
      "get": {
        "description": "Returns the team's game for the current schedule day (which rolls over at\n5 AM Central, so a night game is still returned after midnight) or its next\nscheduled game, and the start of the user's favorite team's next game in the\nsame league (null if none). Times are ISO 8601 with a Central offset.\n",
        "parameters": [
          {
            "description": "League abbreviation",
            "enum": [
              "nba",
              "nhl",
              "mlb",
              "nfl"
            ],
            "in": "path",
            "name": "league",
            "required": true,
            "type": "string"
          },
          {
            "description": "Team code (e.g. phi, min)",
            "in": "path",
            "name": "team_code",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "The team's current or next game",
            "schema": {
              "properties": {
                "away": {
                  "type": "object"
                },
                "favorite_next_start": {
                  "example": "2026-11-09T12:00:00-06:00",
                  "type": "string",
                  "x-nullable": true
                },
                "game_start": {
                  "example": "2026-11-08T19:20:00-06:00",
                  "type": "string"
                },
                "home": {
                  "properties": {
                    "team_code": {
                      "type": "string"
                    },
                    "team_location": {
                      "type": "string"
                    },
                    "team_name": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                },
                "league": {
                  "example": "nfl",
                  "type": "string"
                }
              },
              "type": "object"
            }
          },
          "404": {
            "description": "Team not found, or the team has no current or upcoming game"
          }
        },
        "security": [
          {
            "Bearer": []
          }
        ],
        "summary": "Get a team's in-progress or next game, plus the favorite team's next kickoff",
        "tags": [
          "Games"
        ]
      }
    }
  },
  "schemes": [
    "https"
  ],
  "security": [
    {
      "Bearer": []
    }
  ],
  "securityDefinitions": {
    "Bearer": {
      "description": "JWT Bearer token issued by Authentik. Format: Bearer <token>\nSetup guide: https://www.stompingbear.com/auth-token-setup/",
      "in": "header",
      "name": "Authorization",
      "type": "apiKey"
    }
  },
  "swagger": "2.0"
}
