Argentine CUIT/CUIL check digit
Enter 20-12345678 and get check digit 6, so the full CUIT is 20-12345678-6; type 20-12345678-7 instead and validation fails. It catches keying errors in invoices, supplier records and payroll files before they cause trouble. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Cuit
- 20-12345678
- Calculation mode
- Compute
- Input
- 2012345678
- Check digit
- 6
- With check
- 20123456786
CUIT and CUIL numbers identify people and companies for tax, payroll, and banking workflows in Argentina. Each eleven-digit code ends with a single check digit derived from a fixed weighting of the first ten digits under the AFIP (Administración Federal de Ingresos Públicos) rule. A mistyped body digit or a swapped pair often breaks that checksum, so validating the check digit before posting an invoice, opening a supplier record, or accepting a payroll file catches many keying errors early.
What the Argentine CUIT/CUIL check digit is and how the weights work
A CUIT (Clave Única de Identificación Tributaria) or CUIL (Clave Única de Identificación Laboral) is an eleven-digit identifier used across Argentine tax, social security, banking, and commercial systems. The printed form is usually XX-XXXXXXXX-X: a two-digit type prefix, an eight-digit body (often a document number), and a final check digit.
That last digit is not decorative — it is computed so that a weighted sum of the first ten digits, using the fixed multipliers five, four, three, two, seven, six, five, four, three, and two from left to right, yields a value whose remainder modulo eleven determines the check. After summing digit times weight for each position, the algorithm takes eleven minus (sum modulo eleven).
If the result is eleven the check digit is zero; if the result is ten the check digit is nine; otherwise the result itself is the check digit. When someone types 20-12345678-6 as 20-12345678-7, the sum no longer matches and validation fails. The same rule catches many single-digit substitutions in ERP imports, e-invoicing gateways, and HR onboarding forms where operators re-key numbers from paper or PDFs.
This tool implements that standard AFIP weighting on pure digits after optional hyphen stripping. It does not query AFIP, prove that a taxpayer exists, or assign a type code — only that the digit string is consistent under the published check algorithm. Compared with Luhn mod-10 used on cards and general account strings, the CUIT scheme uses a fixed left-to-right weight vector and modulo eleven, so you must not reuse a Luhn validator on CUIT fields.
Compared with Brazilian CPF or Mexican RFC helpers, the Argentine rule is specific to this eleven-digit layout and these ten multipliers. Knowing which scheme you need avoids false confidence when a general check-digit utility accepts a digit string that is not a well-formed CUIT or CUIL.
Where CUIT check digits fit tax, payroll, and commercial workflows
Electronic invoicing and billing systems store a customer or vendor CUIT on every legal document; a single mistyped digit during onboarding can send fiscal XML to the wrong party or fail AFIP authorization later. Payroll and HR platforms attach a CUIL to each employee; batch-importing national ID files often produces off-by-one errors that a check digit catches before the first payslip run.
Banks and payment gateways that accept Argentine tax IDs for KYC or transfer metadata can recompute the check digit without calling an external registry, filtering OCR noise and partial captures early. Product teams that already expose general Luhn or ISO 7064 check tools should still use this CUIT-specific capability for Argentine tax ID fields so weights, length bounds, and hyphen formatting match the domain.
Do not treat a passing CUIT check digit as proof that the person or company is correctly identified, active with AFIP, authorized to invoice, or present in any official registry — it only proves the digit string is consistent under the Argentine CUIT/CUIL check algorithm.
What you can do with it
Audit CUIT columns in partner and payroll files
Batch-validate every CUIT/CUIL in a CSV import and quarantine rows whose check digit no longer matches the recomputed expected value.
FAQ
What is the Argentine CUIT/CUIL check digit?
It is a single trailing digit computed with AFIP weights 5,4,3,2,7,6,5,4,3,2 over the first ten digits, then modulo 11 (with 11 mapping to 0 and 10 mapping to 9), so most single-digit typos break the checksum.
What happens with letters, spaces, or wrong length?
Provide digits 0-9 only (optional hyphens); compute needs ten digits and validate needs eleven. Failed validation tasks are not billed.
Is the CUIT check digit tool free?
The browser tool is free and runs locally.
What happens when the calculation gives 10 or 11?
The rule takes 11 minus the weighted sum modulo 11. A result of 11 becomes a check digit of 0, a result of 10 becomes 9, and any other result is the check digit itself.
Does a valid CUIT prove that the taxpayer exists?
No. The tool does not query AFIP or any registry of taxpayers, and it does not assign a type prefix. A passing check only shows that the digits are consistent with the published rule.
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/cuit-argentina \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"cuit":"20-12345678"}'const res = await fetch("https://api.kit.forhosting.com/enc/cuit-argentina", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"cuit": "20-12345678"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/enc/cuit-argentina",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"cuit": "20-12345678"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/enc/cuit-argentina", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"cuit":"20-12345678"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"cuit":"20-12345678"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/enc/cuit-argentina", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"cuit": "20-12345678"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "enc.cuit_argentina",
"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
This capability computes the CUIT/CUIL check digit for a ten-digit payload (with or without the usual hyphens), or validates a full eleven-digit number that already includes the trailing digit, and it reports bad input instead of silently stripping letters or punctuation. Use it free in the browser or call the KIT API at the published price; both paths run the same deterministic arithmetic with no network lookup and no registry of real taxpayers.
How to compute a check digit or validate a full CUIT/CUIL
Send a cuit field that contains digits zero through nine, optionally separated by the standard hyphens. Mode validate expects a complete eleven-digit number including the trailing check digit (for example 20-12345678-6 or 20123456786). Empty strings, missing cuit, invalid mode values, and wrong lengths (not ten digits for compute, not eleven for validate) fail before any weighted sum runs and are not billed. Spaces around the value are trimmed; letters, other punctuation, double hyphens, or leading or trailing hyphens are rejected as malformed input with invalid_input so you never accept a silently cleaned value. Mode compute is the default: provide exactly ten digits without the check digit (for example 20-12345678 or 2012345678), and the engine returns check_digit as a one-character string, with_check as the full eleven-digit string including that digit, and formatted as the hyphenated XX-XXXXXXXX-X form used on invoices and forms. The response reports valid true when the recomputed check digit matches the last digit, and always includes check_digit, expected_check_digit, payload without the last digit, and formatted for consistent display. 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 gate bulk supplier imports, onboarding forms, and ETL jobs without negotiating a custom tier. Prefer compute when you assemble a CUIT string from a known type prefix and document body; prefer validate when a user, partner file, or scanned label supplies a full number and you need a boolean gate before an AFIP or internal master-data lookup.
Where CUIT check digits fit tax, payroll, and commercial workflows
Validate mode at entry blocks the save when valid is false and can show expected_check_digit so the clerk corrects the form before the record is written.
Integration use cases
Gate CUIT fields on supplier and customer forms
When a user submits a full CUIT, call validate mode and block the save when valid is false, showing expected_check_digit to help correct a single mistype before the ERP record is written.
Compute check digits when minting or completing IDs
From a type prefix and eight-digit body, call compute mode and store with_check or formatted so every new CUIT/CUIL string carries the correct trailing digit before print or export.
Technical questions
How do I compute a CUIT check digit with this API?
POST with cuit set to the ten payload digits (hyphens optional) and mode compute (or omit mode). The response includes check_digit, with_check, and formatted as XX-XXXXXXXX-X.
How do I validate a full CUIT or CUIL?
POST with the full eleven-digit string and mode validate. The response includes valid, check_digit, expected_check_digit, payload, and formatted.