Golf Stroke Play Score to Par Calculator
This golf stroke play score calculator adds a golfer's strokes across every entered hole, adds the matching course pars, and reports the difference in familiar score-to-par notation.
Run — free
Enter the two lists in the same playing order to calculate an individual round, a nine-hole card, or any other completed stretch of holes. The result includes the hole count, total strokes, total par, a numeric difference, and a display value such as -3, +5, or E for even par. Mismatched lists are rejected instead of producing a misleading result.
Enter one stroke value and one par value for every hole
Start with the golfer's recorded strokes in playing order, then enter the course par values in exactly the same order. The first stroke value must describe the same hole as the first par value, the second pair must describe the next hole, and so on. Each entry must be a positive whole number because a completed hole cannot have a fractional or zero stroke total. The calculator accepts a single hole, a common nine-hole or eighteen-hole round, and longer bounded lists when several played sections need one combined total. The two lists must contain the same number of entries. That requirement is essential: if a scorecard has eighteen stroke values but only seventeen par values, pairing by position would leave one hole without a comparison and make the final score to par unreliable. The capability therefore returns an input error for unequal list lengths. Check omissions, duplicated holes, and ordering before resubmitting. No course lookup occurs, so use the par printed for the tees actually played rather than a remembered value from another tee set.
Understand total score and score relative to par
The total score is the sum of every value in the strokes list. Total par is calculated independently by adding every value in the par list. Score to par is then total score minus total par. A negative result means the golfer used fewer strokes than par, so a result of -3 means three under par. A positive result means more strokes than par, so +5 means five over par. A difference of zero is displayed as E, the conventional abbreviation for even par, while the numeric score_to_par field remains zero for reliable automation. The response also repeats the number of holes, which makes it easier to confirm whether the calculation represents a partial round or a complete card. This is aggregate stroke play arithmetic: every entered stroke contributes to the total. It does not apply match-play scoring, Stableford points, handicap allowances, net double bogey adjustments, disqualifications, or tournament tie procedures. If penalties have already been added to the per-hole stroke figures, they are naturally included in the sum.
Use the result for scorecards, leaderboards, and checks
For a quick scorecard check, compare the returned total score with the handwritten outward and inward totals, then verify that total par matches the selected course and tees. For an application, store the numeric score_to_par value for sorting and calculations, and use score_to_par_display when presenting the familiar signed notation to a reader. Numeric storage avoids treating +10 as text that might sort before +2. The explicit total_par field is useful when rounds on courses with different pars appear together, because the same stroke total can represent a different performance relative to par. Coaches and league organizers can also calculate partial-round progress by submitting only completed holes, provided both arrays cover precisely those holes in the same sequence. The calculation is deterministic and uses no network service, random choice, or current time, so identical inputs always return identical results. It is still important to resolve scorecard corrections before calculation. The tool adds the values supplied; it does not decide whether a penalty should apply or whether a marked score complies with competition rules.
What you can do with it
Check a completed scorecard
Add all recorded holes and confirm both the gross stroke total and the final result relative to the course par.
Power a golf leaderboard
Convert hole-by-hole scoring data into a numeric score to par and a reader-friendly signed display value.
Track a partial round
Calculate progress through the holes already completed by supplying matching stroke and par entries for that section.
FAQ
How is score to par calculated?
The calculator subtracts total course par from total strokes. Negative values are under par, positive values are over par, and zero is even par.
What happens if the two lists contain different numbers of holes?
The request returns an invalid input error because every stroke value must have one corresponding par value.
Can I calculate a nine-hole or partial-round score?
Yes. Supply only the played holes, with the strokes and par lists covering the same holes in the same order.
How are penalty strokes handled?
Include any assessed penalty strokes in the relevant per-hole stroke values before submitting the list.
What does it cost through the API?
Each API request costs $0.002. The same deterministic calculation can also run in the browser.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/sports/golf-stroke-play-score \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"strokes":[4,3,5,4,4,3,5,4,3,4,4,5,3,4,4,3,5,4],"par":[4,4,5,3,4,4,5,4,3,4,4,5,3,4,4,3,5,4]}'const res = await fetch("https://api.kit.forhosting.com/sports/golf-stroke-play-score", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"strokes": [
4,
3,
5,
4,
4,
3,
5,
4,
3,
4,
4,
5,
3,
4,
4,
3,
5,
4
],
"par": [
4,
4,
5,
3,
4,
4,
5,
4,
3,
4,
4,
5,
3,
4,
4,
3,
5,
4
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/sports/golf-stroke-play-score",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"strokes": [
4,
3,
5,
4,
4,
3,
5,
4,
3,
4,
4,
5,
3,
4,
4,
3,
5,
4
],
"par": [
4,
4,
5,
3,
4,
4,
5,
4,
3,
4,
4,
5,
3,
4,
4,
3,
5,
4
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/sports/golf-stroke-play-score", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"strokes":[4,3,5,4,4,3,5,4,3,4,4,5,3,4,4,3,5,4],"par":[4,4,5,3,4,4,5,4,3,4,4,5,3,4,4,3,5,4]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"strokes":[4,3,5,4,4,3,5,4,3,4,4,5,3,4,4,3,5,4],"par":[4,4,5,3,4,4,5,4,3,4,4,5,3,4,4,3,5,4]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/sports/golf-stroke-play-score", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"strokes": [
4,
3,
5,
4,
4,
3,
5,
4,
3,
4,
4,
5,
3,
4,
4,
3,
5,
4
],
"par": [
4,
4,
5,
3,
4,
4,
5,
4,
3,
4,
4,
5,
3,
4,
4,
3,
5,
4
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "sports.golf_stroke_play_score",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |