UK UTR check digit
Compute or check the leading digit of a UK Unique Taxpayer Reference: the body 123456789 gives check digit 1, so the full UTR is 1123456789. Catch a mistyped reference before it reaches a form or a batch import. 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
- Check digit
- 1
- With check
- 1123456789
- Weighted sum
- 230
A Unique Taxpayer Reference (UTR) is the ten-digit identifier HM Revenue and Customs issues to individuals and companies for Self Assessment and corporation tax. The leading digit is not random: it is a check digit derived from the remaining nine body digits using fixed positional weights and a modulus-eleven remainder table. Mistyping a single body digit almost always changes the required check digit, so forms and batch imports can reject impossible UTRs before they hit HMRC gateways. This capability computes that leading check digit from a nine-digit body you already hold, or validates a complete ten-digit UTR and reports whether the stored check digit matches the weighted remainder table.
How the UK UTR check digit and remainder table work
Under the widely documented HMRC-style construction used by accountants and software vendors, a standard Unique Taxpayer Reference is ten decimal digits. The first digit is the check digit; the next nine digits are the body. Each body digit is multiplied by a fixed weight drawn from the sequence six, seven, eight, nine, ten, five, four, three, two from left to right.
Those nine products are summed, and the sum is reduced modulo eleven to produce a remainder in zero through ten.
A remainder table then maps that remainder to a single check digit: remainder zero maps to check digit zero; remainder one is rejected because eleven minus one equals ten, which cannot fit in one decimal place and is never issued as a legal UTR body; remainders two through ten map to check digits nine down through one, which is the same rule as eleven minus the remainder when the result is not ten.
Validation recomputes the expected leading digit from the nine body digits and compares it to the first digit of the submitted ten-digit string. That design is not Luhn, not Damm, and not plain ISO 7064 MOD 11-2: it is a fixed-weight mod-eleven scheme with a leading check position rather than a trailing one. Compared with barcode family check digits such as EAN or UPC, the UTR rule is not tied to a retail GTIN layout and always places the check at the front.
Compared with German Steuer-ID or Swedish personnummer schemes, the alphabet stays digits only and the weight vector is unique to this tax reference. Use it for format hygiene only; a passing check does not prove that HMRC has issued the number, that it belongs to a particular person, or that a tax return is authorised.
Where UK UTR check digits fit real systems
Accountancy practices and tax software vendors need a shared oracle that matches the weighted remainder table used in spreadsheet macros and legacy desktop tools, so a mistyped UTR fails at data entry instead of at HMRC submission. Fintech and payroll products that collect Self Assessment references for sole traders can validate on blur and show the expected leading digit when the typed check does not match, reducing support tickets about rejected filings.
Company secretarial and formation workflows store corporation tax UTRs next to Companies House numbers and can batch-validate every ten-digit column in a partner CSV before a bulk upload. Integration tests and data-quality jobs recompute the expected check digit for every row and flag rows where the stored full value no longer matches, which catches both human edits and off-by-one bugs in generators.
Product teams that already use Luhn for card-like fields or ISO 7064 for other national identifiers can still adopt this scheme where a UK tax reference specification demands the leading weighted check. Document that you store a UK UTR next to the number so you never mix it with National Insurance numbers, VAT registration numbers, or Companies House CRNs without noticing. Never use this tool to invent fake taxpayer identities for fraud; it is a format check only and does not contact HMRC.
What you can do with it
Audit Self Assessment UTR columns in bulk
Batch-validate every ten-digit UTR in a client export or CRM dump and quarantine rows whose leading check digit no longer matches the weighted remainder table.
FAQ
What is a UK UTR check digit?
It is the leading digit of a ten-digit Unique Taxpayer Reference, computed from the nine body digits with weights 6,7,8,9,10,5,4,3,2 and a modulus-eleven remainder table (11 − remainder, with remainder 0 → 0 and remainder 1 never issued).
What happens with letters, spaces, or wrong length?
Compute requires exactly nine digits; validate requires exactly ten. Failed validation tasks are not billed.
Is the UK UTR check digit tool free?
The browser tool is free and runs locally.
How is the UK UTR check digit calculated?
Multiply the nine body digits by 6, 7, 8, 9, 10, 5, 4, 3 and 2, add the results and take the remainder after dividing by 11. Remainder 0 gives 0; remainders 2 to 10 give 9 down to 1. For 123456789 the sum is 230, remainder 10, check digit 1.
Does a correct check digit prove a UTR is genuine?
No. It only shows the number is well formed. A passing check does not prove that HMRC issued it, that it belongs to a particular person or that a tax return is authorised; it just catches typing mistakes early.
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/utr-uk \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"number":"123456789"}'const res = await fetch("https://api.kit.forhosting.com/enc/utr-uk", {
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/utr-uk",
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/utr-uk", 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/utr-uk", 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.utr_uk",
"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, wrong lengths, and bodies that would require a two-digit check value fail with a clear invalid_input error. Run it free in the browser or call the KIT API at the published price; both paths share the same pure arithmetic with no network and no stored taxpayer data.
How the UK UTR check digit and remainder table work
This tool always names the algorithm as uk-utr-weights-mod11 in the JSON so downstream systems can record which scheme protected the value.
How to compute a check digit or validate a full UTR
Send a number field that contains only characters zero through nine after optional spaces or hyphens are stripped. Empty strings, missing number, invalid mode values, nine digits in validate mode, and ten digits in compute mode fail before the walk completes and are not billed. Letters, decimal points, scientific notation, and other punctuation are rejected as non-numeric input with invalid_input so you never accept a silently cleaned garbage string. Mode compute is the default: provide exactly nine body digits, and the engine returns check_digit as a one-character string, with_check as the ten-digit UTR with the check digit prepended, plus weighted_sum and remainder for audit trails. Mode validate expects a full ten-digit UTR: the response reports valid true when the leading digit matches the remainder-table value for the body, and always includes check_digit, body without the leading digit, weighted_sum, remainder, and expected_check_digit when a legal expected value exists. Bodies whose weighted sum leaves remainder one cannot produce a single-digit check value: compute mode rejects them with invalid_input, and validate mode reports valid false. Because the path is pure parse with no clock, random source, or network, the same input always yields the same JSON on the free browser tool and on the API. At $0.002 per successful request you can protect bulk CRM imports, Self Assessment onboarding forms, and partner file audits without negotiating a custom tier. Prefer compute when you mint or complete a body you already control; prefer validate when a user, scanner, or CSV column supplies a full ten-digit UTR and you need a boolean gate before looking up the record.
Integration use cases
Complete a nine-digit UTR body with its check digit
When your system holds the nine body digits of a Unique Taxpayer Reference, call compute mode and store with_check so every record carries a well-formed ten-digit UTR before forms or letters are printed.
Validate typed or imported full UTRs at entry
When a user or CSV row submits a ten-digit UTR, call validate mode and block lookup when valid is false, optionally showing expected_check_digit to help correct a single mistype.
Technical questions
How do I compute a UTR check digit with this API?
POST with number set to the nine body digits and mode compute (or omit mode). The response includes check_digit, with_check (leading check plus body), weighted_sum, and remainder.
How do I validate a full Unique Taxpayer Reference?
POST with the full ten-digit UTR (optional spaces or hyphens) and mode validate. The response includes valid, check_digit, expected_check_digit when applicable, body, weighted_sum, and remainder.