Discover/MaxPreps API
live

MaxPreps APImaxpreps.com

Access MaxPreps data via API: search schools, get team rosters, schedules, athlete profiles, and national/state rankings for high school sports.

Endpoints
5
Updated
2mo ago

What is the MaxPreps API?

The MaxPreps API covers 5 endpoints for high school sports data, including school search, team rosters with per-player fields like jersey number and grade, game schedules with scores and win/loss results, detailed athlete profiles with career history, and national or state rankings by sport. The get_rankings endpoint alone returns rank, record, movement, and school identifiers for any supported sport.

Try it
School name or search query (e.g., 'Oak Hill Academy', 'Mater Dei')
api.parse.bot/scraper/e0a033cc-4c08-49d5-8417-81682c9b3dbf/<endpoint>
Ready to send
Fill in the parameters and hit sign in to send to see live response data here.
Call it over HTTPgrab a free API key at signup
curl -X GET 'https://api.parse.bot/scraper/e0a033cc-4c08-49d5-8417-81682c9b3dbf/search_schools?query=Mater+Dei' \
  -H 'X-API-Key: $PARSE_API_KEY'
Python SDK · recommended

Typed, relational, agent-ready

A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.

  • Fully typed · autocompletes
  • Objects link to objects
  • Typed errors & pagination

Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:

uv add parse-sdk
uv run parse init
uv run parse add --marketplace maxpreps-com-api

uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.

"""
MaxPreps Sports API Client
Get your API key from: https://parse.bot/settings
"""

import os
import requests
from typing import Any, Dict, List, Optional


class ParseClient:
    """Client for interacting with the MaxPreps Sports API via Parse."""

    def __init__(self, api_key: Optional[str] = None):
        """Initialize the Parse API client."""
        self.base_url = "https://api.parse.bot"
        self.scraper_id = "e0a033cc-4c08-49d5-8417-81682c9b3dbf"
        self.api_key = api_key or os.getenv("PARSE_API_KEY")
        if not self.api_key:
            raise ValueError("API key not provided. Set PARSE_API_KEY environment variable.")

    def _call(self, endpoint: str, method: str = "POST", **params) -> Dict[str, Any]:
        """Make an API call to the Parse bot."""
        url = f"{self.base_url}/scraper/{self.scraper_id}/{endpoint}"
        headers = {
            "X-API-Key": self.api_key,
            "Content-Type": "application/json"
        }

        if method == "GET":
            response = requests.get(url, headers=headers, params=params)
        else:  # POST
            response = requests.post(url, headers=headers, json=params)

        response.raise_for_status()
        return response.json()

    def search_schools(self, query: str) -> Dict[str, Any]:
        """Search for schools by name or query.

        Args:
            query: School name or search query (e.g., 'Oak Hill Academy')

        Returns:
            Dictionary containing list of schools with details
        """
        return self._call("search_schools", method="GET", query=query)

    def get_team_roster(self, path: str, season: str = "24-25") -> Dict[str, Any]:
        """Get the roster for a specific team and season.

        Args:
            path: The school/team path (e.g., '/va/mouth-of-wilson/oak-hill-academy-warriors/basketball/')
            season: The school year season (default: '24-25')

        Returns:
            Dictionary containing roster and team information
        """
        return self._call("get_team_roster", method="GET", path=path, season=season)

    def get_team_schedule(self, path: str, season: str = "24-25") -> Dict[str, Any]:
        """Get the schedule and results for a team.

        Args:
            path: The school/team path
            season: The school year season (default: '24-25')

        Returns:
            Dictionary containing contests, tournaments, and team information
        """
        return self._call("get_team_schedule", method="GET", path=path, season=season)

    def get_athlete_profile(self, path: str, career_id: str) -> Dict[str, Any]:
        """Get detailed athlete profile and history.

        Args:
            path: The athlete profile path
            career_id: The unique career ID for the athlete

        Returns:
            Dictionary containing prospect report, career data, and timeline
        """
        return self._call("get_athlete_profile", method="GET", path=path, career_id=career_id)

    def get_rankings(self, sport: str, state: str = "national") -> Dict[str, Any]:
        """Get national or state rankings for a sport.

        Args:
            sport: The sport name (e.g., 'basketball', 'football')
            state: State code (e.g., 'va', 'il') or 'national' (default: 'national')

        Returns:
            Dictionary containing rankings and title
        """
        return self._call("get_rankings", method="GET", sport=sport, state=state)


