NAV
shell javascript python

PGA API

Welcome to the BALLDONTLIE PGA API, your comprehensive source for PGA Tour data. This API provides access to player information, tournament results, course details, leaderboards, round-by-round statistics, strokes gained metrics, and detailed scorecards. An API key is required. You can obtain an API key by creating a free account on our website. Read the authentication section to learn how to use the API key.

Take a look at our other APIs.

Join us on discord.

AI-Powered Integration

Using the OpenAPI Specification with AI

Our complete OpenAPI specification allows AI assistants to automatically understand and interact with our API. Simply share the spec URL with your AI assistant and describe what you want to build—the AI will handle the technical implementation.

Getting Started with AI:

  1. Copy this URL: https://www.balldontlie.io/openapi.yml
  2. Share it with your preferred AI assistant (ChatGPT, Claude, Gemini, etc.)
  3. Tell the AI what you want to build (e.g., "Create a dashboard showing FedEx Cup standings")
  4. The AI will read the OpenAPI spec and write the code for you

Example prompts to try:

This makes it incredibly easy for non-technical users, analysts, and researchers to leverage our PGA data without needing to learn programming from scratch.

Account Tiers

There are three different account tiers which provide you access to different types of data. Visit our website to create an account for free.

Paid tiers do not apply across sports. The tier you purchase for PGA will not automatically be applied to other sports. You can purchase the ALL-ACCESS ($299.99/mo) tier to get access to every endpoint for every sport.

Read the table below to see the breakdown.

Endpoint Free ALL-STAR GOAT
Players Yes Yes Yes
Tournaments Yes Yes Yes
Courses Yes Yes Yes
Tournament Results No Yes Yes
Tournament Course Stats No Yes Yes
Course Holes No Yes Yes
Player Round Results No No Yes
Player Round Stats No No Yes
Player Season Stats No No Yes
Player Scorecards No No Yes

The feature breakdown per tier is shown in the table below.

Tier Requests / Min $USD / mo.
GOAT 600 39.99
ALL-STAR 60 9.99
Free 5 0

Authentication

To authorize, use this code:

curl "api_endpoint_here" -H "Authorization: YOUR_API_KEY"
const response = await fetch("https://api.balldontlie.io/pga/v1/players", {
  headers: {
    Authorization: "YOUR_API_KEY",
  },
});
const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://api.balldontlie.io/pga/v1/players',
    headers={'Authorization': 'YOUR_API_KEY'}
)

if response.status_code == 200:
    data = response.json()
    print(data)
else:
    print(f'Error: {response.status_code}')

Make sure to replace YOUR_API_KEY with your API key.

BALLDONTLIE uses API keys to allow access to the API. You can obtain an API key by creating a free account at our website

We expect the API key to be included in all API requests to the server in a header that looks like the following:

Authorization: YOUR_API_KEY

Pagination

This API uses cursor based pagination rather than limit/offset. Endpoints that support pagination will send back responses with a meta key that looks like what is displayed on the right.

{
  "meta": {
    "next_cursor": 90,
    "per_page": 25
  }
}

You can use per_page to specify the maximum number of results. It defaults to 25 and doesn't allow values larger than 100.

You can use next_cursor to get the next page of results. Specify it in the request parameters like this: ?cursor=NEXT_CURSOR.

Errors

The API uses the following error codes:

Error Code Meaning
401 Unauthorized - You either need an API key or your account tier does not have access to the endpoint.
400 Bad Request -- The request is invalid. The request parameters are probably incorrect.
404 Not Found -- The specified resource could not be found.
406 Not Acceptable -- You requested a format that isn't json.
429 Too Many Requests -- You're rate limited.
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.

Players

Get All Players

curl "https://api.balldontlie.io/pga/v1/players?per_page=2" \
  -H "Authorization: YOUR_API_KEY"
const response = await fetch(
  "https://api.balldontlie.io/pga/v1/players?per_page=2",
  {
    headers: {
      Authorization: "YOUR_API_KEY",
    },
  }
);
const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://api.balldontlie.io/pga/v1/players',
    headers={'Authorization': 'YOUR_API_KEY'},
    params={'per_page': 2}
)

