All tutorials
AdvancedWHS15 min read

WHS Handicap Integration

Use slope rating and course rating from UK Golf API scorecards to calculate WHS handicap differentials for any round played at a UK course.

How WHS handicaps work

The World Handicap System (WHS) uses two course-specific numbers to make scores comparable across different courses and tee sets:

Course Rating

The expected score for a scratch golfer on that course. Typically 68–76 depending on difficulty.

tee_set.course_rating

Slope Rating

How much harder the course is for a bogey golfer vs a scratch golfer. Scale 55–155, standard is 113.

tee_set.slope_rating

The formula

WHS Handicap Differential:

Differential = (Adjusted Gross Score − Course Rating) × 113 ÷ Slope Rating

113 is the standard slope rating (par for the formula)

Example

Gross: 85 · Course Rating: 71.2 · Slope: 126

Differential = (85 − 71.2) × 113 ÷ 126 = 12.4

Data availability

Not all courses in the UK Golf API have slope/course rating data — this requires official measurement by the national golf union. Coverage breakdown:

GolfCourseAPI source

Slope: High (directly from GCA)

CR: High

LLM-extracted courses

Slope: Medium (scraped from websites)

CR: Medium

Always check tee_set.slope_rating != null before calculating. Fall back to the club's website or the WHS API for official values.

Single round differential

JavaScript
// Combine UK Golf API scorecard data with WHS handicap calculation
// The WHS formula uses: Handicap Differential = (Adjusted Gross Score - Course Rating) × 113 / Slope Rating

async function calculateHandicapDifferential({
  grossScore,
  courseId,
  teeColour = 'white',
}) {
  const headers = {
    'X-RapidAPI-Key': process.env.RAPIDAPI_KEY,
    'X-RapidAPI-Host': 'uk-golf-course-data-api.p.rapidapi.com',
  };

  // Fetch scorecard to get course rating and slope
  const res = await fetch(
    `https://uk-golf-api.vercel.app/courses/${courseId}/scorecard`,
    { headers }
  );
  const { data } = await res.json();

  // Find the right tee set
  const teeSet = data.tee_sets.find(
    t => t.name.toLowerCase() === teeColour.toLowerCase()
  );

  if (!teeSet) {
    throw new Error(`No ${teeColour} tee set found`);
  }

  const { course_rating, slope_rating, par } = teeSet;

  if (!course_rating || !slope_rating) {
    return {
      teeSet,
      par,
      message: 'Course/slope rating not available for this tee set',
      differential: null,
    };
  }

  // WHS Handicap Differential formula
  const differential = ((grossScore - course_rating) * 113) / slope_rating;

  return {
    teeSet,
    par,
    grossScore,
    courseRating: course_rating,
    slopeRating: slope_rating,
    differential: Math.round(differential * 10) / 10,
  };
}

const result = await calculateHandicapDifferential({
  grossScore: 85,
  courseId: 'YOUR_COURSE_ID',
  teeColour: 'white',
});

console.log(`Course: ${result.teeSet.name} tees`);
console.log(`Par: ${result.par}, Course Rating: ${result.courseRating}, Slope: ${result.slopeRating}`);
console.log(`Gross: ${result.grossScore}, Differential: ${result.differential}`);
Python
import requests
import math

API_KEY = "YOUR_API_KEY"
HEADERS = {
    "X-RapidAPI-Key": API_KEY,
    "X-RapidAPI-Host": "uk-golf-course-data-api.p.rapidapi.com",
}

def calculate_handicap_differential(
    gross_score: int,
    course_id: str,
    tee_colour: str = "white",
) -> dict:
    """Calculate WHS handicap differential using UK Golf API scorecard data."""

    # Fetch scorecard
    res = requests.get(
        f"https://uk-golf-api.vercel.app/courses/{course_id}/scorecard",
        headers=HEADERS,
    )
    scorecard = res.json()["data"]

    # Find tee set by colour
    tee_set = next(
        (t for t in scorecard["tee_sets"]
         if t["name"].lower() == tee_colour.lower()),
        None
    )
    if not tee_set:
        raise ValueError(f"No {tee_colour} tee set found")

    course_rating = tee_set.get("course_rating")
    slope_rating = tee_set.get("slope_rating")
    par = tee_set["par"]

    if not course_rating or not slope_rating:
        return {
            "par": par,
            "message": "Course/slope rating not available",
            "differential": None,
        }

    # WHS formula: (Adjusted Gross - Course Rating) × 113 / Slope
    differential = ((gross_score - course_rating) * 113) / slope_rating

    return {
        "tee_colour": tee_colour,
        "par": par,
        "gross_score": gross_score,
        "course_rating": course_rating,
        "slope_rating": slope_rating,
        "differential": round(differential, 1),
        "net_score": gross_score - (par - 72),  # simple net score
    }


result = calculate_handicap_differential(85, "YOUR_COURSE_ID", "white")
print(f"Gross: {result['gross_score']}, Par: {result['par']}")
print(f"Course Rating: {result['course_rating']}, Slope: {result['slope_rating']}")
print(f"Handicap Differential: {result['differential']}")

Calculate handicap index from multiple rounds

The WHS handicap index uses the best differentials from recent rounds. Here's how to calculate it from an array of differentials:

JavaScript (handicap index from history)
// Calculate handicap index from last 20 rounds (WHS method)
// Best 8 of last 20 differentials, multiplied by 0.96

function calculateHandicapIndex(differentials) {
  if (differentials.length < 3) {
    return { error: 'Need at least 3 rounds' };
  }

  // Sort ascending, take best 8 of last 20
  const sorted = [...differentials].sort((a, b) => a - b);
  const count = differentials.length;

  // WHS adjustment table
  const useBest = count >= 20 ? 8
    : count >= 17 ? 7
    : count >= 14 ? 6
    : count >= 11 ? 5
    : count >= 9  ? 4
    : count >= 7  ? 3
    : count >= 5  ? 2
    : 1;

  const best = sorted.slice(0, useBest);
  const avg = best.reduce((a, b) => a + b, 0) / best.length;
  const index = Math.round(avg * 0.96 * 10) / 10;

  return { handicapIndex: index, usedRounds: useBest, differentials: best };
}

Important note

This tutorial implements the handicap differential formula for educational purposes. For official WHS handicap records, use the WHS system or your national golf union's official platform. The UK Golf API provides the course/slope data needed as inputs to WHS calculations.

Next steps