Skip to Content
US SSN

Validating a US SSN: less than you think, and one thing you’d miss

Most identifier validators have something to check. An IBAN has MOD-97 check digits, a Canadian SIN a Luhn digit, a Spanish NIF a control letter. A mistyped digit changes the checksum, and the validator notices.

A US Social Security Number has none of that. In the SSA’s words it “is still comprised of nine numeric digits” — an area, a group and a serial, none of them a check digit. Before 2011 the serial was simply “a straight numerical series of numbers from 0001-9999”; randomization made the digits less predictable, not self-checking. Change any digit and you usually get another perfectly possible SSN.

So SSN validation is mostly about knowing its limits. It is a cheap check — free libraries do the structural part — and it is worth exactly what it catches: impossible numbers, at the point of entry, before they reach payroll or a tax form. This page covers what it can still catch, the number it most often gets wrong, and where real verification comes from when you need proof.


What a validator can catch

The SSA does not issue certain numbers, and says so. From its randomization FAQ: SSNs are assigned “excluding area numbers 000, 666 and 900-999”, and “SSNs containing group number 00 or serial number 0000 will continue to be invalid”.

That is the whole rulebook:

RuleExample of what it rejects
Area 000000-12-3456
Area 666666-12-3456
Area 900–999912-12-3456
Group 00123-00-4567
Serial 0000123-45-0000

Add the handful of numbers voided after being printed in public — and you have everything a number can reveal about its own validity. The famous one is 078-05-1120: in 1938 a wallet maker put a sample card in every wallet it sold, using the real SSN of a company secretary. More than 40,000 people reported it as their own, and the SSA voided it. The SSA’s own 1940 pamphlet did the same with a made-up 219-09-9999.

VerifNow says which rule failed, because “invalid SSN” gives a form nothing to show:

{ "valid": false, "message": "No SSN ends with 0000", "originalValue": "123-45-0000" }

What it cannot catch

A typo. With no check digit, change one digit of a real SSN and you almost always get another possible SSN. A user who mistypes their last digit gets a valid response.

Whether the number was issued. Nothing in the digits records that.

Whether it belongs to the person in front of you. Validation says nothing about identity.

The state. Before June 25, 2011, the first three digits reflected the state where the card was applied for. The SSA’s randomization removed that: the structure “is no longer of any significance”. Any API that still returns a state from an SSN is describing numbers issued more than a decade ago, and guessing about the rest.

Treat a valid SSN as “not obviously impossible”, never as “verified”. If it matters that the number is real and belongs to the applicant, you need the SSA — below.


The number that looks like an SSN: the ITIN

An ITIN — Individual Taxpayer Identification Number — is issued by the IRS “to individuals who are required for U.S. tax purposes to have a U.S. taxpayer identification number but who do not have and are not eligible to obtain a social security number”. It has exactly the SSN’s format.

It also starts with 9, which is why a naive SSN validator rejects it as a typo. The IRS defines the range: an ITIN begins with 9, and “the fourth and fifth numbers will range from: 50-65, 70-88, 90–92, 94-99”.

What to do with one depends on the question your form is asking:

  • “What is your taxpayer number?” — for a W-9, a 1099, a contractor onboarding — an ITIN is a legitimate answer. Rejecting it turns away foreign contractors who pay US taxes.
  • “What is your SSN?” — for employment eligibility — it is not. The IRS is explicit that an ITIN does not “authorize you to work legally in the U.S.”

VerifNow keeps valid: false for an ITIN, since it is not an SSN, and names it:

{ "valid": false, "message": "That is an ITIN, not an SSN", "ssnDetails": { "itin": true } }
import { VerifNow } from '@verifnow/sdk'; const client = new VerifNow({ apiKey: process.env.VERIFNOW_API_KEY! }); /** For a W-9 style field that accepts either an SSN or an ITIN. */ export async function checkTaxpayerNumber(input: string) { const result = await client.validateSsn(input); if (result.valid) { return { ok: true as const, kind: 'SSN' as const, value: result.normalizedValue! }; } if (result.ssnDetails?.itin) { // Not an SSN, but a valid taxpayer number for this purpose. return { ok: true as const, kind: 'ITIN' as const, value: input.replace(/[\s-]/g, '') }; } return { ok: false as const, error: result.message ?? 'That is not a valid taxpayer number.' }; }

Needs @verifnow/sdk 1.6.0 or later, which models ssnDetails. For Java, io.verifnow:verifnow-spring 2.6.0 or later exposes it through getSsnDetails().


Verification is a different service

When you need to know that a number was issued and matches a name, validation is the wrong tool — and the right ones are not API keys you sign up for in an afternoon. The SSA lists them:

  • the Social Security Number Verification Service, for employers checking name and SSN for wage reporting;
  • E-Verify, run by the Department of Homeland Security, for employment eligibility;
  • eCBSV, which confirms that an SSN, name and date of birth match SSA records, and flags a death.

eCBSV is worth understanding before you plan around it. It is open only to a “permitted entity” — a financial institution as defined by the Gramm-Leach-Bliley Act, or its service provider — it requires the number holder’s written consent, and it is billed by annual tier, starting at $5,100 a year for up to 10,000 verifications. Most product teams will reach it, if at all, through an identity or KYC vendor rather than directly.

That is the real shape of the market: structural validation is close to free, verified identity is expensive and gated, and there is nothing in between. Use validation at the point of entry, to catch the impossible and name the ITIN. Buy verification only where the law or your risk requires proof.


Holding one

An SSN is a prime target for identity theft. Collect it only where you need it — payroll, tax reporting, credit, or a regulation that asks for a taxpayer number — and treat it accordingly: encrypt it, mask it on screen, keep it out of logs and analytics. Several states also restrict how businesses may use and display SSNs; check the ones you operate in.

On our side, the usage log that meters your calls stores an SSN as ***.


Testing without anyone’s SSN

Every number that clears the rules above may belong to someone. The SSA’s history of misused numbers says those confusions usually start “when someone publishes a facsimile of an SSN using a made-up number”. So:

  • use 078-05-1120 for the rejection path — it is voided, and VerifNow says so;
  • do not use 123-45-6789 as a “valid” test value. Nothing in the SSA’s rules excludes it, VerifNow accepts it, and that is exactly the problem;
  • if a test needs a possible SSN, assemble it from its three parts at run time, and do not commit it.

In short

  • An SSN has no check digit. Validation rules out impossible numbers; it cannot catch a typo.
  • The first three digits have not meant a state since 2011.
  • A number starting with 9 may be an ITIN: a valid taxpayer number, not an SSN. Decide by what your form is for.
  • For proof that a number is real and belongs to someone, use the SSA’s verification services.

Where this check belongs

Nobody should add a vendor, a key and an invoice for a structural SSN check. That is the point: it is one field on a form that already has others, and those others are where validation earns its keep — a VAT number that needs a live registry lookup, an IBAN whose country structure most validators skip, an email whose domain has to receive mail, a phone that has to exist in its country’s numbering plan.

VerifNow validates all seven — email, phone, IBAN, VAT, SIN, NIF and SSN — on one key, one quota and one bill. The SSN endpoint is not a reason to sign up. It is the reason you do not need a seventh vendor once you have.

Next: Validate SSN · Validating a Canadian SIN

Sources: SSN Randomization FAQs  (SSA) · eCBSV: eligibility, consent and fees  (SSA) · POMS RM 10201.030, Structure of the SSN  (SSA) · Social Security Cards Issued by Woolworth  (SSA) · IRM 3.21.263, ITIN Real-Time System  (IRS) · Individual Taxpayer Identification Number  (IRS)

Last updated on