players = response.json()['data']
for player in players:
    print(f"{player['display_name']} ({player['country']})")

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": 1,
      "first_name": "Ludvig",
      "last_name": "Åberg",
      "display_name": "Ludvig Åberg",
      "country": "Sweden",
      "country_code": "SWE",
      "height": "6'3\"",
      "weight": "190",
      "birth_date": "Oct 31, 1999",
      "birthplace_city": "Eslov",
      "birthplace_state": null,
      "birthplace_country": "Sweden",
      "turned_pro": "2023",
      "school": "Texas Tech University",
      "residence_city": "Ponte Vedra",
      "residence_state": "Florida",
      "residence_country": "United States",
      "owgr": 18,
      "active": true
    },
    {
      "id": 2,
      "first_name": "Byeong Hun",
      "last_name": "An",
      "display_name": "Byeong Hun An",
      "country": "Republic of Korea",
      "country_code": "KOR",
      "height": "6'2\"",
      "weight": "240",
      "birth_date": "Sep 17, 1991",
      "birthplace_city": "Seoul",
      "birthplace_state": null,
      "birthplace_country": "South Korea",
      "turned_pro": "2011",
      "school": "University of California-Berkeley",
      "residence_city": "Orlando",
      "residence_state": "Florida",
      "residence_country": "United States",
      "owgr": 98,
      "active": true
    }
  ],
  "meta": {
    "next_cursor": 2,
    "per_page": 2
  }
}

This endpoint retrieves PGA Tour players.

HTTP Request

GET https://api.balldontlie.io/pga/v1/players

Query Parameters

Parameter Type Required Description
player_ids integer[] No Filter by player IDs
search string No Search players by name
first_name string No Filter by first name
last_name string No Filter by last name
country string No Filter by country
active boolean No Filter by active status
cursor integer No Pagination cursor
per_page integer No Results per page (max 100, default 25)

Tournaments

Get All Tournaments

curl "https://api.balldontlie.io/pga/v1/tournaments?season=2025&per_page=2" \
  -H "Authorization: YOUR_API_KEY"
const response = await fetch(
  "https://api.balldontlie.io/pga/v1/tournaments?season=2025&per_page=2",
  {
    headers: {
      Authorization: "YOUR_API_KEY",
    },
  }
);
const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://api.balldontlie.io/pga/v1/tournaments',
    headers={'Authorization': 'YOUR_API_KEY'},
    params={'season': 2025, 'per_page': 2}
)

tournaments = response.json()['data']
for tournament in tournaments:
    print(f"{tournament['name']} - {tournament['start_date']}")

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": 6,
      "season": 2025,
      "name": "The Sentry",
      "start_date": "2025-01-01T19:00:00.000Z",
      "end_date": "Jan 2 - 5",
      "city": "Kapalua, Maui",
      "state": "Hawaii",
      "country": "United States of America",
      "course_name": "Plantation Course at Kapalua",
      "purse": "$20,000,000",
      "status": "COMPLETED",
      "champion": {
        "id": 130,
        "first_name": "Hideki",
        "last_name": "Matsuyama",
        "display_name": "Hideki Matsuyama",
        "country": "Japan",
        "country_code": "JPN",
        "active": true
      }
    },
    {
      "id": 46,
      "season": 2025,
      "name": "Sony Open in Hawaii",
      "start_date": "2025-01-08T19:00:00.000Z",
      "end_date": "Jan 9 - 12",
      "city": "Honolulu",
      "state": "Hawaii",
      "country": "United States of America",
      "course_name": "Waialae Country Club",
      "purse": "$8,700,000",
      "status": "IN_PROGRESS",
      "champion": null
    }
  ],
  "meta": {
    "next_cursor": 46,
    "per_page": 2
  }
}

This endpoint retrieves PGA Tour tournaments.

HTTP Request

GET https://api.balldontlie.io/pga/v1/tournaments

Query Parameters

Parameter Type Required Description
tournament_ids integer[] No Filter by tournament IDs
season integer No Filter by season year
status string No Filter by status (COMPLETED, IN_PROGRESS, SCHEDULED)
cursor integer No Pagination cursor
per_page integer No Results per page (max 100, default 25)

Courses

Get All Courses

curl "https://api.balldontlie.io/pga/v1/courses?per_page=2" \
  -H "Authorization: YOUR_API_KEY"
