NPI check digit
The base 123456789 gets the check digit 3, so the full NPI is 1234567893. Enter nine digits to complete a National Provider Identifier, or ten to confirm its last digit before a claim or provider directory entry goes out. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Number
- 123456789
- Calculation mode
- Compute
- Input
- 123456789
- Prefix
- 80840
- Prefixed
- 80840123456789
The United States National Provider Identifier is a ten-digit number that identifies individual clinicians and organizational providers in claims, enrollment, and directory systems under HIPAA. The first nine digits are the base identifier issued through NPPES; the tenth is a check digit produced by the Luhn algorithm after the constant prefix 80840 is applied to the base. That rule makes an NPI behave like an ISO-style identifier for checksum purposes without claiming it is a payment card. This capability implements that CMS rule only: compute mode accepts exactly nine base digits and returns the check digit plus the full ten-digit NPI; validate mode accepts a full ten-digit NPI and reports whether the trailing digit matches the recomputed expected value.
How the NPI check digit is calculated with the 80840 prefix
Under the Centers for Medicare & Medicaid Services specification, an NPI is always ten decimal digits. Positions one through nine form the base identifier (individuals typically start with one, organizations with two, though this tool does not enforce issuer type). Position ten is the check digit.
Apply the classic double-add-double Luhn algorithm from the right of that fourteen-digit string: double every second digit starting with the rightmost base digit, because once the check digit is appended that rightmost base digit sits in position two from the right of the full fifteen-digit ISO-style sequence. When twice a digit is greater than nine, subtract nine (equivalently sum the tens and units of the product).
Add every weighted value; the check digit is ten minus that sum modulo ten, modulo ten again so the complete sequence including the check digit has a Luhn total divisible by ten. Validation recomputes the expected digit from the first nine characters after the same 80840 prefix and compares it to the tenth digit of the submitted NPI. The algorithm is deterministic and local: no NPPES registry call, no clock, and no randomness.
Compared with generic card Luhn or IMEI Luhn tools, the search intent here is narrow: people who need an NPI check digit calculator for nine-digit bases or a ten-digit National Provider Identifier checker, not a payment or device tool.
Where NPI check digits fit real healthcare workflows
Practice management and EHR vendors receive nine-digit internal bases during onboarding sandboxes and must append the official Luhn check digit before an NPI appears on claims, superbills, or provider directories. Clearinghouses and payers validate ten-digit NPIs at claim intake so a single transposition does not create a phantom provider and a rejected 837 transaction. ETL jobs that load provider master files walk every NPI column in a CSV or HL7 feed, call validate mode, and quarantine rows where valid is false—catching both human edits and off-by-one bugs in generators.
Do not treat a passing NPI check as proof that the provider is active in NPPES, licensed in a state, or enrolled with a payer; it only proves the Luhn digit is consistent with the base under the CMS 80840 weights used for National Provider Identifiers.
What you can do with it
Audit NPI columns in provider master data
Batch-validate every ten-digit NPI in an EHR, credentialing, or clearinghouse CSV and quarantine rows whose check digit no longer matches the recomputed expected value.
FAQ
What is an NPI check digit?
It is the tenth digit of a US National Provider Identifier, computed with the Luhn algorithm after prefixing the constant 80840 to the first nine digits, so typing and scanning errors are usually caught before the number is stored or billed.
Is the NPI check digit tool free?
The browser tool is free and runs locally.
How is the NPI check digit calculated?
Put 80840 in front of the nine-digit base and run the Luhn method on those fourteen digits: double every second digit from the right, subtract nine from any result above nine and add everything. The check digit is the one that brings the total to a multiple of ten.
Why is 80840 placed in front of the base?
It is the fixed prefix in the CMS rule, so an NPI gets the same check digit that a card-style Luhn number would. The prefix is only used for the calculation: the NPI you print still has ten digits, such as 1234567893.
Does a valid NPI mean the provider is active?
No. A valid result only means the last digit matches the calculation. The tool does not query the NPPES registry and says nothing about whether a provider is active, enrolled or licensed.
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/enc/npi \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"number":"123456789"}'const res = await fetch("https://api.kit.forhosting.com/enc/npi", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"number": "123456789"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/enc/npi",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"number": "123456789"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/enc/npi", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"number":"123456789"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"number":"123456789"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/enc/npi", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"number": "123456789"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "enc.npi",
"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
Non-numeric input and wrong lengths fail with invalid_input instead of silent stripping, so you never persist a half-cleaned identifier. The same pure arithmetic runs free in the browser and at the published API price, with no network lookup of NPPES registries and no claim that a valid checksum means the provider is active, enrolled, or licensed.
How the NPI check digit is calculated with the 80840 prefix
To compute it, concatenate the fixed five-digit constant 80840 in front of the nine-digit base, producing a fourteen-digit string that mimics the payload of a card-number style Luhn calculation.
Input contract, modes, and error behaviour
Send a number field that contains only characters zero through nine. Wrong length is an explicit error that names the mode and the length you sent—nine for compute, ten for validate—so client forms can show “need nine digits” without guessing. Empty strings, missing number, and invalid mode values fail before any Luhn sum runs and are not billed. Failed validation tasks that reject bad shape are not charged; a well-formed ten-digit string that simply has the wrong check digit returns valid false without throwing. Spaces, hyphens, letters, and decimal points are rejected as non-numeric input with invalid_input so a silently stripped value never reaches storage. Mode compute is the default: the engine requires exactly nine digits, returns check_digit as a one-character string, returns with_check as the ten-digit NPI you can print or persist, and also returns prefix (always 80840) and prefixed (80840 plus the nine-digit base) for audit trails and debugging of the CMS rule. Mode validate requires exactly ten digits; the response reports valid true when the trailing digit matches the recomputed expected_check_digit, and always includes payload (the first nine digits), check_digit, expected_check_digit, prefix, prefixed, and length ten. Alias keys such as digits, npi, and code are accepted for the same payload field so integrations that already speak “npi” do not need a rename. Because the path is pure parse with no clock, random source, or network, the same JSON body always yields the same JSON result on the free browser tool and on the API at $0.002 per successful request.
Where NPI check digits fit real healthcare workflows
Credentialing and roster teams recompute expected_check_digit when a clinic reads a number over the phone or pastes it from a PDF, catching mistypes before a contract or enrollment file is submitted.
Integration use cases
Complete a 9-digit NPI base for claims fixtures
Call compute mode with the nine-digit base, store with_check, and use the ten-digit NPI in test claims, superbills, or sandbox provider records.
Validate typed or imported NPIs at entry
When a form, roster file, or partner feed submits ten digits, call validate mode and block enrollment when valid is false, showing expected_check_digit to help correct a single mistype.
Technical questions
How do I compute an NPI check digit with this API?
POST with number set to exactly nine digits and mode compute (or omit mode). The response includes check_digit, with_check (the full ten-digit NPI), and prefix 80840 for audit of the CMS rule.
How do I validate a full ten-digit NPI?
POST with the ten-digit string and mode validate. The response includes valid, check_digit, expected_check_digit, and payload (digits without the last one).
What happens with wrong length, letters, or hyphens?
Non-numeric input and lengths other than nine (compute) or ten (validate) are rejected with invalid_input. Failed validation tasks are not billed.