if __name__ == "__main__":
    # Initialize the client
    client = ParseClient()

    print("=" * 70)
    print("MaxPreps Sports API - Scout High School Basketball Players")
    print("=" * 70)

    # Step 1: Search for schools
    print("\n[1] Searching for elite high schools...")
    search_queries = ["Mater Dei", "Sierra Canyon", "Montverde Academy"]
    all_schools = []

    for query in search_queries:
        try:
            results = client.search_schools(query)
            schools = results.get("data", {}).get("schools", [])
            if schools:
                all_schools.extend(schools)
                for school in schools:
                    print(f"    ✓ Found: {school['name']} ({school['mascot']}) - {school['city']}, {school['state']}")
        except Exception as e:
            print(f"    ✗ Error searching '{query}': {str(e)}")

    if not all_schools:
        print("    No schools found. Exiting.")
        exit(1)

    # Step 2: Get rosters and identify top players
    print("\n[2] Fetching basketball rosters and analyzing players...")
    player_database = {}

    for school in all_schools[:2]:  # Analyze first 2 schools
        try:
            school_path = school.get("path")
            basketball_path = f"{school_path}basketball/"
            school_name = school.get("name")

            roster_response = client.get_team_roster(basketball_path)
            roster = roster_response.get("data", {}).get("roster", [])

            print(f"\n    {school_name} - {len(roster)} players on roster")

            # Filter guards and forwards
            guards = [p for p in roster if p.get("position") == "G"]
            forwards = [p for p in roster if p.get("position") in ["F", "SF", "PF"]]

            print(f"      • Guards: {len(guards)}")
            print(f"      • Forwards: {len(forwards)}")

            # Store player data for later analysis
            for player in roster[:8]:  # Top 8 players
                player_key = f"{player['display_name']}_{school_name}"
                player_database[player_key] = {
                    "name": player.get("display_name"),
                    "school": school_name,
                    "number": player.get("jersey"),
                    "position": player.get("position"),
                    "height": player.get("height"),
                    "grade": player.get("grade"),
                    "career_id": player.get("career_id"),
                    "profile_path": player.get("profile_url")
                }

        except Exception as e:
            print(f"    ✗ Error fetching roster for {school.get('name')}: {str(e)}")

    # Step 3: Get detailed profiles for top prospects
    print("\n[3] Analyzing top prospect profiles...")
    top_prospects = list(player_database.values())[:5]

    for prospect in top_prospects:
        try:
            if prospect["career_id"] and prospect["profile_path"]:
                profile = client.get_athlete_profile(prospect["profile_path"], prospect["career_id"])
                career_data = profile.get("data", {}).get("career_data", [])
                timeline = profile.get("data", {}).get("timeline", [])

                print(f"\n    {prospect['name']} | {prospect['position']} | {prospect['height']}")
                print(f"      School: {prospect['school']} ({prospect['grade']})")

                if career_data and isinstance(career_data, list) and len(career_data) > 0:
                    current_season = career_data[0]
                    stats = current_season.get("stats", [])
                    if stats:
                        ppg_stat = next((s for s in stats if "Points" in s.get("displayName", "")), None)
                        if ppg_stat:
                            print(f"      PPG: {ppg_stat.get('value', 'N/A')}")

                if timeline:
                    recent_events = timeline[:2]
                    print(f"      Recent Activity: {len(timeline)} events")
                    for event in recent_events:
                        print(f"        - {event.get('title', 'N/A')}")

        except Exception as e:
            print(f"    ✗ Error fetching profile for {prospect['name']}: {str(e)}")

    # Step 4: Get team schedules to see upcoming matchups
    print("\n[4] Checking team schedules...")
    for school in all_schools[:1]:  # Schedule for first school
        try:
            basketball_path = f"{school.get('path')}basketball/"
            schedule = client.get_team_schedule(basketball_path)
            contests = schedule.get("data", {}).get("contests", [])

            print(f"\n    {school['name']} Basketball Schedule ({len(contests)} contests)")
            wins = sum(1 for c in contests if c.get("result", "").startswith("W"))
            losses = sum(1 for c in contests if c.get("result", "").startswith("L"))
            print(f"      Record: {wins}-{losses}")

            # Show recent games
            print("      Recent Results:")
            for contest in contests[:5]:
                opponent = contest.get("opponent", "Unknown")
                result = contest.get("result", "TBD")
                date = contest.get("date", "N/A")
                print(f"        {date[:10]} vs {opponent}: {result}")

        except Exception as e:
            print(f"    ✗ Error fetching schedule: {str(e)}")

    # Step 5: Get national rankings
    print("\n[5] Checking national basketball rankings...")
    try:
        rankings = client.get_rankings("basketball", "national")
        title = rankings.get("data", {}).get("title", "Rankings")
        ranked_teams = rankings.get("data", {}).get("rankings", [])

        print(f"\n    {title}")
        print("      Top 10 Teams:")
        for team in ranked_teams[:10]:
            rank = team.get("rank")
            name = team.get("schoolName")
            state = team.get("stateCode")
            record = team.get("overall", "N/A")
            movement = team.get("movement", "--")
            print(f"      {rank:2d}. {name:30s} ({state}) - {record} {movement}")

    except Exception as e:
        print(f"    ✗ Error fetching rankings: {str(e)}")

    print("\n" + "=" * 70)
    print("Scout analysis complete!")
    print("=" * 70)