const response = await fetch(
  "https://api.balldontlie.io/pga/v1/courses?per_page=2",
  {
    headers: {
      Authorization: "YOUR_API_KEY",
    },
  }
);
const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://api.balldontlie.io/pga/v1/courses',
    headers={'Authorization': 'YOUR_API_KEY'},
    params={'per_page': 2}
)

courses = response.json()['data']
for course in courses:
    print(f"{course['name']} - Par {course['par']}, {course['yardage']} yards")

The above command returns JSON structured like this:

{
  "data": [
    {
      "id": 1,
      "name": "TPC River Highlands",
      "city": "Cromwell",
      "state": "Connecticut",
      "country": "USA",
      "par": 70,
      "yardage": "6,844",
      "established": "1928",
      "architect": "Robert J. Ross/Maurice Kearney",
      "fairway_grass": "Creeping Bentgrass/Poa Annua",
      "rough_grass": "Bluegrass/Ryegrass",
      "green_grass": "Poa annua"
    },
    {
      "id": 2,
      "name": "Tiburón Golf Club",
      "city": "Naples",
      "state": "Florida",
      "country": "USA",
      "par": 72,
      "yardage": "7,382",
      "established": "1998",
      "architect": "Greg Norman",
      "fairway_grass": "Bermudagrass",
      "rough_grass": null,
      "green_grass": "Bermudagrass"
    }
  ],
  "meta": {
    "next_cursor": 2,
    "per_page": 2
  }
}

This endpoint retrieves golf courses used in PGA Tour events.

HTTP Request

GET https://api.balldontlie.io/pga/v1/courses

Query Parameters

Parameter Type Required Description
course_ids integer[] No Filter by course IDs
search string No Search courses by name
cursor integer No Pagination cursor
per_page integer No Results per page (max 100, default 25)

Tournament Results

Get Tournament Results

curl "https://api.balldontlie.io/pga/v1/tournament_results?tournament_ids[]=1201&per_page=3" \
  -H "Authorization: YOUR_API_KEY"
const response = await fetch(
  "https://api.balldontlie.io/pga/v1/tournament_results?tournament_ids[]=1201&per_page=3",
  {
    headers: {
      Authorization: "YOUR_API_KEY",
    },
  }
);
const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://api.balldontlie.io/pga/v1/tournament_results',
    headers={'Authorization': 'YOUR_API_KEY'},
    params={'tournament_ids[]': 1201, 'per_page': 3}
)

results = response.json()['data']
for result in results:
    player = result['player']
    print(f"{result['position']} - {player['display_name']}: {result['par_relative_score']}")

The above command returns JSON structured like this:

{
  "data": [
    {
      "tournament": {
        "id": 6,
        "season": 2025,
        "name": "The Sentry",
        "start_date": "2025-01-01T19:00:00.000Z",
        "end_date": "Jan 2 - 5",
        "status": "COMPLETED"
      },
      "player": {
        "id": 130,
        "first_name": "Hideki",
        "last_name": "Matsuyama",
        "display_name": "Hideki Matsuyama",
        "country": "Japan",
        "country_code": "JPN",
        "active": true
      },
      "position": "1",
      "position_numeric": 1,
      "total_score": 257,
      "par_relative_score": -35
    },
    {
      "tournament": {
        "id": 6,
        "season": 2025,
        "name": "The Sentry",
        "start_date": "2025-01-01T19:00:00.000Z",
        "end_date": "Jan 2 - 5",
        "status": "COMPLETED"
      },
      "player": {
        "id": 142,
        "first_name": "Collin",
        "last_name": "Morikawa",
        "display_name": "Collin Morikawa",
        "country": "United States",
        "country_code": "USA",
        "active": true
      },
      "position": "2",
      "position_numeric": 2,
      "total_score": 260,
      "par_relative_score": -32
    },
    {
      "tournament": {
        "id": 6,
        "season": 2025,
        "name": "The Sentry",
        "start_date": "2025-01-01T19:00:00.000Z",
        "end_date": "Jan 2 - 5",
        "status": "COMPLETED"
      },
      "player": {
        "id": 93,
        "first_name": "Sungjae",
        "last_name": "Im",
        "display_name": "Sungjae Im",
        "country": "Republic of Korea",
        "country_code": "KOR",
        "active": true
      },
      "position": "3",
      "position_numeric": 3,
      "total_score": 263,
      "par_relative_score": -29
    }
  ],
  "meta": {
    "next_cursor": 809,
    "per_page": 3
  }
}

