{
  "openapi": "3.0.3",
  "info": {
    "title": "PlayCaller Data API",
    "version": "1.4.0",
    "description": "The PlayCaller Data API delivers real-time and historical sports intelligence for fantasy, DFS, and AI developers.\n\n49 REST endpoints across NFL, MLB, NBA, NHL, College Football, Soccer, Tennis, and Golf — plus TypeScript SDK, Python SDK, and an MCP server for AI workflow integration.\n\n## Key capabilities\n- **8 sports** with live data pipelines: NFL, MLB, NBA, NHL, CFB, Soccer (EPL/MLS/La Liga/Bundesliga/Serie A/UCL), Tennis (ATP/WTA), Golf (PGA/LPGA)\n- **13,606 canonical player identities** normalized across ESPN, Sleeper, Yahoo, NFL.com, and BallDontLie\n- **AUC-validated ML models**: NFL confidence (AUC 0.697), NFL heat (AUC 0.623), MLB pitcher form (AUC 0.671), NBA confidence (AUC 0.855)\n- **Alpha metrics**: consistency score, momentum delta, opportunity ceiling per player\n- **Semantic similarity**: pgvector cosine search — find players with matching production profiles\n- **Real-time delivery**: SSE stream (Pro Insights+), HMAC-signed webhooks (Syndicate Alpha)\n- **AI-first**: MCP server at `/mcp`, ChatGPT plugin manifest at `/.well-known/ai-plugin.json`\n- **SDKs**: `npm install @playcaller/sdk` (TypeScript), `pip install playcaller-sdk` (Python)\n\n## Authentication\nAll data endpoints require an `X-PlayCaller-Key` header. Keys are issued at [playcallerapp.com/developer](https://playcallerapp.com/developer). Sandbox keys work immediately — no credit card required.\n\nKey format by tier: `pc_sbx_...` (Sandbox), `pc_bld_...` (Build), `pc_pri_...` (Pro Insights), `pc_syn_...` (Syndicate Alpha). Legacy keys issued before the V2 tier restructure may still carry `pc_hob_...` (Hobbyist) or `pc_pro_...` (Pro) prefixes.\n\n## Base URLs\n- Data endpoints (v1 prefix): `https://playcallerapp.com/v1`\n- Intelligence endpoints (no prefix): `https://playcallerapp.com/intelligence`\n- Analytics endpoint (no prefix): `https://playcallerapp.com/analytics`\n- MCP server: `https://playcallerapp.com/mcp`\n- Account endpoints: `https://playcallerapp.com/daas`\n\n## Tiers\n\n| Plan | Price | Daily calls | Req/min | Endpoints |\n|------|-------|------------|---------|-----------|\n| (tier data unavailable — set DATABASE_URL and regenerate) | | | | |\n\n## Rate Limiting\n- `X-RateLimit-Limit`: Requests allowed per minute\n- `X-RateLimit-Remaining`: Remaining this window\n- `X-RateLimit-Reset`: Unix timestamp when window resets\n- `429` responses include a `Retry-After` header in seconds",
    "contact": {
      "name": "PlayCaller Support",
      "url": "https://playcallerapp.com/developer/docs"
    },
    "termsOfService": "https://playcallerapp.com/developer/terms"
  },
  "servers": [
    {
      "url": "https://playcallerapp.com",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Intelligence",
      "description": "Beat reporter signals, injury feeds, and historical analytics. These routes have no /v1 prefix."
    },
    {
      "name": "NFL",
      "description": "NFL players, games, standings, and team rosters (2024 season backfilled, 2026 schedule live)"
    },
    {
      "name": "MLB",
      "description": "MLB player data, game states, standings, and fantasy scoring"
    },
    {
      "name": "NBA",
      "description": "NBA game scores, standings, teams, player profiles, and game logs"
    },
    {
      "name": "CFB",
      "description": "College football scoreboard, standings, and rankings (Pro only)"
    },
    {
      "name": "Soccer",
      "description": "Soccer match scores and league tables (EPL + MLS)"
    },
    {
      "name": "Multi",
      "description": "Multi-sport discovery, cross-sport player search, and public stats endpoints"
    },
    {
      "name": "Account",
      "description": "API key management, quota monitoring, and trial activation"
    },
    {
      "name": "MCP",
      "description": "Model Context Protocol server — AI workflow integration for Cursor, Claude Desktop, and enterprise AI agents"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-PlayCaller-Key",
        "description": "Your PlayCaller API key. Obtain one free at playcallerapp.com/developer."
      }
    },
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "required": [
          "error_code",
          "message",
          "documentation_url"
        ],
        "properties": {
          "error_code": {
            "type": "string",
            "example": "RATE_LIMIT_EXCEEDED"
          },
          "message": {
            "type": "string",
            "example": "Rate limit exceeded. Try again in 42 seconds."
          },
          "documentation_url": {
            "type": "string",
            "format": "uri",
            "example": "https://playcallerapp.com/developer/docs"
          },
          "upgrade_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "example": "https://playcallerapp.com/developer/checkout?tier=pro"
          }
        }
      },
      "ResponseMeta": {
        "type": "object",
        "properties": {
          "sport": {
            "type": "string",
            "example": "nfl"
          },
          "league": {
            "type": "string",
            "example": "nfl",
            "description": "Present on multi-sport (ESPN-backed) endpoints; mirrors sport unless a sport has sub-leagues (e.g. soccer: epl/mls)."
          },
          "tier": {
            "type": "string",
            "example": "pro"
          },
          "calls_remaining_this_month": {
            "type": "integer",
            "example": 9843
          },
          "documentation_url": {
            "type": "string",
            "format": "uri",
            "example": "https://playcallerapp.com/developer/docs"
          }
        }
      },
      "BeatReporterSignal": {
        "type": "object",
        "required": [
          "id",
          "player_name",
          "team",
          "signal_type",
          "severity",
          "title",
          "summary",
          "source"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "example": 38
          },
          "player_name": {
            "type": "string",
            "example": "Zavion Thomas"
          },
          "team": {
            "type": "string",
            "example": "SF",
            "description": "Often an empty string — team is not always resolved at scrape time"
          },
          "signal_type": {
            "type": "string",
            "enum": [
              "injury_update",
              "depth_chart_change",
              "return_from_injury",
              "role_reduction",
              "role_expansion",
              "practice_report"
            ],
            "example": "injury_update"
          },
          "severity": {
            "type": "string",
            "enum": [
              "high",
              "medium",
              "low"
            ],
            "example": "high"
          },
          "title": {
            "type": "string",
            "example": "McCaffrey questionable with hamstring — listed DNP"
          },
          "summary": {
            "type": "string",
            "example": "Christian McCaffrey did not practice Wednesday with a hamstring injury. He is listed DNP and is considered questionable for Sunday."
          },
          "source": {
            "type": "string",
            "example": "ESPN NFL Injury Report"
          },
          "source_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "example": "https://www.espn.com/nfl/injuries"
          },
          "published_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "/intelligence/news only — see reported_at for /intelligence/injuries",
            "example": "2026-06-24T19:12:10.637Z"
          },
          "reported_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "/intelligence/injuries only — see published_at for /intelligence/news",
            "example": "2026-06-24T19:12:10.637Z"
          }
        }
      },
      "PlayerIdentity": {
        "type": "object",
        "required": [
          "playcaller_id",
          "full_name",
          "position",
          "team",
          "sport_key"
        ],
        "properties": {
          "playcaller_id": {
            "type": "string",
            "description": "Canonical PlayCaller player ID — stable across all platforms",
            "example": "pc_nfl_001234"
          },
          "full_name": {
            "type": "string",
            "example": "Christian McCaffrey"
          },
          "position": {
            "type": "string",
            "example": "RB"
          },
          "team": {
            "type": "string",
            "example": "SF"
          },
          "sport_key": {
            "type": "string",
            "enum": [
              "nfl",
              "mlb",
              "nba"
            ],
            "example": "nfl"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "injured",
              "inactive"
            ],
            "example": "active"
          },
          "platform_ids": {
            "type": "object",
            "description": "Platform-specific IDs for this player. Keys are platform names; values are IDs used by that platform.",
            "additionalProperties": {
              "type": "string"
            },
            "example": {
              "espn": "3054211",
              "sleeper": "4034",
              "yahoo": "28849",
              "nfl.com": "mccaffrey-christian"
            }
          }
        }
      },
      "HistoricalGameRecord": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "example": 9121
          },
          "season": {
            "type": "integer",
            "example": 2025
          },
          "week": {
            "type": "integer",
            "nullable": true,
            "example": 18,
            "description": "NFL/NBA only — null for MLB (daily games, no week concept)"
          },
          "game_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": null,
            "description": "Real date for MLB (daily_player_stats.stat_date); always null for NFL, which has no per-game date column"
          },
          "sport_key": {
            "type": "string",
            "example": "nfl"
          },
          "player_name": {
            "type": "string",
            "example": "Josh Allen"
          },
          "team": {
            "type": "string",
            "example": "BUF"
          },
          "position": {
            "type": "string",
            "example": "QB"
          },
          "opponent": {
            "type": "string",
            "nullable": true,
            "example": "MIA"
          },
          "fantasy_points": {
            "type": "string",
            "example": "35.30",
            "description": "Numeric value returned as a string"
          },
          "passing_yards": {
            "type": "integer",
            "nullable": true
          },
          "passing_tds": {
            "type": "integer",
            "nullable": true
          },
          "rushing_yards": {
            "type": "integer",
            "nullable": true,
            "example": 131
          },
          "rushing_tds": {
            "type": "integer",
            "nullable": true,
            "example": 2
          },
          "receiving_yards": {
            "type": "integer",
            "nullable": true,
            "example": 22
          },
          "receiving_tds": {
            "type": "integer",
            "nullable": true,
            "example": 1
          },
          "receptions": {
            "type": "integer",
            "nullable": true,
            "example": 2
          },
          "snap_pct": {
            "type": "integer",
            "nullable": true,
            "example": 47
          },
          "target_share": {
            "type": "number",
            "nullable": true
          },
          "air_yards": {
            "type": "number",
            "nullable": true
          },
          "batting_h": {
            "type": "integer",
            "nullable": true,
            "description": "MLB only"
          },
          "batting_r": {
            "type": "integer",
            "nullable": true
          },
          "batting_hr": {
            "type": "integer",
            "nullable": true
          },
          "batting_rbi": {
            "type": "integer",
            "nullable": true
          },
          "batting_sb": {
            "type": "integer",
            "nullable": true
          },
          "batting_bb": {
            "type": "integer",
            "nullable": true
          },
          "batting_ab": {
            "type": "integer",
            "nullable": true
          },
          "pitching_ip": {
            "type": "number",
            "nullable": true
          },
          "pitching_w": {
            "type": "integer",
            "nullable": true
          },
          "pitching_k": {
            "type": "integer",
            "nullable": true
          },
          "pitching_sv": {
            "type": "integer",
            "nullable": true
          },
          "pitching_hld": {
            "type": "integer",
            "nullable": true
          },
          "pitching_er": {
            "type": "integer",
            "nullable": true
          }
        }
      },
      "HistoricalTrend": {
        "type": "object",
        "properties": {
          "player_name": {
            "type": "string",
            "example": "Rhamondre Stevenson"
          },
          "team": {
            "type": "string",
            "example": "NE"
          },
          "position": {
            "type": "string",
            "example": "RB"
          },
          "sport": {
            "type": "string",
            "example": "nfl"
          },
          "games_in_sample": {
            "type": "integer",
            "example": 1
          },
          "avg_fantasy_points": {
            "type": "number",
            "example": 35.3
          },
          "recent_game": {
            "$ref": "#/components/schemas/HistoricalGameRecord"
          },
          "all_games": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HistoricalGameRecord"
            }
          }
        }
      },
      "MLBPlayer": {
        "type": "object",
        "required": [
          "id",
          "full_name",
          "position",
          "team",
          "status"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "PlayCaller MLB player ID",
            "example": "pc_mlb_001234"
          },
          "full_name": {
            "type": "string",
            "example": "Shohei Ohtani"
          },
          "first_name": {
            "type": "string",
            "example": "Shohei"
          },
          "last_name": {
            "type": "string",
            "example": "Ohtani"
          },
          "position": {
            "type": "string",
            "enum": [
              "SP",
              "RP",
              "C",
              "1B",
              "2B",
              "3B",
              "SS",
              "OF",
              "DH"
            ],
            "example": "DH"
          },
          "team": {
            "type": "string",
            "example": "LAD"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "injured",
              "inactive"
            ],
            "example": "active"
          }
        }
      },
      "MLBPlayerStats": {
        "type": "object",
        "properties": {
          "rank": {
            "type": "integer",
            "nullable": true,
            "example": 1,
            "description": "Leaders endpoint only"
          },
          "id": {
            "type": "string",
            "nullable": true,
            "example": "pc_mlb_672640",
            "description": "Leaders endpoint only"
          },
          "player_name": {
            "type": "string",
            "nullable": true,
            "example": "Otto Lopez",
            "description": "Leaders endpoint only"
          },
          "team": {
            "type": "string",
            "example": "Miami Marlins"
          },
          "position": {
            "type": "string",
            "example": "SS"
          },
          "stat_date": {
            "type": "string",
            "format": "date-time",
            "example": "2026-06-24T07:00:00.000Z"
          },
          "game_pk": {
            "type": "string",
            "nullable": true,
            "example": "822800",
            "description": "Player-stats endpoint only"
          },
          "fantasy_points": {
            "type": "string",
            "example": "8.50",
            "description": "Numeric value returned as a string"
          },
          "is_final": {
            "type": "boolean",
            "example": true
          },
          "is_starter": {
            "type": "boolean",
            "nullable": true,
            "description": "Player-stats endpoint only"
          },
          "last_updated": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Player-stats endpoint only"
          },
          "batting": {
            "type": "object",
            "properties": {
              "h": {
                "type": "integer",
                "description": "Hits",
                "example": 2
              },
              "r": {
                "type": "integer",
                "description": "Runs Scored",
                "example": 2
              },
              "hr": {
                "type": "integer",
                "description": "Home Runs",
                "example": 1
              },
              "rbi": {
                "type": "integer",
                "description": "RBI",
                "example": 3
              },
              "sb": {
                "type": "integer",
                "description": "Stolen Bases",
                "example": 1
              },
              "bb": {
                "type": "integer",
                "description": "Walks",
                "example": 1
              },
              "ab": {
                "type": "integer",
                "nullable": true,
                "description": "At Bats — player-stats endpoint only"
              },
              "pa": {
                "type": "integer",
                "nullable": true,
                "description": "Plate Appearances — player-stats endpoint only"
              }
            }
          },
          "pitching": {
            "type": "object",
            "nullable": true,
            "properties": {
              "ip": {
                "type": "string",
                "description": "Innings Pitched, returned as a string (e.g. \"6.2\")",
                "example": "6.2"
              },
              "w": {
                "type": "integer",
                "description": "Wins",
                "example": 0
              },
              "k": {
                "type": "integer",
                "description": "Strikeouts",
                "example": 9
              },
              "sv": {
                "type": "integer",
                "description": "Saves",
                "example": 0
              },
              "hld": {
                "type": "integer",
                "description": "Holds",
                "example": 0
              },
              "er": {
                "type": "integer",
                "description": "Earned Runs",
                "example": 1
              }
            }
          }
        }
      },
      "MLBGame": {
        "type": "object",
        "properties": {
          "game_pk": {
            "type": "string",
            "example": "745302",
            "description": "MLB Stats API game ID — returned as a string, not numeric"
          },
          "game_date": {
            "type": "string",
            "format": "date-time",
            "example": "2026-05-01T00:00:00.000Z"
          },
          "game_time": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "example": "2026-05-01T22:10:00.000Z"
          },
          "state": {
            "type": "string",
            "enum": [
              "pre_game",
              "scheduled",
              "in_progress",
              "final",
              "completed",
              "postponed"
            ],
            "example": "completed",
            "description": "Real values from mlb_game_states — not the previously-documented live/final/preview enum"
          },
          "home_team": {
            "type": "object",
            "properties": {
              "id": {
                "type": "integer",
                "example": 146
              },
              "name": {
                "type": "string",
                "example": "Miami Marlins"
              },
              "score": {
                "type": "integer",
                "nullable": true,
                "example": 4
              }
            }
          },
          "away_team": {
            "type": "object",
            "properties": {
              "id": {
                "type": "integer",
                "example": 140
              },
              "name": {
                "type": "string",
                "example": "Texas Rangers"
              },
              "score": {
                "type": "integer",
                "nullable": true,
                "example": 2
              }
            }
          },
          "inning": {
            "type": "integer",
            "nullable": true,
            "example": 9
          },
          "inning_state": {
            "type": "string",
            "nullable": true,
            "example": "Top"
          },
          "lineup_posted": {
            "type": "boolean"
          },
          "is_final": {
            "type": "boolean",
            "example": true
          },
          "status_code": {
            "type": "string",
            "example": "F"
          },
          "last_polled": {
            "type": "string",
            "format": "date-time",
            "example": "2026-05-01T22:14:05Z"
          }
        }
      },
      "ESPNGame": {
        "type": "object",
        "description": "Game state from ESPN feed (NBA, CFB, Soccer)",
        "properties": {
          "event_id": {
            "type": "string",
            "example": "740975"
          },
          "league": {
            "type": "string",
            "nullable": true,
            "example": "epl",
            "description": "Soccer only (epl/mls) — distinguishes league within the sport"
          },
          "game_date": {
            "type": "string",
            "format": "date-time",
            "example": "2026-05-24T07:00:00.000Z"
          },
          "game_time": {
            "type": "string",
            "format": "date-time",
            "example": "2026-05-24T15:00:00.000Z"
          },
          "state": {
            "type": "string",
            "enum": [
              "scheduled",
              "in_progress",
              "final"
            ],
            "example": "final",
            "description": "Real values from espn_game_states — not the previously-documented pre/in/post"
          },
          "home_team": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "example": "18"
              },
              "name": {
                "type": "string",
                "example": "Los Angeles Lakers"
              },
              "abbr": {
                "type": "string",
                "example": "LAL"
              },
              "logo": {
                "type": "string",
                "format": "uri",
                "example": "https://a.espncdn.com/i/teamlogos/nba/500/lal.png"
              },
              "score": {
                "type": "integer",
                "nullable": true,
                "example": 112
              }
            }
          },
          "away_team": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "example": "2"
              },
              "name": {
                "type": "string",
                "example": "Boston Celtics"
              },
              "abbr": {
                "type": "string",
                "example": "BOS"
              },
              "logo": {
                "type": "string",
                "format": "uri",
                "example": "https://a.espncdn.com/i/teamlogos/nba/500/bos.png"
              },
              "score": {
                "type": "integer",
                "nullable": true,
                "example": 108
              }
            }
          },
          "period": {
            "type": "integer",
            "nullable": true,
            "example": 4
          },
          "period_label": {
            "type": "string",
            "nullable": true,
            "example": "Q4"
          },
          "clock": {
            "type": "string",
            "nullable": true,
            "example": "2:14"
          },
          "venue": {
            "type": "string",
            "nullable": true,
            "example": "Crypto.com Arena"
          },
          "broadcast": {
            "type": "string",
            "nullable": true,
            "example": "TNT"
          },
          "is_final": {
            "type": "boolean",
            "example": true
          },
          "last_polled": {
            "type": "string",
            "format": "date-time",
            "example": "2026-05-01T02:14:05Z"
          }
        }
      },
      "ESPNStanding": {
        "type": "object",
        "properties": {
          "rank": {
            "type": "integer",
            "example": 1
          },
          "league": {
            "type": "string",
            "nullable": true,
            "example": "epl",
            "description": "Soccer only (epl/mls)"
          },
          "ties": {
            "type": "integer",
            "nullable": true,
            "description": "Soccer only — NBA/CFB have no tie record"
          },
          "team_id": {
            "type": "string",
            "example": "2"
          },
          "team_name": {
            "type": "string",
            "example": "Boston Celtics"
          },
          "team_abbr": {
            "type": "string",
            "example": "BOS"
          },
          "team_logo": {
            "type": "string",
            "format": "uri",
            "nullable": true
          },
          "conference": {
            "type": "string",
            "nullable": true,
            "example": "East"
          },
          "division": {
            "type": "string",
            "nullable": true,
            "example": "Atlantic"
          },
          "wins": {
            "type": "integer",
            "example": 64
          },
          "losses": {
            "type": "integer",
            "example": 18
          },
          "win_pct": {
            "type": "number",
            "format": "float",
            "example": 0.78
          },
          "games_back": {
            "type": "string",
            "nullable": true,
            "example": "-"
          },
          "streak": {
            "type": "string",
            "nullable": true,
            "example": "W3"
          },
          "home_record": {
            "type": "string",
            "nullable": true,
            "example": "36-5"
          },
          "away_record": {
            "type": "string",
            "nullable": true,
            "example": "28-13"
          },
          "conf_record": {
            "type": "string",
            "nullable": true,
            "example": "42-14"
          },
          "points_for": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "example": 120.4
          },
          "points_against": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "example": 109.8
          },
          "last_updated": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "CFBRanking": {
        "type": "object",
        "properties": {
          "rank": {
            "type": "integer",
            "example": 1
          },
          "team_id": {
            "type": "string",
            "example": "cfb_alabama"
          },
          "team_name": {
            "type": "string",
            "example": "Alabama"
          },
          "team_abbr": {
            "type": "string",
            "example": "ALA"
          },
          "record": {
            "type": "string",
            "example": "12-0"
          },
          "points": {
            "type": "integer",
            "nullable": true,
            "example": 1550
          },
          "first_place_votes": {
            "type": "integer",
            "nullable": true,
            "example": 42
          },
          "prev_rank": {
            "type": "integer",
            "nullable": true,
            "example": 1
          },
          "week": {
            "type": "integer",
            "example": 15
          }
        }
      },
      "UsageStats": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "key_prefix": {
            "type": "string",
            "example": "pcdk_test_9b..."
          },
          "tier": {
            "type": "string",
            "enum": [
              "sandbox",
              "hobbyist",
              "build",
              "pro",
              "pro_insights",
              "enterprise",
              "syndicate_alpha"
            ],
            "example": "pro"
          },
          "tier_limits": {
            "type": "object",
            "description": "Reference limits for every legacy tier (V2 tiers are not monthly-metered, so they are not listed here — see GET /v1/sports or the pricing table for sandbox/build/pro_insights/syndicate_alpha caps)",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "requests_per_minute": {
                  "type": "integer"
                },
                "daily_calls": {
                  "type": "integer",
                  "nullable": true
                },
                "monthly_calls": {
                  "type": "integer",
                  "nullable": true
                }
              }
            }
          },
          "is_trial": {
            "type": "boolean",
            "example": false
          },
          "trial_starts_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "trial_ends_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "trial_days_remaining": {
            "type": "integer",
            "nullable": true,
            "description": "Days left in trial (null if not in trial)"
          },
          "requests_today": {
            "type": "integer",
            "example": 0
          },
          "daily_limit": {
            "type": "integer",
            "nullable": true,
            "example": 1000
          },
          "daily_remaining": {
            "type": "integer",
            "nullable": true,
            "example": 1000
          },
          "calls_this_period": {
            "type": "integer",
            "example": 0
          },
          "calls_this_month": {
            "type": "integer",
            "example": 157
          },
          "calls_limit_month": {
            "type": "integer",
            "example": 10000
          },
          "calls_remaining": {
            "type": "integer",
            "example": 9843
          },
          "rate_limit_per_min": {
            "type": "integer",
            "example": 60
          },
          "rate_limit_remaining": {
            "type": "integer",
            "example": 59
          },
          "reset_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When monthly quota resets (legacy tiers only — null for V2 tiers, which are not monthly-metered)",
            "example": "2026-06-01T00:00:00Z"
          },
          "upgrade_url": {
            "type": "string",
            "format": "uri",
            "nullable": true
          },
          "endpoint_breakdown": {
            "type": "array",
            "description": "Per-endpoint call counts for the trailing 30 days — an array of rows, not a map (returned empty for RapidAPI-proxied keys, which have no DB usage row)",
            "items": {
              "type": "object",
              "properties": {
                "endpoint": {
                  "type": "string"
                },
                "calls": {
                  "type": "integer"
                },
                "avg_ms": {
                  "type": "integer"
                },
                "last_call": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          }
        }
      },
      "MCPTool": {
        "type": "object",
        "required": [
          "name",
          "description",
          "inputSchema"
        ],
        "properties": {
          "name": {
            "type": "string",
            "example": "get_injury_signals"
          },
          "description": {
            "type": "string",
            "example": "Returns active beat reporter injury signals filtered by sport and severity."
          },
          "inputSchema": {
            "type": "object",
            "description": "JSON Schema for tool arguments",
            "properties": {
              "type": {
                "type": "string",
                "example": "object"
              },
              "properties": {
                "type": "object",
                "additionalProperties": true
              },
              "required": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "PublicStats": {
        "type": "object",
        "properties": {
          "active_users": {
            "type": "integer",
            "description": "Registered users with at least one login this month",
            "example": 4182
          },
          "active_signals": {
            "type": "integer",
            "description": "Beat reporter signals currently active across all sports",
            "example": 625
          },
          "players_tracked": {
            "type": "integer",
            "description": "Total canonical player identities in the database",
            "example": 13606
          },
          "sports_covered": {
            "type": "integer",
            "description": "Number of sports with live data pipelines",
            "example": 5
          },
          "platforms": {
            "type": "integer",
            "description": "External platforms with cross-platform player ID mappings",
            "example": 6
          }
        }
      }
    }
  },
  "paths": {
    "/intelligence/news": {
      "get": {
        "tags": [
          "Intelligence"
        ],
        "summary": "Live multi-sport player signals",
        "description": "Returns real-time player signals scraped every 2 hours from ESPN NFL, MLB, and NBA injury reports and beat reporter feeds. Signals surface before they appear on mainstream aggregators.\n\nIncludes injuries, depth chart changes, role shifts, practice participation, and return-to-practice designations across all three sports. Signal severity is calculated based on fantasy impact: a DNP for a workhorse RB is `high`; a minor hamstring note for a backup is `low`.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getIntelligenceNews",
        "parameters": [
          {
            "name": "severity",
            "in": "query",
            "description": "Filter by fantasy impact severity",
            "schema": {
              "type": "string",
              "enum": [
                "high",
                "medium",
                "low"
              ]
            },
            "example": "high"
          },
          {
            "name": "sport",
            "in": "query",
            "description": "Filter by sport (defaults to all)",
            "schema": {
              "type": "string",
              "enum": [
                "nfl",
                "mlb",
                "nba",
                "all"
              ]
            },
            "example": "nfl"
          },
          {
            "name": "team",
            "in": "query",
            "description": "Filter by 2-3 letter team abbreviation",
            "schema": {
              "type": "string",
              "maxLength": 3
            },
            "example": "SF"
          },
          {
            "name": "position",
            "in": "query",
            "description": "Filter by position (NFL: QB/RB/WR/TE/K; MLB: SP/OF/etc; NBA: PG/SG/etc)",
            "schema": {
              "type": "string"
            },
            "example": "WR"
          },
          {
            "name": "signal_type",
            "in": "query",
            "description": "Filter by signal category",
            "schema": {
              "type": "string",
              "enum": [
                "injury",
                "depth_chart",
                "role_shift",
                "practice_report",
                "return_to_practice"
              ]
            },
            "example": "injury"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max results (default 25, max 100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "example": 25
          }
        ],
        "responses": {
          "200": {
            "description": "Active player signals ordered by severity then recency",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/BeatReporterSignal"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/intelligence/injuries": {
      "get": {
        "tags": [
          "Intelligence"
        ],
        "summary": "Active injury feed (multi-sport)",
        "description": "Filtered view of the signal feed returning only active injury designations across NFL, MLB, and NBA. Equivalent to `GET /intelligence/news?signal_type=injury` with convenience defaults tuned for DFS stack-building and lineup decisions.\n\n625+ active signals are re-scraped every 2 hours. High-severity signals are available before mainstream platforms aggregate them.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getIntelligenceInjuries",
        "parameters": [
          {
            "name": "severity",
            "in": "query",
            "description": "Minimum severity level",
            "schema": {
              "type": "string",
              "enum": [
                "high",
                "medium",
                "low"
              ]
            },
            "example": "high"
          },
          {
            "name": "sport",
            "in": "query",
            "description": "Sport filter (defaults to nfl)",
            "schema": {
              "type": "string",
              "enum": [
                "nfl",
                "mlb",
                "nba",
                "all"
              ]
            },
            "example": "nfl"
          },
          {
            "name": "team",
            "in": "query",
            "description": "2-3 letter team abbreviation",
            "schema": {
              "type": "string",
              "maxLength": 3
            },
            "example": "KC"
          },
          {
            "name": "player",
            "in": "query",
            "description": "Partial player name search (case-insensitive)",
            "schema": {
              "type": "string"
            },
            "example": "Mahomes"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max results (default 50, max 100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Active injury signals ordered by severity then recency",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/BeatReporterSignal"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/analytics/trends": {
      "get": {
        "tags": [
          "Intelligence"
        ],
        "summary": "Historical performance trends (Pro)",
        "description": "Game-by-game performance logs for NFL (2024 full season, 4,624 records) and MLB players. Each row represents one game: full stat line plus calculated fantasy points under PPR, half-PPR, or standard scoring.\n\nUse this endpoint to calculate targets-per-route, air yards share, snap consistency, and multi-week usage trends — the signals that separate week-winning waiver adds from noise.\n\n**Tier access:** Pro Insights, Syndicate Alpha",
        "operationId": "getAnalyticsTrends",
        "parameters": [
          {
            "name": "sport",
            "in": "query",
            "description": "Sport to query (default: nfl)",
            "schema": {
              "type": "string",
              "enum": [
                "nfl",
                "mlb",
                "all"
              ]
            },
            "example": "nfl"
          },
          {
            "name": "player_name",
            "in": "query",
            "description": "Partial player name (case-insensitive)",
            "schema": {
              "type": "string"
            },
            "example": "McCaffrey"
          },
          {
            "name": "team",
            "in": "query",
            "description": "2-3 letter team abbreviation",
            "schema": {
              "type": "string",
              "maxLength": 3
            },
            "example": "SF"
          },
          {
            "name": "position",
            "in": "query",
            "description": "Position (QB/RB/WR/TE for NFL; SP/OF/etc for MLB)",
            "schema": {
              "type": "string"
            },
            "example": "WR"
          },
          {
            "name": "season",
            "in": "query",
            "description": "Season year (NFL: 2024; MLB: 2024)",
            "schema": {
              "type": "integer"
            },
            "example": 2024
          },
          {
            "name": "week",
            "in": "query",
            "description": "NFL week number (1–18)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 18
            },
            "example": 8
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max records (default 50, max 500)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 50
            },
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Players grouped with their recent game and full game log in the requested window",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "sport": {
                      "type": "string",
                      "example": "nfl"
                    },
                    "seasons": {
                      "type": "array",
                      "items": {
                        "type": "integer"
                      },
                      "example": [
                        2025
                      ]
                    },
                    "total_records": {
                      "type": "integer",
                      "description": "Total game rows considered before grouping by player"
                    },
                    "trends": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/HistoricalTrend"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "403": {
            "description": "Pro tier required for this endpoint",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "TIER_INSUFFICIENT",
                  "message": "This endpoint requires a Pro subscription.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/tiers",
                  "upgrade_url": "https://playcallerapp.com/developer/checkout?tier=pro"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/mlb/players": {
      "get": {
        "tags": [
          "MLB"
        ],
        "summary": "List active MLB players",
        "description": "Returns all active MLB players (966 total). Positions, teams, and statuses are normalized from MLB Stats API and reconciled against ESPN for accuracy.\n\nFilter by position and team to build DFS pools or lineup constraints without doing the normalization yourself.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "listMLBPlayers",
        "parameters": [
          {
            "name": "position",
            "in": "query",
            "description": "Filter by position",
            "schema": {
              "type": "string",
              "enum": [
                "SP",
                "RP",
                "C",
                "1B",
                "2B",
                "3B",
                "SS",
                "OF",
                "DH"
              ]
            },
            "example": "SP"
          },
          {
            "name": "team",
            "in": "query",
            "description": "3-letter MLB team abbreviation",
            "schema": {
              "type": "string"
            },
            "example": "NYY"
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by player status",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "injured",
                "inactive"
              ]
            },
            "example": "active"
          },
          {
            "name": "search",
            "in": "query",
            "description": "Partial name search (case-insensitive)",
            "schema": {
              "type": "string"
            },
            "example": "Ohtani"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max results (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "example": 50
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Pagination offset",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "example": 0
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list of MLB players",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/MLBPlayer"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/mlb/players/{id}": {
      "get": {
        "tags": [
          "MLB"
        ],
        "summary": "Get MLB player by ID",
        "description": "Returns the full profile for a single MLB player by PlayCaller ID. Use `/v1/mlb/players?search=` to find IDs by name.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getMLBPlayer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "PlayCaller MLB player ID (format: pc_mlb_XXXXXX)",
            "schema": {
              "type": "string"
            },
            "example": "pc_mlb_001234"
          }
        ],
        "responses": {
          "200": {
            "description": "MLB player profile",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/MLBPlayer"
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "404": {
            "description": "Player not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "PLAYER_NOT_FOUND",
                  "message": "No player found with ID pc_mlb_999999.",
                  "documentation_url": "https://playcallerapp.com/developer/docs#mlb"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/mlb/players/{id}/stats": {
      "get": {
        "tags": [
          "MLB"
        ],
        "summary": "Game-by-game stats for an MLB player",
        "description": "Returns daily batting and pitching stat lines with pre-calculated fantasy points. Useful for tracking recent form, streaks, and park-factor-adjusted production.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getMLBPlayerStats",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "PlayCaller MLB player ID",
            "schema": {
              "type": "string"
            },
            "example": "pc_mlb_001234"
          },
          {
            "name": "date",
            "in": "query",
            "description": "Filter to a specific game date (YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-05-01"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max game logs (default 30, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 30
            },
            "example": 30
          }
        ],
        "responses": {
          "200": {
            "description": "Player game-by-game stat log",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "player": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "full_name": {
                          "type": "string"
                        },
                        "position": {
                          "type": "string"
                        },
                        "team": {
                          "type": "string"
                        }
                      }
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/MLBPlayerStats"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "404": {
            "description": "Player not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/mlb/teams": {
      "get": {
        "tags": [
          "MLB"
        ],
        "summary": "All 30 MLB teams",
        "description": "Returns metadata for all 30 MLB teams including roster depth. Abbreviations are normalized (e.g. NYY, BOS, LAD).\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "listMLBTeams",
        "responses": {
          "200": {
            "description": "30 MLB teams with roster counts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "abbreviation": {
                            "type": "string",
                            "example": "NYY"
                          },
                          "full_name": {
                            "type": "string",
                            "example": "New York Yankees"
                          },
                          "roster_size": {
                            "type": "integer",
                            "example": 26
                          },
                          "active_players": {
                            "type": "integer",
                            "example": 24
                          },
                          "positions": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "example": [
                              "1B",
                              "2B",
                              "OF",
                              "SP"
                            ]
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/mlb/teams/{team}/roster": {
      "get": {
        "tags": [
          "MLB"
        ],
        "summary": "MLB team roster",
        "description": "Returns the active roster for a specific team. Filter by position to pull only starting pitchers or corner infielders for lineup construction.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getMLBTeamRoster",
        "parameters": [
          {
            "name": "team",
            "in": "path",
            "required": true,
            "description": "3-letter MLB team abbreviation (e.g. NYY, LAD)",
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 3
            },
            "example": "NYY"
          },
          {
            "name": "position",
            "in": "query",
            "description": "Filter by position",
            "schema": {
              "type": "string",
              "enum": [
                "SP",
                "RP",
                "C",
                "1B",
                "2B",
                "3B",
                "SS",
                "OF",
                "DH"
              ]
            },
            "example": "SP"
          }
        ],
        "responses": {
          "200": {
            "description": "Team roster",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "team": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/MLBPlayer"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "404": {
            "description": "Team abbreviation not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/mlb/games": {
      "get": {
        "tags": [
          "MLB"
        ],
        "summary": "Live and scheduled MLB games",
        "description": "Live inning-by-inning game state from the MLB Stats API pipeline. Defaults to today's games. Scores update on a polling cycle throughout the game day.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "listMLBGames",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "description": "Game date (YYYY-MM-DD, defaults to today)",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-05-01"
          },
          {
            "name": "state",
            "in": "query",
            "description": "Filter by game state (matches the live state column exactly)",
            "schema": {
              "type": "string",
              "enum": [
                "pre_game",
                "scheduled",
                "in_progress",
                "final",
                "completed",
                "postponed"
              ]
            },
            "example": "in_progress"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max games (default 30, max 100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 30
            },
            "example": 30
          }
        ],
        "responses": {
          "200": {
            "description": "MLB game states",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/MLBGame"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/mlb/standings": {
      "get": {
        "tags": [
          "MLB"
        ],
        "summary": "MLB division standings",
        "description": "Current MLB standings by division sourced from ESPN. Includes win %, streak, home/away splits, and runs differential.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getMLBStandings",
        "parameters": [
          {
            "name": "season",
            "in": "query",
            "description": "Season year (defaults to current)",
            "schema": {
              "type": "integer"
            },
            "example": 2026
          },
          {
            "name": "division",
            "in": "query",
            "description": "Filter by division name (partial match: \"AL East\", \"NL West\")",
            "schema": {
              "type": "string"
            },
            "example": "AL East"
          }
        ],
        "responses": {
          "200": {
            "description": "MLB standings by division",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "season": {
                      "type": "integer"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ESPNStanding"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/mlb/scoring/leaders": {
      "get": {
        "tags": [
          "MLB"
        ],
        "summary": "MLB fantasy scoring leaders (Pro)",
        "description": "Top fantasy scorers for any game day, ranked by total points. Uses the PlayCaller scoring engine with standard roto weights (H, HR, RBI, SB, R, BB for batters; IP, K, SV for pitchers).\n\nUseful for identifying daily stack targets and late-swap pivots before lock.\n\n**Tier access:** Pro Insights, Syndicate Alpha",
        "operationId": "getMLBScoringLeaders",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "description": "Game date (YYYY-MM-DD, defaults to most recent game day)",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-05-01"
          },
          {
            "name": "position",
            "in": "query",
            "description": "Filter by position",
            "schema": {
              "type": "string",
              "enum": [
                "SP",
                "RP",
                "C",
                "1B",
                "2B",
                "3B",
                "SS",
                "OF",
                "DH"
              ]
            },
            "example": "OF"
          },
          {
            "name": "team",
            "in": "query",
            "description": "3-letter team abbreviation",
            "schema": {
              "type": "string"
            },
            "example": "NYY"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max leaders (default 25, max 100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "example": 25
          }
        ],
        "responses": {
          "200": {
            "description": "Fantasy scoring leaderboard for date",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/MLBPlayerStats"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "403": {
            "description": "Pro tier required for this endpoint",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "TIER_INSUFFICIENT",
                  "message": "This endpoint requires a Pro subscription.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/tiers",
                  "upgrade_url": "https://playcallerapp.com/developer/checkout?tier=pro"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/mlb/scoring/categories": {
      "get": {
        "tags": [
          "MLB"
        ],
        "summary": "MLB rotisserie category leaders (Pro)",
        "description": "Top 10 players per rotisserie scoring category (HR, RBI, SB, R, BB, IP, K, SV) for a given date. Ideal for roto league managers tracking category races and daily contributions.\n\n**Tier access:** Pro Insights, Syndicate Alpha",
        "operationId": "getMLBScoringCategories",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "description": "Game date (YYYY-MM-DD, defaults to most recent game day)",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-05-01"
          }
        ],
        "responses": {
          "200": {
            "description": "Top 10 per rotisserie category",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "categories": {
                      "type": "object",
                      "description": "Keys: home_runs, rbi, stolen_bases, runs, walks, innings_pitched, strikeouts, saves",
                      "additionalProperties": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "rank": {
                              "type": "integer",
                              "example": 1
                            },
                            "id": {
                              "type": "string",
                              "example": "pc_mlb_672640"
                            },
                            "player_name": {
                              "type": "string"
                            },
                            "team": {
                              "type": "string"
                            },
                            "position": {
                              "type": "string"
                            },
                            "value": {
                              "type": "number",
                              "example": 1
                            },
                            "stat_date": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "403": {
            "description": "Pro tier required for this endpoint",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "TIER_INSUFFICIENT",
                  "message": "This endpoint requires a Pro subscription.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/tiers",
                  "upgrade_url": "https://playcallerapp.com/developer/checkout?tier=pro"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/nba/games": {
      "get": {
        "tags": [
          "NBA"
        ],
        "summary": "NBA game scores and schedule",
        "description": "Live scores and scheduled NBA games from the ESPN feed. Includes venue, broadcast network, period clock, and team logos for display-ready integrations.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "listNBAGames",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "description": "Game date (YYYY-MM-DD, defaults to today)",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-05-01"
          },
          {
            "name": "state",
            "in": "query",
            "description": "Game state filter (matches the live state column exactly)",
            "schema": {
              "type": "string",
              "enum": [
                "scheduled",
                "in_progress",
                "final"
              ]
            },
            "example": "in_progress"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max games (default 30, max 100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 30
            },
            "example": 30
          }
        ],
        "responses": {
          "200": {
            "description": "NBA game states",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ESPNGame"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/nba/standings": {
      "get": {
        "tags": [
          "NBA"
        ],
        "summary": "NBA conference standings",
        "description": "Current NBA standings including conference, division, win %, streak, and home/away split records. Filterable by conference.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getNBAStandings",
        "parameters": [
          {
            "name": "season",
            "in": "query",
            "description": "Season year (defaults to current)",
            "schema": {
              "type": "integer"
            },
            "example": 2026
          },
          {
            "name": "conference",
            "in": "query",
            "description": "Filter by conference",
            "schema": {
              "type": "string",
              "enum": [
                "East",
                "West"
              ]
            },
            "example": "East"
          }
        ],
        "responses": {
          "200": {
            "description": "NBA standings by conference",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "season": {
                      "type": "integer"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ESPNStanding"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/nba/teams": {
      "get": {
        "tags": [
          "NBA"
        ],
        "summary": "All 30 NBA teams",
        "description": "All 30 NBA teams with conference, division, and ESPN team logo URL. Filterable by conference.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "listNBATeams",
        "parameters": [
          {
            "name": "conference",
            "in": "query",
            "description": "Filter by conference",
            "schema": {
              "type": "string",
              "enum": [
                "East",
                "West"
              ]
            },
            "example": "West"
          }
        ],
        "responses": {
          "200": {
            "description": "NBA teams",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "nullable": true,
                            "example": "2"
                          },
                          "abbreviation": {
                            "type": "string",
                            "example": "BOS"
                          },
                          "full_name": {
                            "type": "string",
                            "example": "Boston Celtics"
                          },
                          "conference": {
                            "type": "string",
                            "nullable": true,
                            "example": "East"
                          },
                          "division": {
                            "type": "string",
                            "nullable": true,
                            "example": "Atlantic"
                          },
                          "logo": {
                            "type": "string",
                            "format": "uri",
                            "nullable": true
                          },
                          "record": {
                            "type": "object",
                            "properties": {
                              "wins": {
                                "type": "integer",
                                "nullable": true
                              },
                              "losses": {
                                "type": "integer",
                                "nullable": true
                              },
                              "win_pct": {
                                "type": "number",
                                "nullable": true
                              }
                            }
                          },
                          "last_updated": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/nba/players": {
      "get": {
        "tags": [
          "NBA"
        ],
        "summary": "NBA players (3,252 seeded)",
        "description": "3,252 NBA players from player_identities (same identity-resolution pipeline as MLB). Searchable by name, position, or team. No jersey number or headshot URL is currently returned (despite earlier docs claiming otherwise — corrected 2026-06-24 against a live response).\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "listNBAPlayers",
        "parameters": [
          {
            "name": "search",
            "in": "query",
            "description": "Partial player name (case-insensitive)",
            "schema": {
              "type": "string"
            },
            "example": "LeBron"
          },
          {
            "name": "position",
            "in": "query",
            "description": "Filter by position",
            "schema": {
              "type": "string",
              "enum": [
                "PG",
                "SG",
                "SF",
                "PF",
                "C"
              ]
            },
            "example": "PG"
          },
          {
            "name": "team",
            "in": "query",
            "description": "3-letter team abbreviation",
            "schema": {
              "type": "string"
            },
            "example": "LAL"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max results (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "example": 50
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Pagination offset",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "example": 0
          }
        ],
        "responses": {
          "200": {
            "description": "NBA players",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "example": "pc_nba_1262"
                          },
                          "full_name": {
                            "type": "string"
                          },
                          "first_name": {
                            "type": "string"
                          },
                          "last_name": {
                            "type": "string"
                          },
                          "position": {
                            "type": "string",
                            "nullable": true
                          },
                          "team": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/nba/players/{id}": {
      "get": {
        "tags": [
          "NBA"
        ],
        "summary": "NBA player profile by ID",
        "description": "Full profile for a single NBA player by PlayCaller ID. Returns platform IDs, team, position, and status.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getNBAPlayer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "PlayCaller NBA player ID (format: pc_nba_XXXXXX)",
            "schema": {
              "type": "string"
            },
            "example": "pc_nba_1262"
          }
        ],
        "responses": {
          "200": {
            "description": "NBA player profile",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "full_name": {
                          "type": "string"
                        },
                        "first_name": {
                          "type": "string"
                        },
                        "last_name": {
                          "type": "string"
                        },
                        "position": {
                          "type": "string",
                          "nullable": true
                        },
                        "team": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        },
                        "metadata": {
                          "type": "object",
                          "nullable": true
                        },
                        "last_updated": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "404": {
            "description": "Player not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/nba/players/{id}/stats": {
      "get": {
        "tags": [
          "NBA"
        ],
        "summary": "Game-by-game stats for an NBA player",
        "description": "Game logs from `historical_performance` for an NBA player (127,909 rows across 5 seasons, 2021–2025). Returns fantasy points and box score stats per game.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getNBAPlayerStats",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "PlayCaller NBA player ID",
            "schema": {
              "type": "string"
            },
            "example": "pc_nba_1262"
          },
          {
            "name": "season",
            "in": "query",
            "description": "Season year (2021–2025)",
            "schema": {
              "type": "integer"
            },
            "example": 2025
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max game logs (default 30, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 30
            },
            "example": 30
          }
        ],
        "responses": {
          "200": {
            "description": "NBA game log",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "player": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "full_name": {
                          "type": "string"
                        },
                        "position": {
                          "type": "string"
                        },
                        "team": {
                          "type": "string"
                        }
                      }
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/HistoricalGameRecord"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "404": {
            "description": "Player not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/nba/teams/{team}/roster": {
      "get": {
        "tags": [
          "NBA"
        ],
        "summary": "NBA team roster",
        "description": "Active roster for a specific NBA team. Returns all players from `player_identities` for the requested team abbreviation.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getNBATeamRoster",
        "parameters": [
          {
            "name": "team",
            "in": "path",
            "required": true,
            "description": "3-letter NBA team abbreviation (e.g. BOS, LAL)",
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 3
            },
            "example": "BOS"
          },
          {
            "name": "position",
            "in": "query",
            "description": "Filter by position",
            "schema": {
              "type": "string",
              "enum": [
                "PG",
                "SG",
                "SF",
                "PF",
                "C"
              ]
            },
            "example": "PG"
          }
        ],
        "responses": {
          "200": {
            "description": "Team roster",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "team": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "full_name": {
                            "type": "string"
                          },
                          "position": {
                            "type": "string",
                            "nullable": true
                          },
                          "status": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "404": {
            "description": "Team abbreviation not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/nba/confidence": {
      "get": {
        "tags": [
          "NBA"
        ],
        "summary": "NBA confidence model — raw score + components (Pro Insights, AUC 0.855)",
        "description": "Full detail behind PlayCaller's best-validated signal in the entire portfolio — AUC-ROC 0.855, 84.23x decile lift, promoted ACTIVE 2026-06-19. `/v1/feed` returns a capped display score for this same model; this endpoint exposes the raw (pre-cap) score, percentile, and the 5 underlying signal components including `usage_vacuum`.\n\n**Tier access:** Pro Insights, Syndicate Alpha",
        "operationId": "getNBAConfidence",
        "parameters": [
          {
            "name": "player",
            "in": "query",
            "required": true,
            "description": "Player full name (fuzzy matched)",
            "schema": {
              "type": "string"
            },
            "example": "Nikola Jokic"
          }
        ],
        "responses": {
          "200": {
            "description": "NBA confidence score with raw detail and model audit citation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "player": {
                      "type": "string"
                    },
                    "team": {
                      "type": "string",
                      "nullable": true
                    },
                    "position": {
                      "type": "string",
                      "nullable": true
                    },
                    "confirmed_out": {
                      "type": "boolean"
                    },
                    "reason": {
                      "type": "string",
                      "nullable": true,
                      "description": "Present when confidence is null: \"insufficient game history\", \"unsupported position (X)\", or a disqualification reason"
                    },
                    "confidence": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "score": {
                          "type": "number",
                          "example": 43
                        },
                        "display": {
                          "type": "string",
                          "example": "43%"
                        },
                        "tier": {
                          "type": "string",
                          "example": "strong"
                        },
                        "label": {
                          "type": "string",
                          "example": "Strong Start"
                        },
                        "signals": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "key": {
                                "type": "string"
                              },
                              "label": {
                                "type": "string"
                              },
                              "value": {
                                "type": "number"
                              },
                              "direction": {
                                "type": "string",
                                "enum": [
                                  "up",
                                  "down",
                                  "flat"
                                ]
                              },
                              "note": {
                                "type": "string"
                              }
                            }
                          }
                        },
                        "raw": {
                          "type": "object",
                          "description": "Pre-display-cap detail — the actual differentiator this endpoint sells over /v1/feed’s capped summary",
                          "properties": {
                            "raw_features": {
                              "type": "array",
                              "items": {
                                "type": "number"
                              }
                            },
                            "normed_features": {
                              "type": "array",
                              "items": {
                                "type": "number"
                              }
                            },
                            "z": {
                              "type": "number"
                            },
                            "raw_logit": {
                              "type": "number"
                            },
                            "calibrated": {
                              "type": "number"
                            },
                            "raw_pct": {
                              "type": "number",
                              "example": 43
                            },
                            "capped_pct": {
                              "type": "number",
                              "example": 43
                            },
                            "display_cap": {
                              "type": "number",
                              "example": 55
                            },
                            "was_capped": {
                              "type": "boolean"
                            }
                          }
                        }
                      }
                    },
                    "model_audit": {
                      "type": "object",
                      "properties": {
                        "auc": {
                          "type": "number",
                          "example": 0.855
                        },
                        "decile_lift": {
                          "type": "number",
                          "example": 84.23
                        },
                        "model_type": {
                          "type": "string",
                          "example": "confidence"
                        },
                        "sport": {
                          "type": "string",
                          "example": "NBA"
                        },
                        "validated": {
                          "type": "string",
                          "format": "date"
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "403": {
            "description": "Pro tier required for this endpoint",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "TIER_INSUFFICIENT",
                  "message": "This endpoint requires a Pro subscription.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/tiers",
                  "upgrade_url": "https://playcallerapp.com/developer/checkout?tier=pro"
                }
              }
            }
          },
          "404": {
            "description": "Player not found or not an NBA player"
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/nfl/teams": {
      "get": {
        "tags": [
          "NFL"
        ],
        "summary": "All 32 NFL teams",
        "description": "Returns metadata for all 32 NFL teams including conference, division, and live roster counts from `player_identities`.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "listNFLTeams",
        "parameters": [
          {
            "name": "conference",
            "in": "query",
            "description": "Filter by conference",
            "schema": {
              "type": "string",
              "enum": [
                "AFC",
                "NFC"
              ]
            },
            "example": "AFC"
          },
          {
            "name": "division",
            "in": "query",
            "description": "Filter by division (partial match: \"North\", \"AFC West\")",
            "schema": {
              "type": "string"
            },
            "example": "North"
          }
        ],
        "responses": {
          "200": {
            "description": "32 NFL teams with roster counts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "abbreviation": {
                            "type": "string",
                            "example": "KC"
                          },
                          "full_name": {
                            "type": "string",
                            "example": "Kansas City Chiefs"
                          },
                          "city": {
                            "type": "string",
                            "example": "Kansas City"
                          },
                          "nickname": {
                            "type": "string",
                            "example": "Chiefs"
                          },
                          "conference": {
                            "type": "string",
                            "example": "AFC"
                          },
                          "division": {
                            "type": "string",
                            "example": "AFC West"
                          },
                          "player_count": {
                            "type": "integer",
                            "example": 53
                          },
                          "roster_url": {
                            "type": "string",
                            "example": "/v1/nfl/teams/KC/roster"
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/nfl/teams/{team}/roster": {
      "get": {
        "tags": [
          "NFL"
        ],
        "summary": "NFL team roster",
        "description": "Active roster for a specific NFL team from `player_identities`. Filter by position to pull only QBs, WRs, or RBs.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getNFLTeamRoster",
        "parameters": [
          {
            "name": "team",
            "in": "path",
            "required": true,
            "description": "2-3 letter NFL team abbreviation (e.g. KC, NE, SF)",
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 3
            },
            "example": "KC"
          },
          {
            "name": "position",
            "in": "query",
            "description": "Filter by position",
            "schema": {
              "type": "string",
              "enum": [
                "QB",
                "RB",
                "WR",
                "TE",
                "K",
                "DEF",
                "DL",
                "LB",
                "DB",
                "OL"
              ]
            },
            "example": "WR"
          }
        ],
        "responses": {
          "200": {
            "description": "Team roster",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "team": {
                      "type": "object",
                      "properties": {
                        "abbreviation": {
                          "type": "string"
                        },
                        "full_name": {
                          "type": "string"
                        },
                        "conference": {
                          "type": "string"
                        },
                        "division": {
                          "type": "string"
                        }
                      }
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "example": "pc_nfl_001234"
                          },
                          "full_name": {
                            "type": "string"
                          },
                          "position": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "404": {
            "description": "Team abbreviation not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/nfl/players": {
      "get": {
        "tags": [
          "NFL"
        ],
        "summary": "NFL players",
        "description": "All NFL players from the canonical `player_identities` table. Searchable by name, position, or team. Same identity-resolution pipeline as MLB and NBA.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "listNFLPlayers",
        "parameters": [
          {
            "name": "search",
            "in": "query",
            "description": "Partial player name (case-insensitive)",
            "schema": {
              "type": "string"
            },
            "example": "Mahomes"
          },
          {
            "name": "position",
            "in": "query",
            "description": "Filter by position",
            "schema": {
              "type": "string",
              "enum": [
                "QB",
                "RB",
                "WR",
                "TE",
                "K",
                "DEF"
              ]
            },
            "example": "WR"
          },
          {
            "name": "team",
            "in": "query",
            "description": "2-3 letter team abbreviation",
            "schema": {
              "type": "string"
            },
            "example": "KC"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max results (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "example": 50
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Pagination offset",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "example": 0
          }
        ],
        "responses": {
          "200": {
            "description": "NFL players",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "example": "pc_nfl_001234"
                          },
                          "full_name": {
                            "type": "string"
                          },
                          "first_name": {
                            "type": "string"
                          },
                          "last_name": {
                            "type": "string"
                          },
                          "position": {
                            "type": "string"
                          },
                          "team": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/nfl/players/{id}": {
      "get": {
        "tags": [
          "NFL"
        ],
        "summary": "NFL player profile by ID",
        "description": "Full profile for a single NFL player including team metadata, conference/division, and platform-resolved status.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getNFLPlayer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "PlayCaller NFL player ID (format: pc_nfl_XXXXXX)",
            "schema": {
              "type": "string"
            },
            "example": "pc_nfl_001234"
          }
        ],
        "responses": {
          "200": {
            "description": "NFL player profile",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "full_name": {
                          "type": "string"
                        },
                        "first_name": {
                          "type": "string"
                        },
                        "last_name": {
                          "type": "string"
                        },
                        "position": {
                          "type": "string"
                        },
                        "team": {
                          "type": "string"
                        },
                        "team_name": {
                          "type": "string",
                          "nullable": true
                        },
                        "conference": {
                          "type": "string",
                          "nullable": true
                        },
                        "division": {
                          "type": "string",
                          "nullable": true
                        },
                        "status": {
                          "type": "string"
                        },
                        "metadata": {
                          "type": "object",
                          "nullable": true
                        },
                        "last_updated": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "404": {
            "description": "Player not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/nfl/players/{id}/stats": {
      "get": {
        "tags": [
          "NFL"
        ],
        "summary": "Weekly game log for an NFL player",
        "description": "Game-by-game stat lines from `historical_performance`. Covers NFL 2024 full season (weeks 1–18, ~4,400 records). Returns passing/rushing/receiving splits and fantasy points.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getNFLPlayerStats",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "PlayCaller NFL player ID",
            "schema": {
              "type": "string"
            },
            "example": "pc_nfl_001234"
          },
          {
            "name": "season",
            "in": "query",
            "description": "Season year (default: all available)",
            "schema": {
              "type": "integer"
            },
            "example": 2024
          },
          {
            "name": "week",
            "in": "query",
            "description": "NFL week number (1–18)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 18
            },
            "example": 8
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max game logs (default 30, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 30
            },
            "example": 30
          }
        ],
        "responses": {
          "200": {
            "description": "Weekly game log",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "player": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "full_name": {
                          "type": "string"
                        },
                        "position": {
                          "type": "string"
                        },
                        "team": {
                          "type": "string"
                        }
                      }
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "season": {
                            "type": "integer"
                          },
                          "week": {
                            "type": "integer"
                          },
                          "team": {
                            "type": "string"
                          },
                          "opponent": {
                            "type": "string",
                            "nullable": true
                          },
                          "position": {
                            "type": "string"
                          },
                          "passing": {
                            "type": "object",
                            "properties": {
                              "yards": {
                                "type": "integer",
                                "nullable": true
                              },
                              "tds": {
                                "type": "integer",
                                "nullable": true
                              }
                            }
                          },
                          "rushing": {
                            "type": "object",
                            "properties": {
                              "yards": {
                                "type": "integer",
                                "nullable": true
                              },
                              "tds": {
                                "type": "integer",
                                "nullable": true
                              }
                            }
                          },
                          "receiving": {
                            "type": "object",
                            "properties": {
                              "yards": {
                                "type": "integer",
                                "nullable": true
                              },
                              "tds": {
                                "type": "integer",
                                "nullable": true
                              },
                              "receptions": {
                                "type": "integer",
                                "nullable": true
                              }
                            }
                          },
                          "snap_pct": {
                            "type": "number",
                            "nullable": true
                          },
                          "target_share": {
                            "type": "number",
                            "nullable": true
                          },
                          "air_yards": {
                            "type": "number",
                            "nullable": true
                          },
                          "fantasy_points": {
                            "type": "number",
                            "nullable": true
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "404": {
            "description": "Player not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/nfl/games": {
      "get": {
        "tags": [
          "NFL"
        ],
        "summary": "NFL schedule and scores",
        "description": "NFL schedule and game results from `nfl_games`. Covers the 2026 season (285 games scheduled) with 2024 results backfilled. Filter by season, week, or status.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "listNFLGames",
        "parameters": [
          {
            "name": "season",
            "in": "query",
            "description": "Season year (default: all)",
            "schema": {
              "type": "integer"
            },
            "example": 2026
          },
          {
            "name": "week",
            "in": "query",
            "description": "NFL week number",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 22
            },
            "example": 1
          },
          {
            "name": "status",
            "in": "query",
            "description": "Game status filter",
            "schema": {
              "type": "string",
              "enum": [
                "scheduled",
                "in_progress",
                "final"
              ]
            },
            "example": "final"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max games (default 30, max 100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 30
            },
            "example": 30
          }
        ],
        "responses": {
          "200": {
            "description": "NFL games",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "game_id": {
                            "type": "string"
                          },
                          "season": {
                            "type": "integer"
                          },
                          "week": {
                            "type": "integer"
                          },
                          "season_type": {
                            "type": "string",
                            "example": "regular"
                          },
                          "game_time": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "status": {
                            "type": "string"
                          },
                          "away_team": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string"
                              },
                              "abbreviation": {
                                "type": "string"
                              }
                            }
                          },
                          "home_team": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string"
                              },
                              "abbreviation": {
                                "type": "string"
                              }
                            }
                          },
                          "away_score": {
                            "type": "integer",
                            "nullable": true
                          },
                          "home_score": {
                            "type": "integer",
                            "nullable": true
                          },
                          "winner": {
                            "type": "string",
                            "nullable": true
                          },
                          "spread": {
                            "type": "number",
                            "nullable": true
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/nfl/standings": {
      "get": {
        "tags": [
          "NFL"
        ],
        "summary": "NFL division standings",
        "description": "NFL division standings computed from `nfl_games` results (W/L/T record, win %). Grouped by conference and division.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getNFLStandings",
        "parameters": [
          {
            "name": "conference",
            "in": "query",
            "description": "Filter by conference",
            "schema": {
              "type": "string",
              "enum": [
                "AFC",
                "NFC"
              ]
            },
            "example": "AFC"
          },
          {
            "name": "division",
            "in": "query",
            "description": "Filter by division (partial match: \"AFC West\")",
            "schema": {
              "type": "string"
            },
            "example": "AFC West"
          },
          {
            "name": "season",
            "in": "query",
            "description": "Season year (defaults to current)",
            "schema": {
              "type": "integer"
            },
            "example": 2026
          }
        ],
        "responses": {
          "200": {
            "description": "NFL standings by division",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "season": {
                      "type": "integer"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "team": {
                            "type": "string",
                            "example": "KC"
                          },
                          "full_name": {
                            "type": "string",
                            "example": "Kansas City Chiefs"
                          },
                          "conference": {
                            "type": "string",
                            "example": "AFC"
                          },
                          "division": {
                            "type": "string",
                            "example": "AFC West"
                          },
                          "wins": {
                            "type": "integer"
                          },
                          "losses": {
                            "type": "integer"
                          },
                          "ties": {
                            "type": "integer"
                          },
                          "win_pct": {
                            "type": "number",
                            "format": "float",
                            "example": 0.75
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/{sport}/players/{id}/alpha": {
      "get": {
        "tags": [
          "Multi"
        ],
        "summary": "Alpha Metrics for a player (Pro Insights+)",
        "description": "Returns three proprietary ML-derived signals computed from the player's last 8 games:\n\n- **Consistency Score (0–100)** — how stable the player's usage/floor is. Higher = more reliable starter.\n- **Momentum Delta** — signed float. Positive = trending up vs. prior 3-game baseline; negative = cooling off.\n- **Opportunity Ceiling** — 90th-percentile fantasy output from the sample window. Represents the player's peak upside.\n\nResults are pre-computed weekly (Tuesday 3 AM ET, post-MNF) and cached. Fresh players compute on-the-fly.\n\n**Tier access:** Pro Insights, Syndicate Alpha",
        "operationId": "getPlayerAlphaMetrics",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sport",
            "in": "path",
            "required": true,
            "description": "Sport key",
            "schema": {
              "type": "string",
              "enum": [
                "nfl",
                "mlb",
                "nba"
              ]
            },
            "example": "nfl"
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "PlayCaller player ID",
            "schema": {
              "type": "string"
            },
            "example": "pc_nfl_001234"
          }
        ],
        "responses": {
          "200": {
            "description": "Alpha Metrics",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "player_id": {
                          "type": "string",
                          "example": "pc_nfl_001234"
                        },
                        "full_name": {
                          "type": "string",
                          "example": "CeeDee Lamb"
                        },
                        "position": {
                          "type": "string",
                          "example": "WR"
                        },
                        "team": {
                          "type": "string",
                          "example": "DAL"
                        },
                        "sport": {
                          "type": "string",
                          "example": "nfl"
                        },
                        "consistency_score": {
                          "type": "number",
                          "nullable": true,
                          "minimum": 0,
                          "maximum": 100,
                          "description": "Usage/floor stability (0–100). Higher = more consistent starter.",
                          "example": 78
                        },
                        "momentum_delta": {
                          "type": "number",
                          "nullable": true,
                          "description": "Avg pts last 3 games minus avg games 4–6 back. Positive = trending up.",
                          "example": 4.2
                        },
                        "opportunity_ceiling": {
                          "type": "number",
                          "nullable": true,
                          "description": "90th-percentile fantasy output from the last 8 games. Peak upside.",
                          "example": 38.4
                        },
                        "sample_size": {
                          "type": "integer",
                          "example": 8
                        },
                        "season": {
                          "type": "integer",
                          "example": 2024
                        },
                        "week_computed": {
                          "type": "integer",
                          "nullable": true,
                          "example": 14
                        },
                        "computed_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "403": {
            "description": "Pro Insights or Syndicate Alpha key required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Insufficient data (< 4 historical games)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/players/similar/{id}": {
      "get": {
        "tags": [
          "Multi"
        ],
        "summary": "Find players with similar stat profiles (Pro Insights+)",
        "description": "Returns the N most similar players by cosine distance across an 8-dimension stat-profile vector:\n\n1. Average fantasy points\n2. Usage rate (snap% for NFL, minutes for NBA)\n3. Opportunity rate (target share for NFL, usage% for NBA)\n4. Average rushing yards\n5. Average receiving yards\n6. Consistency Score (from Alpha Metrics)\n7. Momentum Delta (normalized)\n8. Opportunity Ceiling (from Alpha Metrics)\n\nUse case: \"Find WRs with the same profile as CeeDee Lamb,\" \"Identify breakout candidates with similar usage to Cooper Kupp Year 2,\" DFS stack-building, dynasty trade comps.\n\n**Tier access:** Pro Insights, Syndicate Alpha",
        "operationId": "getSimilarPlayers",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "PlayCaller player ID to find comps for",
            "schema": {
              "type": "string"
            },
            "example": "pc_nfl_001234"
          },
          {
            "name": "sport",
            "in": "query",
            "required": true,
            "description": "Sport key (required — similarity is sport-scoped)",
            "schema": {
              "type": "string",
              "enum": [
                "nfl",
                "mlb",
                "nba"
              ]
            },
            "example": "nfl"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Number of similar players (default 10, max 25)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 25,
              "default": 10
            },
            "example": 10
          }
        ],
        "responses": {
          "200": {
            "description": "Similar players ranked by cosine similarity",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "query": {
                      "type": "object",
                      "properties": {
                        "player_id": {
                          "type": "string"
                        },
                        "full_name": {
                          "type": "string"
                        },
                        "position": {
                          "type": "string"
                        },
                        "team": {
                          "type": "string"
                        },
                        "sport": {
                          "type": "string"
                        }
                      }
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "full_name": {
                            "type": "string"
                          },
                          "position": {
                            "type": "string"
                          },
                          "team": {
                            "type": "string"
                          },
                          "similarity_score": {
                            "type": "number",
                            "minimum": -1,
                            "maximum": 1,
                            "description": "1.0 = identical profile, 0.0 = no overlap",
                            "example": 0.9342
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "sport parameter missing or invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "403": {
            "description": "Pro Insights or Syndicate Alpha key required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Player not found or insufficient game data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/stream": {
      "get": {
        "tags": [
          "Multi"
        ],
        "summary": "Real-time SSE event stream (Pro Insights+)",
        "description": "Server-Sent Events stream delivering live sports intelligence as it happens. Keep the connection open and receive events pushed by the server.\n\n**Events pushed:**\n- `player.injured` — new injury signal detected\n- `game.score_updated` — live score change\n- `game.status_changed` — game state transition (scheduled → in_progress → final)\n- `anomaly.detected` — statistical anomaly flagged\n\nHeartbeat `:heartbeat` comment sent every 30s to keep the connection alive.\n\n**Tier access:** Pro Insights, Syndicate Alpha",
        "operationId": "streamEvents",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sport",
            "in": "query",
            "description": "Filter to a single sport (default: all)",
            "schema": {
              "type": "string",
              "enum": [
                "nfl",
                "mlb",
                "nba",
                "all"
              ]
            },
            "example": "nfl"
          }
        ],
        "responses": {
          "200": {
            "description": "SSE stream (text/event-stream)",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "example": "event: player.injured\ndata: {\"event\":\"player.injured\",\"sport\":\"nfl\",\"player_name\":\"Patrick Mahomes\",\"team\":\"KC\",\"status\":\"Questionable\",\"injury_type\":\"Ankle\",\"ts\":\"2026-07-02T22:00:00Z\"}\n\n"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "403": {
            "description": "Pro Insights or Syndicate Alpha key required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/daas/webhooks": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Register a webhook endpoint (Syndicate Alpha)",
        "description": "Register an HTTPS endpoint to receive signed webhook deliveries for one or more event types. Returns a one-time secret for HMAC-SHA256 signature verification (`X-PlayCaller-Signature`).\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "createWebhook",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url",
                  "events"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "example": "https://your-server.com/playcaller-hook"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "player.injured",
                        "game.score_updated",
                        "game.status_changed",
                        "anomaly.detected"
                      ]
                    },
                    "example": [
                      "player.injured",
                      "anomaly.detected"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook registered. Secret shown once.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "url": {
                          "type": "string"
                        },
                        "events": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "secret": {
                          "type": "string",
                          "description": "HMAC secret — store securely, not shown again"
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "403": {
            "description": "Syndicate Alpha key required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "List registered webhooks (Syndicate Alpha)",
        "operationId": "listWebhooks",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Active and inactive webhooks for this key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "url": {
                            "type": "string"
                          },
                          "events": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "is_active": {
                            "type": "boolean"
                          },
                          "failure_count": {
                            "type": "integer"
                          },
                          "last_delivery_at": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "403": {
            "description": "Syndicate Alpha key required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/daas/webhooks/{id}": {
      "delete": {
        "tags": [
          "Account"
        ],
        "summary": "Deactivate a webhook (Syndicate Alpha)",
        "operationId": "deleteWebhook",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook deactivated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "404": {
            "description": "Webhook not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/daas/webhooks/{id}/deliveries": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Webhook delivery log (Syndicate Alpha)",
        "description": "Returns the last 50 delivery attempts for a webhook, including status codes, attempt counts, and error messages.",
        "operationId": "getWebhookDeliveries",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Delivery log",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "webhook_id": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "event_type": {
                            "type": "string"
                          },
                          "status_code": {
                            "type": "integer",
                            "nullable": true
                          },
                          "attempt": {
                            "type": "integer"
                          },
                          "delivered_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "error_message": {
                            "type": "string",
                            "nullable": true
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "404": {
            "description": "Webhook not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/players/search": {
      "get": {
        "tags": [
          "Multi"
        ],
        "summary": "Cross-sport player search",
        "description": "Search across all 13,606 canonical player identities (NFL + MLB + NBA) by name, with optional sport and position filters. Returns matching players from all sports in a single call.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "searchPlayers",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Player name search (min 2 characters)",
            "schema": {
              "type": "string",
              "minLength": 2
            },
            "example": "LeBron"
          },
          {
            "name": "sport",
            "in": "query",
            "description": "Filter by sport",
            "schema": {
              "type": "string",
              "enum": [
                "nfl",
                "mlb",
                "nba"
              ]
            },
            "example": "nba"
          },
          {
            "name": "position",
            "in": "query",
            "description": "Filter by position",
            "schema": {
              "type": "string"
            },
            "example": "WR"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max results (default 25, max 100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            },
            "example": 25
          }
        ],
        "responses": {
          "200": {
            "description": "Matching player identities across all sports",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "q": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PlayerIdentity"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or too-short q parameter",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/trending": {
      "get": {
        "tags": [
          "Multi"
        ],
        "summary": "Trending hashtags/topics (all tiers, including free Sandbox)",
        "description": "Raw trending-topic rows refreshed on a ~2-hour cadence. Contextual social signal, not a model output — no tier gate.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getTrending",
        "parameters": [
          {
            "name": "sport",
            "in": "query",
            "description": "Filter by sport (omit or \"all\" for everything)",
            "schema": {
              "type": "string",
              "enum": [
                "nfl",
                "mlb",
                "nba",
                "all"
              ]
            },
            "example": "nba"
          }
        ],
        "responses": {
          "200": {
            "description": "Trending topics",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "tag": {
                            "type": "string"
                          },
                          "sport": {
                            "type": "string"
                          },
                          "category": {
                            "type": "string"
                          },
                          "relevance_score": {
                            "type": "integer"
                          },
                          "scraped_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "expires_at": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/articles/waiver": {
      "get": {
        "tags": [
          "Multi"
        ],
        "summary": "Waiver wire articles with signal audit trail (Pro Insights)",
        "description": "AI-generated waiver-wire recommendations alongside `signals_used` — the exact validated model-signal rows, with their own AUCs, that drove each call. No other sports-data API exposes which signals produced a given recommendation.\n\n**Tier access:** Pro Insights, Syndicate Alpha",
        "operationId": "getWaiverArticles",
        "parameters": [
          {
            "name": "sport",
            "in": "query",
            "required": true,
            "description": "Sport",
            "schema": {
              "type": "string",
              "enum": [
                "nfl",
                "mlb",
                "nba"
              ]
            },
            "example": "nfl"
          },
          {
            "name": "season",
            "in": "query",
            "description": "Season year",
            "schema": {
              "type": "integer"
            },
            "example": 2026
          },
          {
            "name": "week",
            "in": "query",
            "description": "Week number",
            "schema": {
              "type": "integer"
            },
            "example": 10
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max articles (default 10, max 50)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 10
            },
            "example": 10
          }
        ],
        "responses": {
          "200": {
            "description": "Waiver wire articles with signal audit trail",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "slug": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "content": {
                            "type": "string"
                          },
                          "meta_description": {
                            "type": "string",
                            "nullable": true
                          },
                          "season": {
                            "type": "integer"
                          },
                          "week": {
                            "type": "integer"
                          },
                          "signals_used": {
                            "type": "array",
                            "description": "Validated model-signal rows that produced this article"
                          },
                          "published_at": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing required sport parameter"
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "403": {
            "description": "Pro tier required for this endpoint",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "TIER_INSUFFICIENT",
                  "message": "This endpoint requires a Pro subscription.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/tiers",
                  "upgrade_url": "https://playcallerapp.com/developer/checkout?tier=pro"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/{sport}/games/history": {
      "get": {
        "tags": [
          "Multi"
        ],
        "summary": "Raw per-game historical box lines (Pro Insights)",
        "description": "`/analytics/trends` only returns aggregated trend summaries; this exposes the granular per-game rows behind those — `historical_performance` for NFL/NBA, `daily_player_stats` for MLB.\n\n**Tier access:** Pro Insights, Syndicate Alpha",
        "operationId": "getGamesHistory",
        "parameters": [
          {
            "name": "sport",
            "in": "path",
            "required": true,
            "description": "Sport",
            "schema": {
              "type": "string",
              "enum": [
                "nfl",
                "nba",
                "mlb"
              ]
            },
            "example": "nfl"
          },
          {
            "name": "player_name",
            "in": "query",
            "description": "Partial match (ILIKE)",
            "schema": {
              "type": "string"
            },
            "example": "Josh Allen"
          },
          {
            "name": "season",
            "in": "query",
            "description": "Season year",
            "schema": {
              "type": "integer"
            },
            "example": 2025
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max rows (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "Raw per-game rows for the requested sport",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "sport": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "403": {
            "description": "Pro tier required for this endpoint",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "TIER_INSUFFICIENT",
                  "message": "This endpoint requires a Pro subscription.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/tiers",
                  "upgrade_url": "https://playcallerapp.com/developer/checkout?tier=pro"
                }
              }
            }
          },
          "404": {
            "description": "Unsupported sport (must be nfl, nba, or mlb)"
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/cfb/games": {
      "get": {
        "tags": [
          "CFB"
        ],
        "summary": "College football scoreboard (Pro)",
        "description": "CFB game scores and schedule from ESPN. Covers FBS games including conference championships and bowl games.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "listCFBGames",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "description": "Game date (YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-09-05"
          },
          {
            "name": "state",
            "in": "query",
            "description": "Game state filter (matches the live state column exactly)",
            "schema": {
              "type": "string",
              "enum": [
                "scheduled",
                "in_progress",
                "final"
              ]
            },
            "example": "final"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max games (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "CFB games",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ESPNGame"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "403": {
            "description": "Pro tier required for this endpoint",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "TIER_INSUFFICIENT",
                  "message": "This endpoint requires a Pro subscription.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/tiers",
                  "upgrade_url": "https://playcallerapp.com/developer/checkout?tier=pro"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/cfb/standings": {
      "get": {
        "tags": [
          "CFB"
        ],
        "summary": "College football conference standings (Pro)",
        "description": "CFB standings by conference. Includes win %, conference record, and streak. Useful for playoff scenario modeling.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getCFBStandings",
        "parameters": [
          {
            "name": "season",
            "in": "query",
            "description": "Season year (defaults to current)",
            "schema": {
              "type": "integer"
            },
            "example": 2026
          },
          {
            "name": "conference",
            "in": "query",
            "description": "Filter by conference (partial match: \"SEC\", \"Big Ten\")",
            "schema": {
              "type": "string"
            },
            "example": "SEC"
          }
        ],
        "responses": {
          "200": {
            "description": "CFB standings",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "season": {
                      "type": "integer"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ESPNStanding"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "403": {
            "description": "Pro tier required for this endpoint",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "TIER_INSUFFICIENT",
                  "message": "This endpoint requires a Pro subscription.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/tiers",
                  "upgrade_url": "https://playcallerapp.com/developer/checkout?tier=pro"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/cfb/rankings": {
      "get": {
        "tags": [
          "CFB"
        ],
        "summary": "AP / Coaches Poll / CFP rankings (Pro)",
        "description": "AP Top 25, Coaches Poll, and CFP rankings by week. Each poll returns ranked teams with first-place votes, total points, and previous rank movement.\n\n**Tier access:** Pro Insights, Syndicate Alpha",
        "operationId": "getCFBRankings",
        "parameters": [
          {
            "name": "season",
            "in": "query",
            "description": "Season year (defaults to current)",
            "schema": {
              "type": "integer"
            },
            "example": 2026
          },
          {
            "name": "poll",
            "in": "query",
            "description": "Poll filter (partial match: \"AP\", \"Coaches\", \"CFP\")",
            "schema": {
              "type": "string"
            },
            "example": "AP"
          },
          {
            "name": "week",
            "in": "query",
            "description": "Week number (1–16)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 16
            },
            "example": 14
          }
        ],
        "responses": {
          "200": {
            "description": "CFB rankings grouped by poll",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "season": {
                      "type": "integer"
                    },
                    "polls": {
                      "type": "object",
                      "description": "Keys are poll names; values are ranked team arrays",
                      "additionalProperties": {
                        "type": "array",
                        "items": {
                          "$ref": "#/components/schemas/CFBRanking"
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "403": {
            "description": "Pro tier required for this endpoint",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "TIER_INSUFFICIENT",
                  "message": "This endpoint requires a Pro subscription.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/tiers",
                  "upgrade_url": "https://playcallerapp.com/developer/checkout?tier=pro"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/soccer/games": {
      "get": {
        "tags": [
          "Soccer"
        ],
        "summary": "Soccer match scores (EPL + MLS)",
        "description": "Live and historical match scores for EPL and MLS. Includes team logos, venue, broadcast, and score state for display-ready applications.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "listSoccerGames",
        "parameters": [
          {
            "name": "league",
            "in": "query",
            "description": "League filter (omit for both leagues)",
            "schema": {
              "type": "string",
              "enum": [
                "epl",
                "mls"
              ]
            },
            "example": "epl"
          },
          {
            "name": "date",
            "in": "query",
            "description": "Match date (YYYY-MM-DD, defaults to today)",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-05-01"
          },
          {
            "name": "state",
            "in": "query",
            "description": "Game state filter (matches the live state column exactly)",
            "schema": {
              "type": "string",
              "enum": [
                "scheduled",
                "in_progress",
                "final"
              ]
            },
            "example": "final"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max matches (default 30, max 100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 30
            },
            "example": 30
          }
        ],
        "responses": {
          "200": {
            "description": "Soccer matches",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ESPNGame"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/soccer/standings": {
      "get": {
        "tags": [
          "Soccer"
        ],
        "summary": "Soccer league table (EPL, MLS, La Liga, Bundesliga, Serie A, UCL)",
        "description": "Current league tables for EPL, MLS, La Liga, Bundesliga, Serie A, and Champions League. Includes points, goal difference, wins, draws, losses, and home/away splits.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getSoccerStandings",
        "parameters": [
          {
            "name": "league",
            "in": "query",
            "description": "League filter (epl, mls, la_liga, bundesliga, serie_a, champions_league; omit for all)",
            "schema": {
              "type": "string",
              "enum": [
                "epl",
                "mls",
                "la_liga",
                "bundesliga",
                "serie_a",
                "champions_league"
              ]
            },
            "example": "epl"
          },
          {
            "name": "season",
            "in": "query",
            "description": "Season year (defaults to current)",
            "schema": {
              "type": "integer"
            },
            "example": 2026
          }
        ],
        "responses": {
          "200": {
            "description": "Soccer standings",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "league": {
                      "type": "string",
                      "example": "epl"
                    },
                    "season": {
                      "type": "integer"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ESPNStanding"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/nhl/games": {
      "get": {
        "tags": [
          "NHL"
        ],
        "summary": "NHL game scores and schedule",
        "description": "Current day scores, live updates, and upcoming schedule for NHL games. Polled every 30 min during game windows.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getNHLGames",
        "parameters": [
          {
            "name": "date",
            "in": "query",
            "description": "Game date (YYYY-MM-DD or 'today')",
            "schema": {
              "type": "string"
            },
            "example": "today"
          },
          {
            "name": "state",
            "in": "query",
            "description": "Filter by game state (in_progress, final, scheduled)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max results (default 50, max 200)",
            "schema": {
              "type": "integer"
            },
            "example": 50
          }
        ],
        "responses": {
          "200": {
            "description": "NHL games",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ESPNGame"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/nhl/standings": {
      "get": {
        "tags": [
          "NHL"
        ],
        "summary": "NHL standings by division",
        "description": "Current NHL standings including wins, losses, OT losses, points, and division/conference breakdown.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getNHLStandings",
        "parameters": [
          {
            "name": "season",
            "in": "query",
            "description": "Season year (defaults to current)",
            "schema": {
              "type": "integer"
            },
            "example": 2026
          },
          {
            "name": "division",
            "in": "query",
            "description": "Filter by division name (partial match)",
            "schema": {
              "type": "string"
            },
            "example": "Atlantic"
          }
        ],
        "responses": {
          "200": {
            "description": "NHL standings",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "season": {
                      "type": "integer"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ESPNStanding"
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/tennis/matches": {
      "get": {
        "tags": [
          "Tennis"
        ],
        "summary": "ATP and WTA match scores",
        "description": "Live and completed tennis matches across ATP and WTA tours. Returns player names, set scores, and match status.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getTennisMatches",
        "parameters": [
          {
            "name": "tour",
            "in": "query",
            "description": "Tour filter (atp or wta)",
            "schema": {
              "type": "string",
              "enum": [
                "atp",
                "wta"
              ]
            },
            "example": "atp"
          },
          {
            "name": "date",
            "in": "query",
            "description": "Match date (YYYY-MM-DD or 'today')",
            "schema": {
              "type": "string"
            },
            "example": "today"
          },
          {
            "name": "state",
            "in": "query",
            "description": "Match state (in_progress, final, scheduled)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max results (default 50, max 200)",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tennis matches",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "match_id": {
                            "type": "string"
                          },
                          "date": {
                            "type": "string"
                          },
                          "tour": {
                            "type": "string"
                          },
                          "state": {
                            "type": "string"
                          },
                          "player_1": {
                            "type": "string"
                          },
                          "player_2": {
                            "type": "string"
                          },
                          "score_p1": {
                            "type": "integer"
                          },
                          "score_p2": {
                            "type": "integer"
                          },
                          "set": {
                            "type": "integer"
                          },
                          "is_final": {
                            "type": "boolean"
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/golf/tournaments": {
      "get": {
        "tags": [
          "Golf"
        ],
        "summary": "Active and recent golf tournaments",
        "description": "Lists current and recently completed PGA Tour and LPGA Tour tournaments with player counts and dates.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getGolfTournaments",
        "parameters": [
          {
            "name": "tour",
            "in": "query",
            "description": "Tour filter (pga or lpga)",
            "schema": {
              "type": "string",
              "enum": [
                "pga",
                "lpga"
              ]
            },
            "example": "pga"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max tournaments (default 10, max 50)",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tournament list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "tournament_id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "date": {
                            "type": "string"
                          },
                          "tour": {
                            "type": "string"
                          },
                          "is_active": {
                            "type": "boolean"
                          },
                          "player_count": {
                            "type": "integer"
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/golf/leaderboard": {
      "get": {
        "tags": [
          "Golf"
        ],
        "summary": "Current tournament leaderboard",
        "description": "Live or most recent tournament leaderboard with positions, scores relative to par, and per-round scores. Updated every 4 hours.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getGolfLeaderboard",
        "parameters": [
          {
            "name": "tour",
            "in": "query",
            "description": "Tour (pga or lpga)",
            "schema": {
              "type": "string",
              "enum": [
                "pga",
                "lpga"
              ]
            },
            "example": "pga"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max players (default 50, max 156)",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Golf leaderboard",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "tournament": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "date": {
                          "type": "string"
                        },
                        "is_active": {
                          "type": "boolean"
                        }
                      }
                    },
                    "count": {
                      "type": "integer"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "position": {
                            "type": "integer"
                          },
                          "position_display": {
                            "type": "string"
                          },
                          "player_name": {
                            "type": "string"
                          },
                          "total_score_display": {
                            "type": "string"
                          },
                          "thru_display": {
                            "type": "string"
                          },
                          "rounds": {
                            "type": "object",
                            "properties": {
                              "r1": {
                                "type": "integer"
                              },
                              "r2": {
                                "type": "integer"
                              },
                              "r3": {
                                "type": "integer"
                              },
                              "r4": {
                                "type": "integer"
                              }
                            }
                          }
                        }
                      }
                    },
                    "meta": {
                      "$ref": "#/components/schemas/ResponseMeta"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/sports": {
      "get": {
        "tags": [
          "Multi"
        ],
        "summary": "Supported sports and endpoint discovery",
        "description": "Returns all supported sports with their available endpoints and status. Use this to programmatically discover which data is live vs. coming soon for your tier.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "listSports",
        "responses": {
          "200": {
            "description": "Sports and available endpoints by tier",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "endpoint": {
                      "type": "string"
                    },
                    "sports": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "sport": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "endpoints": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    },
                    "cross_sport_endpoints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Endpoints not scoped to one sport, e.g. /v1/trending, /v1/articles/waiver"
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "tier": {
                          "type": "string"
                        },
                        "documentation_url": {
                          "type": "string",
                          "format": "uri"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/daas/usage": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "API key quota and usage breakdown",
        "description": "Returns current quota consumption, rate limits, tier details, and per-endpoint call breakdown for the authenticated key. Use this to build usage dashboards or trigger pre-quota alerts in your application.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getDaaSUsage",
        "responses": {
          "200": {
            "description": "API key usage statistics — flat object, not wrapped in `data`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageStats"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/daas/key-info": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "API key metadata",
        "description": "Returns tier, trial status, and creation date for the API key passed as `?key=` query parameter. Useful for building key verification flows in your own applications without exposing the full usage payload.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getDaaSKeyInfo",
        "parameters": [
          {
            "name": "key",
            "in": "query",
            "required": true,
            "description": "The PlayCaller API key to look up",
            "schema": {
              "type": "string"
            },
            "example": "pc_pro_abc123"
          }
        ],
        "responses": {
          "200": {
            "description": "API key metadata",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "tier": {
                      "type": "string",
                      "enum": [
                        "sandbox",
                        "hobbyist",
                        "build",
                        "pro",
                        "pro_insights",
                        "enterprise",
                        "syndicate_alpha"
                      ]
                    },
                    "is_trial": {
                      "type": "boolean"
                    },
                    "trial_days_remaining": {
                      "type": "integer",
                      "nullable": true
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "404": {
            "description": "Key not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/daas/trial/start": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Start a 14-day free trial",
        "description": "Creates a Hobbyist-tier API key for a 14-day free trial. No credit card required. Key is returned in the response and emailed to the provided address. Limit: one trial per email.\n\n**Auth:** No API key required",
        "operationId": "startDaaSTrial",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "example": "dev@example.com"
                  },
                  "use_case": {
                    "type": "string",
                    "description": "What you are building (optional, helps us improve)",
                    "example": "DFS lineup optimizer for NFL season"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Trial key created — full response contains API key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "api_key": {
                      "type": "string",
                      "description": "Your new PlayCaller API key. Store it securely.",
                      "example": "pc_hob_xxxxxxxx"
                    },
                    "tier": {
                      "type": "string",
                      "example": "hobbyist"
                    },
                    "trial_ends_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "message": {
                      "type": "string",
                      "example": "Your 14-day trial is active. Key emailed to dev@example.com."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Email already has an active trial or subscription",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/daas/register-key": {
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Register an existing API key",
        "description": "Associates an existing DaaS API key with a user account for dashboard access. Used internally by the developer dashboard onboarding flow.\n\n**Auth:** No API key required",
        "operationId": "registerDaaSKey",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email",
                  "api_key"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "example": "dev@example.com"
                  },
                  "api_key": {
                    "type": "string",
                    "example": "pc_pro_abc123"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Key registered to account",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "INVALID_API_KEY",
                  "message": "The provided API key is invalid or has been revoked.",
                  "documentation_url": "https://playcallerapp.com/developer/docs"
                }
              }
            }
          },
          "404": {
            "description": "API key not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly quota exceeded",
            "headers": {
              "Retry-After": {
                "description": "Seconds until rate limit resets",
                "schema": {
                  "type": "integer"
                },
                "example": 42
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                },
                "example": {
                  "error_code": "RATE_LIMIT_EXCEEDED",
                  "message": "Rate limit exceeded. Try again in 42 seconds.",
                  "documentation_url": "https://playcallerapp.com/developer/docs/rate-limits"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/mcp": {
      "get": {
        "tags": [
          "MCP"
        ],
        "summary": "MCP server info and tool discovery",
        "description": "Returns human-readable JSON describing the PlayCaller MCP server: endpoint URL, auth method, all available tools with descriptions, and links to documentation.\n\nPoint Cursor, Claude Desktop, or any MCP-compatible client at this URL to discover available tools automatically.\n\n**Auth:** No authentication required for GET (tool invocation requires X-PlayCaller-Key)",
        "operationId": "getMCPInfo",
        "security": [],
        "responses": {
          "200": {
            "description": "MCP server info with tool list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "example": "PlayCaller MCP Server"
                    },
                    "version": {
                      "type": "string",
                      "example": "1.0.0"
                    },
                    "protocol": {
                      "type": "string",
                      "example": "MCP over HTTP (JSON-RPC 2.0)"
                    },
                    "endpoint": {
                      "type": "string",
                      "format": "uri",
                      "example": "https://playcallerapp.com/mcp"
                    },
                    "auth": {
                      "type": "string",
                      "example": "X-PlayCaller-Key: <your_daas_key>"
                    },
                    "tools": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/MCPTool"
                      }
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri",
                      "example": "https://playcallerapp.com/developer#mcp"
                    },
                    "get_key": {
                      "type": "string",
                      "format": "uri",
                      "example": "https://playcallerapp.com/developer#pricing"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "MCP"
        ],
        "summary": "MCP JSON-RPC 2.0 endpoint",
        "description": "The PlayCaller MCP server implements Anthropic's Model Context Protocol over HTTP transport. Send JSON-RPC 2.0 messages to invoke sports intelligence tools from any AI application.\n\n**Available tools (7):**\n- `get_injury_signals` — Active beat reporter signals filtered by sport/severity\n- `get_player_identity` — Resolve a player name or platform ID across ESPN, Sleeper, Yahoo, NFL.com\n- `get_anomaly_scores` — Players with usage patterns deviating from 3-season baseline (score 0–100)\n- `get_prediction_markets` — Active Kalshi prop markets with AI confidence scores\n- `get_player_projections` — AI fantasy point projections using recent game logs and injury signals\n- `get_player_stats` — Game log for any player by name across NFL/MLB/NBA historical_performance\n- `get_team_roster` — Active roster for any team by sport and abbreviation\n\n**Config for Cursor (.cursor/mcp.json):**\n```json\n{\n  \"mcpServers\": {\n    \"playcaller\": {\n      \"url\": \"https://playcallerapp.com/mcp\",\n      \"headers\": { \"X-PlayCaller-Key\": \"YOUR_API_KEY\" }\n    }\n  }\n}\n```\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "invokeMCPTool",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jsonrpc",
                  "method"
                ],
                "properties": {
                  "jsonrpc": {
                    "type": "string",
                    "enum": [
                      "2.0"
                    ],
                    "example": "2.0"
                  },
                  "id": {
                    "type": "integer",
                    "example": 1
                  },
                  "method": {
                    "type": "string",
                    "enum": [
                      "initialize",
                      "tools/list",
                      "tools/call",
                      "ping"
                    ],
                    "example": "tools/call"
                  },
                  "params": {
                    "type": "object",
                    "description": "Required for tools/call: `name` (tool name) and `arguments` (tool-specific args)",
                    "properties": {
                      "name": {
                        "type": "string",
                        "example": "get_injury_signals"
                      },
                      "arguments": {
                        "type": "object",
                        "example": {
                          "sport": "nfl",
                          "severity": "high",
                          "limit": 5
                        }
                      }
                    }
                  }
                }
              },
              "examples": {
                "listTools": {
                  "summary": "List available tools",
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 1,
                    "method": "tools/list"
                  }
                },
                "callInjurySignals": {
                  "summary": "Get high-severity NFL injuries",
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 2,
                    "method": "tools/call",
                    "params": {
                      "name": "get_injury_signals",
                      "arguments": {
                        "sport": "nfl",
                        "severity": "high",
                        "limit": 5
                      }
                    }
                  }
                },
                "resolvePlayer": {
                  "summary": "Resolve player identity",
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 3,
                    "method": "tools/call",
                    "params": {
                      "name": "get_player_identity",
                      "arguments": {
                        "name": "Christian McCaffrey",
                        "sport": "nfl"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC 2.0 response (always 200 — errors returned in body per JSON-RPC spec)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "jsonrpc": {
                      "type": "string",
                      "example": "2.0"
                    },
                    "id": {
                      "type": "integer",
                      "example": 1
                    },
                    "result": {
                      "type": "object",
                      "description": "Present on success",
                      "properties": {
                        "content": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "example": "text"
                              },
                              "text": {
                                "type": "string",
                                "description": "JSON-encoded tool result"
                              }
                            }
                          }
                        }
                      }
                    },
                    "error": {
                      "type": "object",
                      "description": "Present on error",
                      "properties": {
                        "code": {
                          "type": "integer",
                          "example": -32601
                        },
                        "message": {
                          "type": "string",
                          "example": "Method not found: tools/unknown"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/public/stats": {
      "get": {
        "tags": [
          "Multi"
        ],
        "summary": "Platform stats (unauthenticated)",
        "description": "Public endpoint returning live platform statistics: registered users, active signals, total players tracked, sports covered, and platforms integrated. No API key required.\n\n**Tier access:** Developer Sandbox, Build, Pro Insights, Syndicate Alpha",
        "operationId": "getPublicStats",
        "security": [],
        "responses": {
          "200": {
            "description": "Current platform statistics",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicStats"
                }
              }
            }
          }
        }
      }
    }
  }
}