All endpoints · 5 totalmissing one? ·

Search for schools by name or query. Returns matching schools with their IDs, locations, mascots, and paths for use in other endpoints.

Input
ParamTypeDescription
queryrequiredstringSchool name or search query (e.g., 'Oak Hill Academy', 'Mater Dei')
Response
{
  "type": "object",
  "fields": {
    "schools": "array of school objects with school_id, name, city, state, mascot, url, and path"
  },
  "sample": {
    "data": {
      "schools": [
        {
          "url": "https://www.maxpreps.com/va/mouth-of-wilson/oak-hill-academy-warriors/",
          "city": "Mouth of Wilson",
          "name": "Oak Hill Academy",
          "path": "/va/mouth-of-wilson/oak-hill-academy-warriors/",
          "state": "VA",
          "mascot": "Warriors",
          "school_id": "f80db136-2ddf-4840-8835-c02f4785634d"
        }
      ]
    },
    "status": "success"
  }
}

About the MaxPreps API

School and Team Data

Start with search_schools to find any high school by name or partial query. Each result includes a school_id, name, city, state, mascot, and a path used as the base input for team endpoints. Append a sport to that path and pass it to get_team_roster or get_team_schedule. Both endpoints accept an optional season parameter in YY-YY format (e.g., 24-25) so you can pull historical data beyond the current year.

Rosters and Athlete Profiles

get_team_roster returns a roster array where each player object includes career_id, athlete_id, first_name, last_name, jersey, position, height, grade, and a photo_url. The career_id from this response is the required input for get_athlete_profile, which returns a timeline of events (articles, stat updates, game results), club_teams, season-by-season career_data with stats and awards, and a prospect_report object — or null if no prospect rating exists for that athlete.

Schedules and Rankings

get_team_schedule returns a contests array with date, home_team, away_team, opponent, and result fields, plus a separate tournaments array for postseason play. get_rankings accepts a sport string and an optional state code (e.g., ca, tx) or the literal string national. Each ranking object includes rank, schoolId, schoolName, stateCode, overall record, teamLink, and a movement indicator showing week-over-week rank change.

Reliability & maintenance

The MaxPreps API is a managed, monitored endpoint for maxpreps.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when maxpreps.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.

This isn't an official maxpreps.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.