This endpoint retrieves tournament leaderboards and final results. Requires ALL-STAR tier or higher.

HTTP Request

GET https://api.balldontlie.io/pga/v1/tournament_results

Query Parameters

Parameter Type Required Description
tournament_ids integer[] No Filter by tournament IDs
player_ids integer[] No Filter by player IDs
season integer No Filter by season year
cursor integer No Pagination cursor
per_page integer No Results per page (max 100, default 25)

Tournament Course Stats

Get Tournament Course Stats

curl "https://api.balldontlie.io/pga/v1/tournament_course_stats?tournament_ids[]=1201&per_page=3" \
  -H "Authorization: YOUR_API_KEY"
const response = await fetch(
  "https://api.balldontlie.io/pga/v1/tournament_course_stats?tournament_ids[]=1201&per_page=3",
  {
    headers: {
      Authorization: "YOUR_API_KEY",
    },
  }
);
const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://api.balldontlie.io/pga/v1/tournament_course_stats',
    headers={'Authorization': 'YOUR_API_KEY'},
    params={'tournament_ids[]': 1201, 'per_page': 3}
)

stats = response.json()['data']
for stat in stats:
    print(f"Hole {stat['hole_number']}: Avg {stat['scoring_average']} (Difficulty Rank: {stat['difficulty_rank']})")

The above command returns JSON structured like this:

{
  "data": [
    {
      "tournament": {
        "id": 6,
        "season": 2025,
        "name": "The Sentry",
        "start_date": "2025-01-01T19:00:00.000Z",
        "end_date": "Jan 2 - 5",
        "status": "COMPLETED"
      },
      "course": {
        "id": 56,
        "name": "Plantation Course at Kapalua",
        "city": "Kapalua, Maui",
        "state": "Hawaii",
        "country": "USA",
        "par": 73
      },
      "hole_number": 1,
      "round_number": null,
      "scoring_average": 4.111,
      "scoring_diff": 0.111,
      "difficulty_rank": 1,
      "eagles": 0,
      "birdies": 17,
      "pars": 178,
      "bogeys": 38,
      "double_bogeys": 1
    },
    {
      "tournament": {
        "id": 6,
        "season": 2025,
        "name": "The Sentry",
        "start_date": "2025-01-01T19:00:00.000Z",
        "end_date": "Jan 2 - 5",
        "status": "COMPLETED"
      },
      "course": {
        "id": 56,
        "name": "Plantation Course at Kapalua",
        "city": "Kapalua, Maui",
        "state": "Hawaii",
        "country": "USA",
        "par": 73
      },
      "hole_number": 1,
      "round_number": 4,
      "scoring_average": 4.103,
      "scoring_diff": 0.103,
      "difficulty_rank": 1,
      "eagles": 0,
      "birdies": 4,
      "pars": 44,
      "bogeys": 10,
      "double_bogeys": 0
    },
    {
      "tournament": {
        "id": 6,
        "season": 2025,
        "name": "The Sentry",
        "start_date": "2025-01-01T19:00:00.000Z",
        "end_date": "Jan 2 - 5",
        "status": "COMPLETED"
      },
      "course": {
        "id": 56,
        "name": "Plantation Course at Kapalua",
        "city": "Kapalua, Maui",
        "state": "Hawaii",
        "country": "USA",
        "par": 73
      },
      "hole_number": 1,
      "round_number": 3,
      "scoring_average": 4.051,
      "scoring_diff": 0.051,
      "difficulty_rank": 1,
      "eagles": 0,
      "birdies": 5,
      "pars": 46,
      "bogeys": 8,
      "double_bogeys": 0
    }
  ],
  "meta": {
    "next_cursor": 4843,
    "per_page": 3
  }
}

This endpoint retrieves hole-by-hole statistics for tournaments, including scoring averages, difficulty rankings, and score distribution. Requires ALL-STAR tier or higher.

