Save percentage calculator
32 saves on 35 shots is a save percentage of about 91.4: enter the two numbers from the scoresheet and get the share of charged shots the goalie stopped, plus goals allowed. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Saves
- 32
- Shots on goal
- 35
- Goals allowed
- 3
- Save percentage
- 91.4285714286
Save percentage is the goaltending rate that turns a night of shots on goal into one comparable figure: saves made divided by shots faced, times one hundred. A keeper who stops twenty-seven of thirty is not the same as a keeper who stops twenty-seven of forty, even though the save totals match. Use it to power a scoreboard graphic, to compare a hockey starter with a soccer keeper, or to gate a report that should never invent a rate before the first shot on goal.
What save percentage measures and how the formula works
Save percentage is the goaltending metric that converts a sample of shots on goal into the share that were stopped. Hockey box scores print it as SV%, soccer analytics desks quote it for keepers, and lacrosse, field hockey, and water polo use the same ratio whenever a shot on target is charged to the goalie. The identity is saves divided by shots on goal, multiplied by one hundred, so thirty-two saves from thirty-five shots is about ninety-one point four percent, not a letter grade and not a ranking.
Shots on goal are the shots the goalie faced, not every attempt from the attacking zone: a blocked shot, a missed net, or an empty-net situation that your scorer did not charge to the goalie should stay out of the denominator you send. This calculator does not fetch a scoresheet and does not reclassify rebound chances. You pass the two numbers you already have from the book, the scoring app, or the play-by-play extract, and it returns the ratio.
It also does not label 0.920 as elite or 0.880 as replacement: a 0.880 night can win a playoff game and a 0.950 night can lose one. Those judgements live in your report. Zero saves from a positive shot count is valid and yields save percentage zero — the honest reading of a night when every charged shot went in.
Inputs, formula, rounding, and the zero-shots error
Negative saves are rejected because a save total cannot go below zero in this calculator. Shots on goal must be greater than zero: save percentage is undefined when shots is zero, and the task fails instead of returning Infinity, NaN, or a silent zero. That failure is not billed.
Zero saves with a positive shot count is valid and yields save percentage 0. Example: 32 saves from 35 shots produces 91.4285714286 percent and three goals allowed, the familiar 32-of-35 night commentators round to 91.4 or .914 on a graphic. Rates of 100 mean a shutout of the charged shots; rates of 0 mean every charged shot scored.
Where a deterministic save percentage calculator earns its keep
Live scoring products need the same formula after every shot on goal, not a spreadsheet cell that someone edited during a TV timeout. Academy databases that mix youth hockey, NCAA soccer, and professional lacrosse should still speak one language for save percentage even when each competition stores empty-net situations differently upstream.
Fantasy pipelines and scouting sheets sort a crease by stop rate as well as by goals-against average; GAA rewards occupancy of the net over time, save percentage rewards the share of charged shots that were stopped, and the two numbers answer different selection questions. Failed validation does not consume balance.
Keep the two inputs in the same game, period, or career window — do not divide this match's saves by last season's shots faced — and you get a reproducible saves-over-shots figure for scoreboards, LMS quizzes, and edge workers without standing up a scoring vendor of your own. If you need goals-against average, batting strike rate, or baseball on-base plus slugging, compute those with their own denominators; this landing is for the goaltending save percentage that people search for as SV% from saves and shots on goal.
What you can do with it
Live scoreboard and broadcast graphics
Turn the current saves and shots on goal into a save percentage for the crease graphic after every charged shot, without inventing a number before the first shot on goal.
Scouting and selection sheets
Compare a hockey starter with a soccer keeper on the same scale by converting each sample's saves and shots faced into a 0–100 stop rate.
FAQ
What happens if shots on goal is zero?
Save percentage is undefined when shots is zero, so the calculator does not return Infinity, NaN, or a fake zero rate, and the failure is not billed.
What if saves exceed shots faced, and can saves be zero?
Zero saves with a positive shot count is valid and yields save percentage 0.
Is this hockey SV% or a soccer statistic, and do you return .915 or 91.5?
The same saves-over-shots identity is used in hockey, soccer, lacrosse, and other sports that charge shots on goal to a keeper.
How do I calculate save percentage?
Divide saves by shots on goal and multiply by 100. A goalie with 32 saves on 35 shots has a save percentage of about 91.4, with three goals allowed.
Which shots count as shots on goal?
Only the shots charged to the goalie. Blocked shots, shots that miss the net and empty-net chances your scorer did not charge to the goalie stay out, because they were never a chance to make a save.
Related tools
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/save-percentage \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"saves":32,"shots_on_goal":35}'const res = await fetch("https://api.kit.forhosting.com/sports/save-percentage", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"saves": 32,
"shots_on_goal": 35
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/sports/save-percentage",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"saves": 32,
"shots_on_goal": 35
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/sports/save-percentage", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"saves":32,"shots_on_goal":35}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"saves":32,"shots_on_goal":35}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/sports/save-percentage", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"saves": 32,
"shots_on_goal": 35
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "sports.save_percentage",
"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.
Limits
max_abs_value | 1000000000000000 |
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. |
Technical notes
What save percentage measures and how the formula works
Official NHL graphics often show the three-decimal form 0.914 by dividing that percentage by one hundred; this endpoint returns the percentage itself so a dashboard can format 91.4 or .914 without a second conversion library. What lives here is a deterministic implementation of save_percentage = (saves / shots_on_goal) × 100, a hard error when shots is zero so a dashboard never renders Infinity, and a hard error when saves exceed shots faced because a stop cannot be credited without a shot.
Inputs, formula, rounding, and the zero-shots error
POST a JSON body with two required finite numbers: saves, the non-negative saves made in the game, period, season, or window you are measuring, and shots_on_goal, the strictly positive number of shots on goal charged to the goalie in that same window. Each field may arrive as a JSON number or as a numeric string; aliases saves_made and sv are accepted for the numerator, and shots, shots_faced, sog, sa, and shots_against for the denominator. Missing fields, empty strings, NaN, Infinity, and non-numeric text fail with invalid_input naming the field. Saves cannot exceed shots on goal: saves cannot exceed shots faced, and a request that claims forty stops from thirty-five shots is rejected as invalid_input. On success the body echoes the two inputs, returns goals_allowed as shots minus saves, returns save_percentage as the 0–100 rate rounded to ten decimal places for stable goldens across runtimes, and restates formula as save_percentage = (saves / shots_on_goal) * 100. Pair the response with your own league benchmarks if you need a traffic-light label; this endpoint returns the percentage only.
Integration use cases
Fantasy and academy pipelines
Gate a goalie who has not yet faced a shot as invalid_input when shots is zero, and reject a save total that exceeds shots faced, instead of rendering Infinity in a ranking.
Technical questions
How is save percentage calculated from saves and shots on goal?
save_percentage = (saves / shots_on_goal) × 100. Send a non-negative save total and a shots-on-goal count greater than zero; the API returns the 0–100 percentage and goals allowed.
What does the save percentage calculator cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.