ForHosting KIT · Developer Utilities

Mexico CURP check digit

Enter HEGG560427MVZRRL0 and get check digit 4, so the full CURP is HEGG560427MVZRRL04; or paste all 18 characters to see whether the last digit matches. Useful for payroll, school enrolment and bank sign-ups. Free in your browser.

  • Free
  • Runs in your browser
  • No sign-up
  • Your data stays on your device
Use it from WebAPIEmailTelegramApp soon
If you enter
Curp
HEGG560427MVZRRL0
You get
Calculation mode
Compute
Input
HEGG560427MVZRRL0
Check digit
4
Curp
HEGG560427MVZRRL04

The Mexican CURP (Clave Única de Registro de Población) is an eighteen-character personal identifier used across banking, payroll, healthcare, schooling, and government forms in Mexico. Seventeen characters encode name, birth date, sex, state, and a homoclave; the eighteenth is a check digit derived from a fixed value table so that single mistypes and many garbled strings fail instead of looking like another valid registration. This capability computes that check digit from a pure seventeen-character base, or validates a complete eighteen-character CURP and reports whether the stored digit matches the recomputed value.

How the Mexican CURP check digit is calculated

A CURP is always eighteen alphanumeric characters when written without punctuation. The first seventeen form the base key; the eighteenth is the dígito verificador. Each character maps to an integer from zero through thirty-six using the official dictionary order: digits zero through nine, then letters A through N, then Ñ, then O through Z.

For every position i from zero through sixteen, the character value is multiplied by the weight eighteen minus i, so the first character is weighted by seventeen and the seventeenth by one. Those products are summed, the sum is reduced modulo ten, and the check digit is ten minus that remainder—or zero when the remainder is already zero (equivalently, when ten minus the remainder would be ten).

Validation is the inverse: recompute the digit from the first seventeen characters and compare it to the last character, which must itself be a decimal digit.

Audit CURP columns in bulk exports

Batch-validate every CURP in a payroll CSV or ERP extract and quarantine rows whose check digit no longer matches the recomputed value.

What is the Mexican CURP check digit?

It is the eighteenth character of a CURP, computed from the first seventeen with the official 0–36 value table and weights 18 down to 2, so single-character typos and many garbled strings are far more likely to fail validation than to look like another registration.

What happens with spaces, hyphens, or wrong lengths?

Failed validation tasks are not billed. Strip formatting in your client before calling.

Is the Mexico CURP check digit tool free?

The browser tool is free and runs locally.

What do the first 17 characters of a CURP encode?

They are built from the person's name, birth date, sex and state, followed by a homoclave. Only the eighteenth character is a check digit, computed from those seventeen.

Why does the letter Ñ matter in the calculation?

Each character gets a value from 0 to 36 in the official order: digits 0 to 9, letters A to N, then Ñ, then O to Z. Leaving Ñ out would shift the value of every letter after it.

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.

POSThttps://api.kit.forhosting.com/enc/curp-mexico

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.

curl -X POST https://api.kit.forhosting.com/enc/curp-mexico \
  -H "Authorization: Bearer $KIT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"curp":"HEGG560427MVZRRL0"}'
{
  "curp": "HEGG560427MVZRRL0"
}
{
  "task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
  "type": "enc.curp_mexico",
  "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.

Per request$0.002

Published price — no tokens, no invented credits. A failed task is never charged.

HTTPCodeMeaning
401unauthorizedMissing or invalid API key.
402insufficient_balanceYour balance doesn't cover the task price.
404unknown_typeThat task type doesn't exist.
429rate_limitedToo many requests. Use the webhook instead of polling.

Non-CURP characters, wrong lengths, and empty input are rejected with a clear invalid_input error. Run it free in the browser or call the KIT API; both paths share the same pure arithmetic with no network round-trip and no stored registries of living persons.

How the Mexican CURP check digit is calculated

Because the algorithm is pure integer modular arithmetic with a fixed table, the same seventeen characters always produce the same check digit on every platform—browser, Worker, or offline test harness—which is why the capability ships as a tier-A parse engine rather than a model call.

How to compute the check digit or validate a full CURP

Send a curp field that contains only letters A–Z, the letter Ñ, and digits zero through nine. Mode validate expects exactly eighteen characters. Empty strings, missing curp, invalid mode values, and wrong lengths (for example sixteen or nineteen characters) fail before any weighted sum runs and are not billed. Spaces, hyphens, dots, and other punctuation are rejected as non-CURP input with invalid_input so a form never accepts a silently cleaned value—strip formatting in your client if users paste a spaced or hyphenated string. Mode compute is the default: provide exactly seventeen base characters; the engine returns check_digit as a single character, curp as the full eighteen-character code, and length eighteen. The response reports valid true only when the trailing digit matches the recomputed expected_check_digit; it always includes base (the first seventeen characters), check_digit as submitted, expected_check_digit, and the canonical curp built from base plus expected digit. That shape makes it easy to show “you typed X, expected Y” in a KYC or signup UI without a second request. 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, partner file audits, and form gates without negotiating a custom tier.

Where CURP check digits fit real product workflows

Mexican fintech and marketplace onboarding flows ask for a CURP early; validating the check digit on blur reduces failed submissions and support tickets without calling RENAPO for every keystroke. Payroll and HR systems import employee CSVs and should quarantine rows whose eighteenth character no longer matches, which catches both human edits and off-by-one bugs in upstream generators. Do not treat a passing check digit as proof that the person exists in RENAPO systems or that the document is active—it only proves the eighteen-character string is arithmetically well formed under the official CURP rule, the same honesty bar you apply to any national-id checksum tool. Healthcare and school enrollment portals that accept CURP as a citizen key can block proceed until valid is true and show expected_check_digit when the digit is wrong. Data-quality jobs recompute expected_check_digit for every CURP column in an export and flag mismatches before they reach billing or fiscal reporting.

Complete seventeen base characters for fixtures and forms

Take a seventeen-character base from a test plan or partial record, call compute mode, and store or display the full eighteen-character curp with the check digit appended.

Validate typed or imported CURPs at entry

When a signup form, CRM import, or partner API submits eighteen characters, call validate mode and block storage when valid is false, showing expected_check_digit to fix a mistype.

How do I compute a CURP check digit with this API?

POST with curp set to exactly seventeen characters and mode compute (or omit mode). The response includes check_digit and curp (the full eighteen-character code).

How do I validate a full eighteen-character CURP?

POST with the eighteen-character string and mode validate. The response includes valid, check_digit, expected_check_digit, base, and the canonical curp.

Read the full KIT documentation →