HTTP Request

GET https://api.balldontlie.io/pga/v1/tournament_course_stats

Query Parameters

Parameter Type Required Description
tournament_ids integer[] No Filter by tournament IDs
course_ids integer[] No Filter by course IDs
hole_number integer No Filter by hole number (1-18)
round_number integer No Filter by round number (1-4)
cursor integer No Pagination cursor
per_page integer No Results per page (max 100, default 25)

Course Holes

Get Course Holes

curl "https://api.balldontlie.io/pga/v1/course_holes?course_ids[]=45&per_page=3" \
  -H "Authorization: YOUR_API_KEY"
const response = await fetch(
  "https://api.balldontlie.io/pga/v1/course_holes?course_ids[]=45&per_page=3",
  {
    headers: {
      Authorization: "YOUR_API_KEY",
    },
  }
);
const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://api.balldontlie.io/pga/v1/course_holes',
    headers={'Authorization': 'YOUR_API_KEY'},
    params={'course_ids[]': 45, 'per_page': 3}
)

holes = response.json()['data']
for hole in holes:
    print(f"Hole {hole['hole_number']}: Par {hole['par']}, {hole['yardage']} yards")

The above command returns JSON structured like this:

{
  "data": [
    {
      "course": {
        "id": 1,
        "name": "TPC River Highlands",
        "city": "Cromwell",
        "state": "Connecticut",
        "country": "USA",
        "par": 70
      },
      "hole_number": 1,
      "par": 4,
      "yardage": 434
    },
    {
      "course": {
        "id": 1,
        "name": "TPC River Highlands",
        "city": "Cromwell",
        "state": "Connecticut",
        "country": "USA",
        "par": 70
      },
      "hole_number": 2,
      "par": 4,
      "yardage": 341
    },
    {
      "course": {
        "id": 1,
        "name": "TPC River Highlands",
        "city": "Cromwell",
        "state": "Connecticut",
        "country": "USA",
        "par": 70
      },
      "hole_number": 3,
      "par": 4,
      "yardage": 431
    }
  ],
  "meta": {
    "next_cursor": 3,
    "per_page": 3
  }
}

This endpoint retrieves hole-by-hole course information including par and yardage. Requires ALL-STAR tier or higher.

HTTP Request

GET https://api.balldontlie.io/pga/v1/course_holes

Query Parameters

Parameter Type Required Description
course_ids integer[] No Filter by course IDs
hole_number integer No Filter by hole number (1-18)
cursor integer No Pagination cursor
per_page integer No Results per page (max 100, default 25)

Player Round Results

Get Player Round Results

curl "https://api.balldontlie.io/pga/v1/player_round_results?tournament_ids[]=1201&player_ids[]=5467" \
  -H "Authorization: YOUR_API_KEY"
const response = await fetch(
  "https://api.balldontlie.io/pga/v1/player_round_results?tournament_ids[]=1201&player_ids[]=5467",
  {
    headers: {
      Authorization: "YOUR_API_KEY",
    },
  }
);
const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://api.balldontlie.io/pga/v1/player_round_results',
    headers={'Authorization': 'YOUR_API_KEY'},
    params={'tournament_ids[]': 1201, 'player_ids[]': 5467}
)

results = response.json()['data']
for result in results:
    print(f"Round {result['round_number']}: {result['score']} ({result['par_relative_score']})")

The above command returns JSON structured like this:

