{
  "openapi": "3.1.0",
  "info": {
    "title": "TheDraftDay public API",
    "version": "1.0.0",
    "description": "Read-only NBA fantasy data: injuries, projected lineups, player projections and data freshness. No authentication. Data derived from public ESPN endpoints (unofficial).",
    "contact": { "url": "https://thedraftday.com" }
  },
  "servers": [{ "url": "https://thedraftday.com" }],
  "paths": {
    "/api/injuries": {
      "get": {
        "operationId": "listInjuries",
        "summary": "Latest NBA injury and status updates, newest first",
        "parameters": [
          { "name": "status", "in": "query", "description": "Comma-separated statuses", "schema": { "type": "string", "example": "OUT,DOUBTFUL" } },
          { "name": "team", "in": "query", "description": "Team abbreviation as used by ESPN (e.g. LAL, BOS, GS, NY, SA, UTAH, WSH)", "schema": { "type": "string" } },
          { "name": "player", "in": "query", "description": "Player name substring", "schema": { "type": "string" } },
          { "name": "kind", "in": "query", "schema": { "type": "string", "enum": ["status_change", "news"] } },
          { "name": "returning", "in": "query", "description": "Only status upgrades (players returning)", "schema": { "type": "boolean" } },
          { "name": "since", "in": "query", "description": "Only updates reported at or after this ISO time", "schema": { "type": "string", "format": "date-time" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 200, "default": 50 } }
        ],
        "responses": {
          "200": {
            "description": "Updates",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": { "type": "integer" },
                    "items": { "type": "array", "items": { "$ref": "#/components/schemas/InjuryUpdate" } }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" }
        }
      }
    },
    "/api/teams": {
      "get": {
        "operationId": "listTeamBoards",
        "summary": "Projected starting five, next three subs and players out, per team",
        "parameters": [{ "name": "team", "in": "query", "description": "Team abbreviation; omit for all 30 teams", "schema": { "type": "string" } }],
        "responses": {
          "200": {
            "description": "Team boards",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": { "type": "integer" },
                    "teams": { "type": "array", "items": { "$ref": "#/components/schemas/TeamBoard" } }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/players": {
      "get": {
        "operationId": "searchPlayers",
        "summary": "Player projections, status, hot flag and value rank",
        "parameters": [
          { "name": "search", "in": "query", "description": "Name substring", "schema": { "type": "string" } },
          { "name": "team", "in": "query", "schema": { "type": "string" } },
          { "name": "status", "in": "query", "description": "Comma-separated statuses", "schema": { "type": "string" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 200, "default": 25 } }
        ],
        "responses": {
          "200": {
            "description": "Players, best 9-category value first",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": { "type": "integer" },
                    "players": { "type": "array", "items": { "$ref": "#/components/schemas/Player" } }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" }
        }
      }
    },
    "/api/status": {
      "get": {
        "operationId": "dataStatus",
        "summary": "Last successful update per data feed",
        "responses": { "200": { "description": "Feed freshness", "content": { "application/json": { "schema": { "type": "object" } } } } }
      }
    }
  },
  "components": {
    "schemas": {
      "Status": { "type": "string", "enum": ["ACTIVE", "PROBABLE", "DAY_TO_DAY", "QUESTIONABLE", "DOUBTFUL", "OUT", "OUT_SEASON", "SUSPENDED"] },
      "InjuryUpdate": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "reported_at": { "type": "string", "format": "date-time" },
          "player": { "type": "string" },
          "player_id": { "type": "integer" },
          "team": { "type": ["string", "null"] },
          "kind": { "type": "string", "enum": ["status_change", "news"] },
          "status": { "$ref": "#/components/schemas/Status" },
          "previous_status": { "oneOf": [{ "$ref": "#/components/schemas/Status" }, { "type": "null" }] },
          "returning": { "type": "boolean" },
          "injury": { "type": ["string", "null"], "example": "left ankle sprain" },
          "summary": { "type": "string" },
          "fantasy_impact": { "type": ["string", "null"], "enum": ["Starter", "Minutes risk", "Waiver watch", null] },
          "source": { "type": "string" },
          "source_url": { "type": ["string", "null"] }
        }
      },
      "LineupSlot": {
        "type": ["object", "null"],
        "properties": {
          "player": { "type": "string" },
          "player_id": { "type": "integer" },
          "positions": { "type": "array", "items": { "type": "string" } },
          "status": { "$ref": "#/components/schemas/Status" },
          "hot": { "type": "boolean" },
          "hot_reason": { "type": ["string", "null"] },
          "replaces": { "type": ["string", "null"], "description": "Injured starter this player is replacing" }
        }
      },
      "TeamBoard": {
        "type": "object",
        "properties": {
          "team": { "type": "string" },
          "name": { "type": "string" },
          "record": { "type": ["string", "null"] },
          "conference": { "type": ["string", "null"] },
          "division": { "type": ["string", "null"] },
          "lineup_basis": { "type": "string" },
          "confirmed": { "type": "boolean" },
          "starters": { "type": "array", "items": { "$ref": "#/components/schemas/LineupSlot" }, "minItems": 5, "maxItems": 5 },
          "subs": { "type": "array", "items": { "$ref": "#/components/schemas/LineupSlot" }, "minItems": 3, "maxItems": 3 },
          "out": { "type": "array", "items": { "type": "object" } }
        }
      },
      "Player": {
        "type": "object",
        "properties": {
          "player_id": { "type": "integer" },
          "name": { "type": "string" },
          "team": { "type": ["string", "null"] },
          "positions": { "type": "array", "items": { "type": "string" } },
          "status": { "$ref": "#/components/schemas/Status" },
          "injury": { "type": ["string", "null"] },
          "status_detail": { "type": ["string", "null"] },
          "hot": { "type": "boolean" },
          "hot_reason": { "type": ["string", "null"] },
          "projection": {
            "type": ["object", "null"],
            "properties": {
              "season": { "type": "string" },
              "games": { "type": "number" },
              "per_game": { "type": "object" },
              "value_rank_9cat": { "type": ["integer", "null"] },
              "auction_value_default": { "type": ["integer", "null"], "description": "8 teams, $200, 13-man rosters, 9-cat" }
            }
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid parameter",
        "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" } } } } }
      }
    }
  }
}
