Sensitivity and specificity calculator
90 true positives, 10 false negatives, 80 true negatives and 20 false positives give a sensitivity of 90 % and a specificity of 80 %. Enter the four counts of your table and get both rates, ready to quote in a methods section. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- True positives
- 90
- True negatives
- 80
- False positives
- 20
- False negatives
- 10
- Actual positives
- 100
- Actual negatives
- 100
- Sensitivity
- 0.9
- Specificity
- 0.8
Sensitivity and specificity turn a four-cell confusion matrix into the two operating characteristics a diagnostic paper, a screening note, or a binary-classifier review actually quotes. Sensitivity — also called the true-positive rate or recall — is the share of actual positives the test catches: true positives divided by true positives plus false negatives. Specificity — the true-negative rate — is the share of actual negatives it correctly leaves unflagged: true negatives divided by true negatives plus false positives. This sensitivity and specificity calculator accepts those four counts and returns both rates as unit-interval proportions and as percentages.
What sensitivity and specificity measure in a 2×2 table
A binary test or classifier partitions observations into four cells: true positives, true negatives, false positives, and false negatives. Sensitivity answers one of those cells' questions: of everyone who truly has the condition, or belongs to the positive class, what fraction did the rule flag? The formula is true positives over the sum of true positives and false negatives — every actual positive, whether caught or missed.
Specificity answers the complementary question: of everyone who is truly free of the condition, what fraction did the rule correctly leave unflagged? That formula is true negatives over the sum of true negatives and false positives. Those identities are older than machine-learning scorecards.
They are the language of diagnostic studies, screening programs, and epidemiology textbooks, and they are not the same as positive or negative predictive value. Predictive values mix prevalence into the same four cells; sensitivity and specificity do not. A highly sensitive assay can still leave a modest positive predictive value when the disease is rare, because false positives swamp the few true cases.
Conversely, a specific assay can miss many cases if its sensitivity is poor. This landing stops at the two rates. It does not estimate prevalence, does not compute likelihood ratios or post-test probability, and does not collapse the table into a single Matthews correlation or F1 score.
Those are different search intents with their own pages. What you get here is the pair of operating characteristics from the four counts you already have, as unit-interval proportions, plus the same figures as percentages so a methods section can quote either convention without a second conversion.
What you can do with it
Diagnostic 2×2 tables from a validation cohort
Turn published true-positive, true-negative, false-positive, and false-negative counts into sensitivity and specificity for a methods section or journal club.
Classroom and LMS auto-grading
Mark confusion-matrix items with a deterministic oracle that rejects any negative count and never invents a rate when a denominator is zero.
FAQ
How are sensitivity and specificity calculated?
Sensitivity is TP / (TP + FN), the true-positive rate or recall. Specificity is TN / (TN + FP), the true-negative rate. Both are returned as proportions in [0, 1] and as percentages.
What happens if a count is a negative number?
Counts must be finite and non-negative; they are never taken at absolute value.
Can a cell be zero?
Yes. A single zero cell is a valid table — for example a test with no false positives. Sensitivity is rejected only when TP + FN is zero, and specificity only when TN + FP is zero, because those rates are then undefined.
How is this different from post-test probability or PPV?
This tool computes the two operating characteristics from the four cell counts. Post-test probability and positive predictive value mix prevalence (or a pre-test chance) into those cells and answer a different question after a result is observed.
What does the sensitivity and specificity 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/sensitivity-and-specificity \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"true_positives":90,"true_negatives":80,"false_positives":20,"false_negatives":10}'const res = await fetch("https://api.kit.forhosting.com/stat/sensitivity-and-specificity", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"true_positives": 90,
"true_negatives": 80,
"false_positives": 20,
"false_negatives": 10
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/stat/sensitivity-and-specificity",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"true_positives": 90,
"true_negatives": 80,
"false_positives": 20,
"false_negatives": 10
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/stat/sensitivity-and-specificity", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"true_positives":90,"true_negatives":80,"false_positives":20,"false_negatives":10}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"true_positives":90,"true_negatives":80,"false_positives":20,"false_negatives":10}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/stat/sensitivity-and-specificity", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"true_positives": 90,
"true_negatives": 80,
"false_positives": 20,
"false_negatives": 10
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "stat.sensitivity_and_specificity",
"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
A negative count is rejected with invalid_input rather than being folded into a meaningless ratio. Successful API calls cost $0.002.
Input contract, response shape, and rejected counts
A negative number in any cell is rejected rather than being silently taken at absolute value — a sign flip in a spreadsheet export cannot become a plausible sensitivity. Zero is allowed in a single cell, so a perfect screen with no false positives is a valid table. What is not allowed is a zero denominator: if true positives plus false negatives is zero there are no actual positives and sensitivity is undefined; if true negatives plus false positives is zero there are no actual negatives and specificity is undefined. Those cases fail instead of returning NaN. Classic check: ninety true positives, ten false negatives, eighty true negatives, and twenty false positives yield sensitivity zero point nine and specificity zero point eight. Failed validation is not billed. Send a JSON body with four required fields. Field true_positives is the TP cell; alias tp is accepted. Field true_negatives is the TN cell; alias tn maps to it. Field false_positives is the FP cell; alias fp works interchangeably. Field false_negatives is the FN cell; alias fn is accepted. Each count may arrive as a JSON number or as a trimmed decimal string, including scientific notation for tiny weighted tables. Missing fields, empty strings, and non-finite values fail with invalid_input naming the field. On success the body echoes the four counts, reports actual_positives and actual_negatives, returns sensitivity and specificity rounded to twelve decimal places for stable goldens, includes the same rates as sensitivity_percent and specificity_percent on a zero-to-one-hundred scale, and restates the two identities in formula. Pricing is a flat $0.002 per successful request with unit item.
Where a sensitivity and specificity calculator earns its keep
Diagnostic-methods courses use a sensitivity and specificity calculator so learners can turn a published 2×2 table into the two rates without mixing them up with predictive values. Do not confuse this landing with a post-test probability page that takes sensitivity and specificity as inputs, with a Bayes-theorem page that also wants a prior, or with a Matthews-correlation page that collapses the same four cells into one coefficient: here the search intent is the two rates themselves. Keep requests small, pin the rounded proportions in tests, and you get reproducible sensitivity and specificity for homework, LMS plugins, and edge workers without standing up symbolic math infrastructure of your own. Always send non-negative counts, and treat a zero row or column of actuals as a contract error rather than a silent one-hundred-percent claim. Tutoring platforms and exam-prep generators need a deterministic oracle that marks a negative cell as invalid_input instead of inventing a ratio no count table can realize. Screening-program notes and journal clubs often quote both operating characteristics from a validation cohort — mammography, troponin, rapid antigen, a new PCR — and calling a tiny parse endpoint avoids pulling a full statistics package for four integers.
Integration use cases
Binary classifier reviews
Pin golden fixtures for recall and the true-negative rate from a known confusion matrix so a refactor cannot silently change the reported operating characteristics.