{
  "data": [
    {
      "tournament": {
        "id": 6,
        "season": 2025,
        "name": "The Sentry",
        "start_date": "2025-01-01T19:00:00.000Z",
        "end_date": "Jan 2 - 5",
        "status": "COMPLETED"
      },
      "player": {
        "id": 130,
        "first_name": "Hideki",
        "last_name": "Matsuyama",
        "display_name": "Hideki Matsuyama",
        "country": "Japan",
        "country_code": "JPN",
        "active": true
      },
      "round_number": 1,
      "score": 65,
      "par_relative_score": -8
    },
    {
      "tournament": {
        "id": 6,
        "season": 2025,
        "name": "The Sentry",
        "start_date": "2025-01-01T19:00:00.000Z",
        "end_date": "Jan 2 - 5",
        "status": "COMPLETED"
      },
      "player": {
        "id": 142,
        "first_name": "Collin",
        "last_name": "Morikawa",
        "display_name": "Collin Morikawa",
        "country": "United States",
        "country_code": "USA",
        "active": true
      },
      "round_number": 1,
      "score": 66,
      "par_relative_score": -7
    },
    {
      "tournament": {
        "id": 6,
        "season": 2025,
        "name": "The Sentry",
        "start_date": "2025-01-01T19:00:00.000Z",
        "end_date": "Jan 2 - 5",
        "status": "COMPLETED"
      },
      "player": {
        "id": 93,
        "first_name": "Sungjae",
        "last_name": "Im",
        "display_name": "Sungjae Im",
        "country": "Republic of Korea",
        "country_code": "KOR",
        "active": true
      },
      "round_number": 1,
      "score": 69,
      "par_relative_score": -4
    }
  ],
  "meta": {
    "next_cursor": 11698,
    "per_page": 3
  }
}

This endpoint retrieves round-by-round player scores. Requires GOAT tier.

HTTP Request

GET https://api.balldontlie.io/pga/v1/player_round_results

Query Parameters

Parameter Type Required Description
tournament_ids integer[] No Filter by tournament IDs
player_ids integer[] No Filter by player IDs
round_number integer No Filter by round number (1-4)
season integer No Filter by season year
cursor integer No Pagination cursor
per_page integer No Results per page (max 100, default 25)

Player Round Stats

Get Player Round Stats

curl "https://api.balldontlie.io/pga/v1/player_round_stats?tournament_ids[]=1201&player_ids[]=5467&round_number=-1" \
  -H "Authorization: YOUR_API_KEY"
const response = await fetch(
  "https://api.balldontlie.io/pga/v1/player_round_stats?tournament_ids[]=1201&player_ids[]=5467&round_number=-1",
  {
    headers: {
      Authorization: "YOUR_API_KEY",
    },
  }
);
const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://api.balldontlie.io/pga/v1/player_round_stats',
    headers={'Authorization': 'YOUR_API_KEY'},
    params={'tournament_ids[]': 1201, 'player_ids[]': 5467, 'round_number': -1}
)

stats = response.json()['data']
for stat in stats:
    print(f"SG Total: {stat['sg_total']}")
    print(f"SG Off Tee: {stat['sg_off_tee']}")
    print(f"SG Approach: {stat['sg_approach']}")
    print(f"SG Putting: {stat['sg_putting']}")

The above command returns JSON structured like this:

{
  "data": [
    {
      "tournament": {
        "id": 6,
        "season": 2025,
        "name": "The Sentry",
        "start_date": "2025-01-01T19:00:00.000Z",
        "end_date": "Jan 2 - 5",
        "status": "COMPLETED"
      },
      "player": {
        "id": 189,
        "first_name": "Adam",
        "last_name": "Scott",
        "display_name": "Adam Scott",
        "country": "Australia",
        "country_code": "AUS",
        "active": true
      },
      "round_number": -1,
      "sg_off_tee": -1.26,
      "sg_off_tee_rank": 46,
      "sg_approach": 3.792,
      "sg_approach_rank": 9,
      "sg_around_green": 1.427,
      "sg_around_green_rank": 10,
      "sg_putting": 0.019,
      "sg_putting_rank": 28,
      "sg_total": 3.978,
      "sg_total_rank": 15,
      "driving_accuracy": 60,
      "driving_accuracy_rank": 46,
      "driving_distance": 282.4,
      "driving_distance_rank": 27,
      "longest_drive": 375,
      "longest_drive_rank": 54,
      "greens_in_regulation": 81.94,
      "greens_in_regulation_rank": 27,
      "sand_saves": 33.33,
      "sand_saves_rank": 24,
      "scrambling": 46.15,
      "scrambling_rank": 48,
      "putts_per_gir": 1.64,
      "putts_per_gir_rank": 10,
      "eagles": null,
      "birdies": 29,
      "pars": 35,
      "bogeys": 8,
      "double_bogeys": null
    }
  ],
  "meta": {
    "next_cursor": 33023,
    "per_page": 1
  }
}

This endpoint retrieves detailed player round statistics including strokes gained metrics, driving accuracy, greens in regulation, and more. Use round_number=-1 for tournament totals. Requires GOAT tier.

