Percentile to z-score calculator
This percentile to z-score calculator finds the standard normal value whose cumulative probability matches the percentile you enter.
Run — free
Give it a percentile strictly between zero and one hundred, and it returns both the equivalent probability and z-score. It is useful for interpreting normal-distribution cutoffs, checking statistical tables, setting one-sided thresholds, and moving between percentile language and standard deviations from the mean without manually searching a table.
What a percentile means on the standard normal curve
A percentile describes cumulative area to the left of a point. For example, the 50th percentile divides the standard normal distribution in half, so its z-score is zero. A percentile above 50 produces a positive z-score, while one below 50 produces a negative z-score. This calculator interprets the entered value on a zero-to-one-hundred scale and divides it by one hundred to obtain a probability. It then solves the inverse standard normal cumulative distribution function: instead of starting with a z-score and finding an area, it starts with the area and finds the z-score. The result therefore answers a precise question: how many standard deviations above or below the normal mean marks the requested cumulative percentile? This direction matters because an ordinary z-score calculator usually starts with a raw observation, mean, and standard deviation. Here, no raw data or distribution parameters are needed because the reference distribution already has mean zero and standard deviation one. The returned probability is included so you can confirm the exact scale used in the conversion.
How to enter and interpret the result
Enter a finite numeric percentile strictly greater than 0 and strictly less than 100. Decimal percentiles are supported, so values such as 2.5, 90, 95, or 99.9 can represent common tail cutoffs. The response includes `percentile`, `probability`, and `z_score`. The sign of `z_score` tells you which side of the mean contains the cutoff, and its magnitude gives the distance from the mean in standard-deviation units. Symmetric percentiles have z-scores with opposite signs: the 5th and 95th percentiles, for example, sit equally far from zero on opposite sides. Do not interpret the result as the probability between zero and the z-score; it is based on cumulative probability from the far left tail. If your source uses right-tail probability instead, convert it to a left-tail percentile first by subtracting that probability from one, then multiplying by one hundred. Keeping the tail convention explicit prevents a plausible-looking answer with the wrong sign.
Accuracy, endpoints, and practical boundaries
The calculation uses a deterministic, piecewise rational approximation to the inverse standard normal distribution. Separate formulas handle the center and tails, where a single polynomial would lose useful accuracy. The returned z-score is rounded to twelve significant digits, which is more precision than most statistical tables and routine threshold calculations require while keeping the JSON result stable. The exact 0th and 100th percentiles are rejected even though they look like boundary values on the percentage scale. Mathematically, their standard normal quantiles are negative and positive infinity, not finite z-scores that can be represented as ordinary JSON numbers. Values outside the zero-to-one-hundred interval, nonnumeric text, missing fields, NaN, and infinity are also invalid. Extremely tail-heavy but finite percentiles may be limited by ordinary floating-point representation, so retain only the precision justified by your source percentile. The browser calculation and API handler share the same pure implementation, with no network lookup, random values, or time-dependent behavior. API use costs $0.002 per request.
What you can do with it
Set a one-sided threshold
Convert a target cumulative percentile into the z cutoff used by a normally distributed monitoring or quality metric.
Check a statistics exercise
Verify an inverse-normal table lookup and see the probability scale alongside the resulting signed z-score.
Translate percentile reporting
Express a published percentile as standard deviations from the mean when a standard normal model is appropriate.
FAQ
What is the z-score at the 50th percentile?
It is 0 because half of the standard normal distribution lies below its mean.
Why are the 0th and 100th percentiles rejected?
Their theoretical quantiles are negative infinity and positive infinity. This calculator returns finite JSON numbers, so valid inputs must be strictly inside the interval.
Can I enter a decimal percentile?
Yes. Any finite numeric value strictly between 0 and 100 is accepted, including tail percentiles such as 2.5 or 99.9.
Is this the same as calculating a z-score from a raw value?
No. Raw-value standardization needs an observation, mean, and standard deviation. This calculator starts with cumulative probability and applies the inverse standard normal distribution.
Does the percentile represent a left-tail or right-tail area?
It is the cumulative left-tail area. For a right-tail probability, subtract it from one before converting the result to a percentile.
How much does API use cost?
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/stat/percentile-to-z \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"percentile":95}'const res = await fetch("https://api.kit.forhosting.com/stat/percentile-to-z", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"percentile": 95
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/stat/percentile-to-z",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"percentile": 95
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/stat/percentile-to-z", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"percentile":95}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"percentile":95}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/stat/percentile-to-z", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"percentile": 95
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "stat.percentile_to_z",
"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. |