Post-test probability calculator
With a pre-test probability of 0.01, a positive result on a test with sensitivity 0.9 and specificity 0.95 raises the chance of disease only to 0.153846153846. Enter the pre-test probability, both test figures and the result to see the updated chance. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Pretest probability
- 0.01
- Sensitivity
- 0.9
- Specificity
- 0.95
- Test result
- Positive
- Post test probability
- 0.1538461538
- Likelihood ratio
- 18
Post-test probability is the chance that a person actually has the target disease after a diagnostic test result is known. Clinicians, students, and guideline authors start from a pre-test probability — the prevalence or clinical suspicion before the assay — then combine it with the test's sensitivity and specificity and update that belief given a positive or a negative result. This post-test probability calculator performs that update with Bayes' rule in its diagnostic form: a positive result multiplies pre-test odds by the positive likelihood ratio, and a negative result multiplies them by the negative likelihood ratio.
What post-test probability answers and how the update works
A diagnostic test does not replace the question of whether disease is present; it revises that question. Before the assay you already hold a pre-test probability, often the local prevalence or a clinical suspicion after history and examination. Sensitivity is the chance the test is positive when disease is truly present.
Specificity is the chance the test is negative when disease is truly absent. Those two operating characteristics, together with the observed result, determine how far the belief should move. For a positive result the posterior is sensitivity times pre-test probability, divided by that same product plus one minus specificity times one minus the pre-test probability.
For a negative result the numerator becomes one minus sensitivity times the pre-test probability, and the complementary term in the denominator is specificity times one minus the pre-test probability. The same identities appear as likelihood ratios: the positive likelihood ratio is sensitivity over one minus specificity, and the negative likelihood ratio is one minus sensitivity over specificity. Pre-test odds equal pre-test probability over one minus that probability; multiplying by the matching ratio and converting odds back to a probability yields the same posterior.
This is why a highly accurate screen can still leave a modest post-test chance when the disease is rare: false positives dominate the pool of positive results. Positive predictive value is simply the special name for post-test probability after a positive result; after a negative result the complementary quantity is one minus the negative predictive value. This landing computes that single posterior for the result you observed.
It does not chain sequential tests, does not fit ROC curves, and does not invent a prevalence from a contingency table.
What you can do with it
Classroom rare-disease examples
Show students how a 90% sensitive, 95% specific test still leaves a modest posterior when prevalence is 1%, for both a positive and a negative result.
Exam and LMS auto-grading
Mark diagnostic-Bayes items with a deterministic oracle that rejects any probability outside 0 to 1 and never invents a posterior when the result is impossible.
Screening and journal-club notes
Turn published sensitivity, specificity, and local prevalence plus the observed result into a post-test chance of disease without a statistics library.
FAQ
What formula does the post-test probability calculator use?
For a positive result, P(D|T+) = (sensitivity × pretest) / (sensitivity × pretest + (1 − specificity) × (1 − pretest)). For a negative result the complementary identity uses (1 − sensitivity) and specificity. The same numbers are the likelihood-ratio update of pre-test odds.
What happens if a probability is outside 0 to 1?
Probabilities must lie in the closed interval from zero to one; they are never clamped.
How is this different from positive predictive value?
Positive predictive value is the post-test probability after a positive result. This tool also accepts a negative result, which yields the posterior P(D|T−). One minus that posterior is the negative predictive value.
What is the likelihood ratio in the response?
After a positive result it is sensitivity / (1 − specificity). After a negative result it is (1 − sensitivity) / specificity.
What does the post-test probability calculator cost?
The browser tool is free and runs locally.
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/stat/post-test-probability \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"pretest_probability":0.01,"sensitivity":0.9,"specificity":0.95,"test_result":"positive"}'const res = await fetch("https://api.kit.forhosting.com/stat/post-test-probability", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"pretest_probability": 0.01,
"sensitivity": 0.9,
"specificity": 0.95,
"test_result": "positive"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/stat/post-test-probability",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"pretest_probability": 0.01,
"sensitivity": 0.9,
"specificity": 0.95,
"test_result": "positive"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/stat/post-test-probability", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"pretest_probability":0.01,"sensitivity":0.9,"specificity":0.95,"test_result":"positive"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"pretest_probability":0.01,"sensitivity":0.9,"specificity":0.95,"test_result":"positive"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/stat/post-test-probability", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"pretest_probability": 0.01,
"sensitivity": 0.9,
"specificity": 0.95,
"test_result": "positive"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "stat.post_test_probability",
"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. |
Technical notes
Every input probability must lie in the closed interval from zero to one; values outside that range fail with invalid_input instead of being silently clamped. Successful API calls cost $0.002.
What post-test probability answers and how the update works
When the observed result has probability zero under the numbers you supplied — for example a positive result when specificity is one and either sensitivity or pre-test probability is zero — the posterior is mathematically undefined and the call fails instead of returning NaN.
Input contract, response shape, and rejected probabilities
Classic check: pre-test probability zero point zero one, sensitivity zero point nine, specificity zero point nine five, and a positive result yield a post-test probability of about zero point one five four, the familiar classroom warning that a ninety-percent-sensitive, ninety-five-percent-specific screen barely lifts a one-percent prevalence into the mid-teens. Failed validation is not billed. Send a JSON body with four required fields. Field pretest_probability is the pre-test chance of disease in the closed interval from zero to one; aliases pre_test_probability, pretest, prevalence, prior, and p are accepted. Field sensitivity is the true-positive rate in the same interval; aliases sens, true_positive_rate, and tpr map to it. Field specificity is the true-negative rate; aliases spec, true_negative_rate, and tnr work interchangeably. Field test_result must be the enum value positive or negative; aliases result and outcome are accepted, as are a few classroom shortcuts such as pos, neg, plus, and minus. Each probability may arrive as a JSON number or as a trimmed decimal string, including scientific notation for tiny prevalences. Missing fields, empty strings, non-finite values, and any number outside the unit interval fail with invalid_input naming the field — a probability of one point five or of negative five hundredths is rejected rather than clamped, so a percent that was never divided by one hundred cannot silently become a nonsense posterior. On success the body echoes the three normalized probabilities and the canonical test_result, returns post_test_probability rounded to twelve decimal places for stable goldens, includes likelihood_ratio when that ratio is finite, and restates the diagnostic Bayes identity in formula. Pricing is a flat $0.002 per successful request with unit item.
Where a post-test probability calculator earns its keep
Evidence-based medicine courses use a post-test probability calculator so learners can see how prevalence, not only advertised accuracy, drives the chance of disease after a screen. Do not confuse this landing with a general Bayes-theorem page that takes a false-positive rate and no observed result, or with a positive-predictive-value page that never handles a negative assay: here the search intent is the clinical posterior after a known diagnostic result. Keep requests small, pin the rounded posterior in tests, and you get reproducible post-test probabilities for homework, LMS plugins, and edge workers without standing up symbolic math infrastructure of your own. Always convert percentages to the unit interval before you call, and treat the returned likelihood ratio as a caption next to the probability so readers see both the odds multiplier and the final chance of disease. Tutoring platforms and exam-prep generators need a deterministic oracle that marks a percent typed as ninety instead of zero point nine as invalid_input, instead of silently returning a posterior no probability space can realize. Screening-program notes and journal clubs often quote the posterior after a positive mammogram, troponin, or rapid antigen test from published sensitivity, specificity, and local prevalence; calling a tiny parse endpoint avoids pulling a full statistics package for four numbers.