HTTP Request

GET https://api.balldontlie.io/pga/v1/player_round_stats

Query Parameters

Parameter Type Required Description
tournament_ids integer[] No Filter by tournament IDs
player_ids integer[] No Filter by player IDs
round_number integer No Filter by round number (1-4, -1 for tournament total)
season integer No Filter by season year
cursor integer No Pagination cursor
per_page integer No Results per page (max 100, default 25)

Player Season Stats

Get Player Season Stats

curl "https://api.balldontlie.io/pga/v1/player_season_stats?player_ids[]=5467&season=2024&per_page=5" \
  -H "Authorization: YOUR_API_KEY"
const response = await fetch(
  "https://api.balldontlie.io/pga/v1/player_season_stats?player_ids[]=5467&season=2024&per_page=5",
  {
    headers: {
      Authorization: "YOUR_API_KEY",
    },
  }
);
const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://api.balldontlie.io/pga/v1/player_season_stats',
    headers={'Authorization': 'YOUR_API_KEY'},
    params={'player_ids[]': 5467, 'season': 2024, 'per_page': 5}
)

stats = response.json()['data']
for stat in stats:
    print(f"{stat['stat_name']}: Rank {stat['rank']}")

The above command returns JSON structured like this:

{
  "data": [
    {
      "player": {
        "id": 185,
        "first_name": "Scottie",
        "last_name": "Scheffler",
        "display_name": "Scottie Scheffler",
        "country": "United States",
        "country_code": "USA",
        "active": true
      },
      "stat_id": 8,
      "stat_name": "SG: Total",
      "stat_category": "STROKES_GAINED",
      "season": 2025,
      "rank": 1,
      "stat_value": [
        { "statName": "Avg", "statValue": "2.743" },
        { "statName": "Total SG:T", "statValue": "197.507" },
        { "statName": "Total SG:T2G", "statValue": "169.995" },
        { "statName": "Total SG:P", "statValue": "27.512" },
        { "statName": "Measured Rounds", "statValue": "72" }
      ]
    },
    {
      "player": {
        "id": 185,
        "first_name": "Scottie",
        "last_name": "Scheffler",
        "display_name": "Scottie Scheffler",
        "country": "United States",
        "country_code": "USA",
        "active": true
      },
      "stat_id": 9,
      "stat_name": "SG: Tee-to-Green",
      "stat_category": "STROKES_GAINED",
      "season": 2025,
      "rank": 1,
      "stat_value": [
        { "statName": "Avg", "statValue": "2.361" },
        { "statName": "SG:OTT", "statValue": "0.748" },
        { "statName": "SG:APR", "statValue": "1.291" },
        { "statName": "SG:ARG", "statValue": "0.322" },
        { "statName": "Measured Rounds", "statValue": "72" }
      ]
    },
    {
      "player": {
        "id": 31,
        "first_name": "Pierceson",
        "last_name": "Coody",
        "display_name": "Pierceson Coody",
        "country": "United States",
        "country_code": "USA",
        "active": true
      },
      "stat_id": 10,
      "stat_name": "SG: Off-the-Tee",
      "stat_category": "STROKES_GAINED",
      "season": 2025,
      "rank": 1,
      "stat_value": [
        { "statName": "Avg", "statValue": "0.789" },
        { "statName": "Total SG:OTT", "statValue": "26.812" },
        { "statName": "Measured Rounds", "statValue": "34" }
      ]
    }
  ],
  "meta": {
    "next_cursor": 20770,
    "per_page": 3
  }
}

This endpoint retrieves player season-level statistics across various categories. Requires GOAT tier.

HTTP Request

GET https://api.balldontlie.io/pga/v1/player_season_stats

Query Parameters

Parameter Type Required Description
player_ids integer[] No Filter by player IDs
season integer No Filter by season year
stat_ids integer[] No Filter by stat IDs
cursor integer No Pagination cursor
per_page integer No Results per page (max 100, default 25)

Available Stat Categories

There are 493 different statistics available, organized into the following categories:

Category Description Example Stats
STROKES_GAINED Strokes gained metrics SG: Total, SG: Tee-to-Green, SG: Off-the-Tee, SG: Approach the Green, SG: Around-the-Green, SG: Putting
OFF_TEE Driving statistics Driving Distance, Driving Accuracy Percentage, Club Head Speed, Ball Speed, Launch Angle
APPROACH_GREEN Approach shot metrics Approach from various distances (50-275+ yards), Greens in Regulation
AROUND_GREEN Short game statistics Sand Save Percentage, Scrambling, Up and Down Percentage
PUTTING Putting metrics Putts per Round, 3-Putt Avoidance, Putting from various distances
SCORING Scoring statistics Scoring Average, Birdie Average, Par Breakers, Final Round Scoring
MONEY_FINISHES Earnings and finishes Official Money, Top 10 Finishes, Wins
POINTS_RANKINGS Rankings and points FedEx Cup Points, World Golf Ranking
STREAKS Consecutive statistics Consecutive Cuts Made, Consecutive Birdies

Player Scorecards

Get Player Scorecards

curl "https://api.balldontlie.io/pga/v1/player_scorecards?tournament_ids[]=1201&player_ids[]=5467&round_number=1&per_page=3" \
  -H "Authorization: YOUR_API_KEY"
const response = await fetch(
  "https://api.balldontlie.io/pga/v1/player_scorecards?tournament_ids[]=1201&player_ids[]=5467&round_number=1&per_page=3",
  {
    headers: {
      Authorization: "YOUR_API_KEY",
    },
  }
);
const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://api.balldontlie.io/pga/v1/player_scorecards',
    headers={'Authorization': 'YOUR_API_KEY'},
    params={'tournament_ids[]': 1201, 'player_ids[]': 5467, 'round_number': 1, 'per_page': 3}
)

scorecard = response.json()['data']
for hole in scorecard:
    print(f"Hole {hole['hole_number']}: {hole['score']} (Par {hole['par']})")

The above command returns JSON structured like this:

{
  "data": [
    {
      "tournament": {
        "id": 6,
        "season": 2025,
        "name": "The Sentry",
        "start_date": "2025-01-01T19:00:00.000Z",
        "end_date": "Jan 2 - 5",
        "status": "COMPLETED"
      },
      "player": {
        "id": 189,
        "first_name": "Adam",
        "last_name": "Scott",
        "display_name": "Adam Scott",
        "country": "Australia",
        "country_code": "AUS",
        "active": true
      },
      "round_number": 1,
      "hole_number": 1,
      "par": 4,
      "score": 4
    },
    {
      "tournament": {
        "id": 6,
        "season": 2025,
        "name": "The Sentry",
        "start_date": "2025-01-01T19:00:00.000Z",
        "end_date": "Jan 2 - 5",
        "status": "COMPLETED"
      },
      "player": {
        "id": 213,
        "first_name": "Nick",
        "last_name": "Taylor",
        "display_name": "Nick Taylor",
        "country": "Canada",
        "country_code": "CAN",
        "active": true
      },
      "round_number": 1,
      "hole_number": 1,
      "par": 4,
      "score": 4
    },
    {
      "tournament": {
        "id": 6,
        "season": 2025,
        "name": "The Sentry",
        "start_date": "2025-01-01T19:00:00.000Z",
        "end_date": "Jan 2 - 5",
        "status": "COMPLETED"
      },
      "player": {
        "id": 223,
        "first_name": "Jhonattan",
        "last_name": "Vegas",
        "display_name": "Jhonattan Vegas",
        "country": "Venezuela",
        "country_code": "VEN",
        "active": true
      },
      "round_number": 1,
      "hole_number": 1,
      "par": 4,
      "score": 4
    }
  ],
  "meta": {
    "next_cursor": 316408,
    "per_page": 3
  }
}

This endpoint retrieves hole-by-hole player scores for specific rounds. Requires GOAT tier.

HTTP Request

GET https://api.balldontlie.io/pga/v1/player_scorecards

Query Parameters

Parameter Type Required Description
tournament_ids integer[] No Filter by tournament IDs
player_ids integer[] No Filter by player IDs
round_number integer No Filter by round number (1-4)
hole_number integer No Filter by hole number (1-18)
cursor integer No Pagination cursor
per_page integer No Results per page (max 100, default 25)