Will this API break when the source site changes?+
It's built not to. Every endpoint is health-checked on a schedule with automated test probes. When the source site changes and a check fails, the API is automatically queued for repair and re-verified — that's the self-healing layer. Each API page shows when its endpoints were last verified. And because marketplace APIs are shared, any fix reaches everyone using it.
Is this an official API from the source site?+
No — Parse APIs are independent, managed REST wrappers over publicly available data. That is the point: where a site has no official API (or only a limited one), Parse gives you a maintained, monitored endpoint for that data and keeps it working as the site changes — so you get a stable contract over a source that never promised one.
Can I fix or extend this API myself if I need a new endpoint or field?+
Yes — and you don't have to wait on us. This API was generated by the Parse agent, which stays attached. Describe the change in plain English ("add an endpoint that returns reviews", "fix the price field") in the revise box on the API page or via the revise_api MCP tool, and the agent rebuilds it against the live site in minutes. Contributing the change back to the public API is free.
What happens if I call an endpoint that has an issue?+
Errors are machine-readable: a bad call returns a clean status with the list of available endpoints and a repair hint, so an agent (or you) can recover or trigger a fix instead of failing silently. Confirmed failures feed the automatic repair queue.
Common use cases
  • Build a high school football recruiting tracker using get_athlete_profile career stats and prospect_report ratings.
  • Generate automated weekly rankings digests by polling get_rankings with sport and state parameters.
  • Power a school sports directory by combining search_schools results with roster data from get_team_roster.
  • Track season results for a specific team by pulling get_team_schedule contests with scores and opponent names.
  • Compare rosters across seasons by calling get_team_roster with different YY-YY season values for the same team path.
  • Identify club team affiliations for recruited athletes using the club_teams field in get_athlete_profile.
  • Display per-player grade and position breakdowns for any high school team using the get_team_roster response fields.
Pricing & limitsSee full pricing →
TierPriceCredits/monthRate limit
Free$0/mo1005 req/min
Hobby$30/mo1,00020 req/min
Developer$100/mo5,000100 req/min

One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.

Frequently asked questions
Does MaxPreps have an official public developer API?+
MaxPreps does not publish a public developer API. Access to structured sports data requires using a third-party API like this one.
What does the `get_athlete_profile` endpoint return beyond basic bio info?+
It returns a timeline array of event objects (articles, stat updates, and game results), a career_data array with season-by-season stats and awards, club_teams affiliations, and a prospect_report object containing prospect rating data — or null if no rating is available for that athlete.
Can I retrieve play-by-play or box score data for individual games?+
Not currently. The API covers schedule results (scores, win/loss, opponent) via get_team_schedule and career-level stats via get_athlete_profile, but individual game box scores are not exposed. You can fork this API on Parse and revise it to add a game-level box score endpoint.
Does `get_rankings` support all sports, or only the major ones?+
The sport parameter accepts string values like basketball, football, baseball, and volleyball. Coverage depends on what MaxPreps publishes rankings for, so niche or regional sports with limited ranking data may return sparse results.
Is there pagination support for large rosters or long schedules?+
The endpoints return full roster and schedule data in a single response without explicit pagination parameters. For schools with unusually large rosters or long seasons, all available records are returned in the single call.
Page content last updated . Spec covers 5 endpoints from maxpreps.com.
Related APIs in SportsSee all →
athletic.net API
Search and analyze cross country and track & field performance data across the US, including athlete profiles, meet results, team rosters, and rankings. Access comprehensive meet information, historical records, and state-level competition data to track athlete progress and discover top performers.
stats.ncaa.org API
Access comprehensive NCAA sports statistics to search for players, teams, and coaches, view game box scores and play-by-play data, and review team schedules, rosters, and rankings. Get detailed head coach records and scoreboard information to analyze performance across college sports.
espn.com API
Get live scores, schedules, standings, teams, rosters, athlete profiles, game logs, and league news across major sports from ESPN.
milesplit.com API
Access high school track and field rankings from MileSplit by state, event, and year. Retrieve team-level standings for relay events and individual athlete rankings for sprint and distance events across all US states.
nikeeyblscholastic.com API
Access comprehensive Nike EYBL Scholastic basketball league data including teams, player bios, schedules, standings, and detailed game box scores. Track team rosters, player statistics, and season performance across the entire league in one place.
insidelacrosse.com API
Access lacrosse game scores, schedules, and detailed statistics from InsideLacrosse.com. Retrieve results by date, gender, division, and season, and drill into individual game box scores including team and player performance data.
ncaaf.com API
Access comprehensive college football data to get live scores, team schedules, player statistics, and game details across the NCAAF. Track rankings, compare team rosters, analyze betting odds and spreads, and explore historical results and trends to stay informed on college football.
baseball-reference.com API
Access comprehensive MLB and college baseball (NCAA Division I) statistics from Baseball-Reference. Retrieve player career and season stats, team rosters and performance data, game box scores, season schedules, league leaders, and college conference standings — all from a single API.