A shape is not evidence. Nine digits describes a bank account and equally well an invoice number, a policy number and a customer ID — so what separates a detection you can act on from a guess that destroys a document is whether there is a checksum underneath it. This is the full list, with the check each one gets.
Talk to our technical team →
— or read the live list, unauthenticated, at GET /api/v1/pii-types.
On by default, because every one of these is either checksum-validated or structurally distinctive enough to be safe on a document nobody has classified.
| Type | Shape | Check | Default |
|---|---|---|---|
aadhaar | 12 digits | Verhoeff check digit. A twelve-digit run that fails it is a misread, not a number. | on |
vid | 16 digits | Virtual ID. Rejected if the first twelve form a valid Aadhaar, since that is an Aadhaar number plus four digits. | on |
pan | AAAAA9999A | Structural. The fourth character encodes holder type and is reported, never enforced. | on |
passport | A9999999 | Indian format. One letter, seven digits, excluding Q, X and Z. | on |
voter_epic | AAA9999999 | Structural. | on |
driving_licence | State + RTO + 11 digits | Structural. | on |
gstin | 15 characters | Embeds a PAN, which is what makes it distinctive. | on |
ifsc | AAAA0BBBBBB | The zero in position five is fixed. | on |
phone_in | [6-9] + 9 digits | Optional +91. Indian mobile series only. | on |
bank_account | 9–18 digits | None. See the warning below. | off |
Available and off by default. The
default set is what runs on a document nobody has classified, and widening it would change
what every existing integration redacts without anyone having asked — on a product
where a wrong redaction cannot be undone. Enable them with types=global.
| Type | Shape | Check | Default |
|---|---|---|---|
iban | AA99 + 11–30 | ISO 13616 mod-97. Move the first four characters to the end, map letters to numbers, and the integer must be 1 mod 97 — a 1-in-97 chance of a random string passing. The strongest check here. | off |
credit_card | 13–19 digits | Luhn plus a real issuer prefix. Luhn alone passes one random string in ten, so both are required. | off |
eu_vat | Country + 8–12 | The two-letter country prefix is what makes it distinctive. Covers the EU, plus GB and XI. | off |
uk_nino | AA999999A | Impossible prefixes excluded — BG, GB, NK, KN, TN, NT, ZZ — plus the letters that never appear. Without these it matches any two-letter reference code. | off |
phone_e164 | + + 8–15 digits | The leading + is doing the work. Without it this is any long number. | off |
us_ssn | 999-99-9999 | No checksum exists. Structural rules only: no 000, 666 or 9xx area, no 00 group, no 0000 serial. | off |
email | Anything address-shaped | Universal. On by default in both sets. | on |
bank_account and us_ssn have no checksum and no distinguishing
shape. Nine digits describes a social security number, an invoice number, a policy number and
a customer ID equally well. Enabled on an unclassified document they will match all of them,
and unlike a missed identifier a wrong redaction cannot be undone — it destroys the
document you were trying to make shareable. Turn them on where you already know what you are
processing, and nowhere else.So you do not list six identifiers to get a sensible set
for where you operate. Pass a group name to types; it expands to its members, and
you can mix a group with individual types.
indiaThe current default set: Aadhaar, VID, PAN, passport, voter EPIC, driving licence, GSTIN, IFSC, Indian mobile and email. Named so it can be asked for explicitly rather than relied on implicitly.
globalEverything not tied to one country's document formats: IBAN, payment cards, EU and UK VAT, UK National Insurance, E.164 phone and email. Deliberately excludes us_ssn, for the same reason bank_account is excluded from the Indian defaults.
allEvery type this API knows, including the two that are unsafe on an unclassified document. For a caller who knows exactly what they are sending.
curl -X POST https://api.maskaadhaar.com/api/v1/redact-pii \ -H "X-API-Key: $MASKAADHAAR_KEY" \ -F "file=@invoice.pdf" \ -F "types=global" \ --output redacted.pdf
GET /api/v1/pii-types returns this table as JSON and
needs no authentication, so you can read the current list — and the groups —
before a key is issued, rather than trusting this page to stay in step.
Detection on an unclassified document is not a search problem, it is a false-positive problem. A missed identifier leaves a document no worse than it arrived. A wrong one covers something that mattered, and nobody can put it back.
So the bar for being on by default is not “does this pattern usually mean that identifier”. It is: can a wrong match be ruled out?
bank_account and us_ssn have, which is why they are off.Because a shape alone is not evidence. Nine digits describes a bank account and also an invoice number, a policy number and a customer ID. A checksum turns a guess into a check: a twelve-digit run that fails the Verhoeff test is a misread, not an Aadhaar number, and a wrong redaction cannot be undone.
Luhn passes roughly one random digit string in ten, which is nowhere near safe on a document nobody has classified. It has to be combined with a real issuer prefix — a leading 4, 34, 37, 5x, 2x or 6x — before a 13-to-19 digit run can be treated as a card number.
The Indian set: Aadhaar, VID, PAN, passport, voter EPIC, driving licence, GSTIN, IFSC, Indian mobile numbers and email addresses. Non-Indian identifiers are available but off by default, so an existing integration's behaviour never changes without being asked.
Pass types=global, which enables IBAN, payment cards, EU and UK VAT numbers, UK National Insurance numbers, E.164 phone numbers and email addresses. You can also name individual types, or mix a group with specific ones.
Because they have no checksum and no distinguishing shape. A US social security number is nine digits and an Indian bank account is nine to eighteen, which describes a great many ordinary reference numbers. Detecting them on an unclassified document would destroy the documents it was meant to make shareable.
Tell us which one and which document it is printed on. A type with a checksum behind it is usually a day's work; the constraint is knowing what a false positive would cost you.