Document Number Validator
Check whether a document number is well-formed for its jurisdiction, before you create a session or submit a verification. Nothing is stored and no verification is consumed.
Endpoint: POST /v1/validators/document-number
Authentication: Bearer token with the sessions scope
A stateless format check against the same registry the verification pipeline uses. Nothing is stored and no verification is consumed β but it accepts government identifiers, so it is attributed to a tenant like every other endpoint here. Useful for validating input in your own form before creating a session.
curl --request POST \
--url https://{FQDN}/v1/validators/document-number \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header 'Content-Type: application/json' \
--data '{
"documentType": "drivers_license",
"number": "31612967",
"issuingCountry": "USA",
"issuingState": "PA"
}'
{
"documentType": "drivers_license",
"issuingCountry": "USA",
"issuingState": "PA",
"valid": true,
"rule": "drivers_license:USA:PA",
"detail": "document number matches the PA license format"
}
The number you send is never echoed back. The response reports the jurisdiction that was applied, not the identifier you submitted.
What Is Covered
| Country | drivers_license | passport | identity_card | ssn / itin |
|---|---|---|---|---|
| πΊπΈ United States | β 51 jurisdictions (50 states + DC) | β | β | β structural rules |
| π¨π¦ Canada | β 13 jurisdictions (10 provinces + 3 territories) | β | β | β |
| π§π· Brazil | β CNH β check digits verified | β | β CPF β check digits verified | β |
| π²π½ Mexico | β | β | β CURP β structure | β |
| πͺπΈ Spain | β | β | β DNI/NIE β control letter verified | β |
| π 11 more countries | β | β | β | β |
| π Everywhere else | β | β generic ICAO shape | β | β |
The 11 additional passport countries, as the issuingCountry you send: ARG, AUS, CHN, DEU, FRA, GBR, IND, ITA, JPN, NLD, RUS.
Anything not marked β β inside the table or beyond it β returns valid: null, never false. Treat a null as "we do not know": accept it, and do not read it as either a pass or a fail.
The CNH, CPF and DNI/NIE are checked with real check-digit arithmetic, so a transposed digit is caught β unlike the licence tables, which are shape-only because those jurisdictions publish no check digit.
Naming the Jurisdiction
issuingCountry is the country β an ISO 3166-1 alpha-3 code, a country name, or a common alias. issuingState is a subdivision within that country β a US state or a Canadian province or territory β and only driver's licenses use it.
| Document type | issuingCountry | issuingState | Notes |
|---|---|---|---|
drivers_license (US) | USA | the state, e.g. PA | |
drivers_license (Canada) | CAN | the province or territory, e.g. ON | |
drivers_license (Brazil) | BRA | β | The CNH is national; the issuing DETRAN does not change the number |
passport | the issuing country | β | |
identity_card | the issuing country | β | |
ssn, itin | USA | β | US-only identifiers; any other country is a 422 |
A licence must name its country. A subdivision cannot: send issuingState without issuingCountry and the request is refused, because PA alone could be Pennsylvania or ParΓ‘ and the answer would name a jurisdiction you never supplied. Sending neither is allowed and returns valid: null β unverifiable, not invalid. Nothing infers a country: a passport or identity card without one also returns valid: null.
ssn and itin are validator-only. They are not capturable document types β you cannot create a session for one β but the structural rules are useful when you collect them on your own forms.
Interpreting the Response
valid is deliberately three-valued:
| Value | Meaning | How to treat it |
|---|---|---|
true | Matches the known format for that jurisdiction | Accept |
false | Violates the known format | Reject before creating the session |
null | No rule exists for that jurisdiction | Accept β an unknown jurisdiction is never a failure |
A null is the honest answer for a jurisdiction we have no rule for, and it is the reason coverage gaps below are safe rather than silently wrong.
rule names the rule that was applied, so you can tell which jurisdiction answered:
rule | Meaning |
|---|---|
drivers_license:USA:PA | A US license checked against Pennsylvania's format |
drivers_license:CAN:ON | A Canadian licence checked against Ontario's format |
drivers_license:BRA | A Brazilian CNH checked against the national check digits β no subdivision component, because the issuing DETRAN does not change the number |
drivers_license:USA:unknown_subdivision | A US license with no resolvable state β valid: null |
drivers_license:<country>:no_rule | A license from a country we have no license rules for β valid: null |
drivers_license:unknown_country | Neither country nor subdivision resolved β valid: null |
passport:USA | A passport checked against that country's format |
passport:generic | A passport whose number does not fit the generic ICAO shape β valid: false |
passport:no_rule | A passport from a country we have no format for β valid: null |
identity_card:ESP | An identity card checked against that country's national scheme |
identity_card:no_rule | An identity card from a country we have no scheme for β valid: null |
ssn:USA, itin:USA | The US structural rules |
Every rule names the documentType it belongs to, so the prefix maps to the type by string equality. The one exception is a sandbox reserved value, which is prefixed reserved: and carries the type in its second segment β see Sandbox and Test Data.
Errors
| Status | Cause |
|---|---|
401 | Missing or invalid Bearer token |
403 | Token lacks the sessions scope |
422 | issuingCountry could not be resolved to a country |
422 | issuingState sent for a passport or identity card β pass the country as issuingCountry |
422 | issuingState sent for a licence with no issuingCountry β a subdivision alone cannot name a jurisdiction |
422 | ssn or itin sent with a non-US issuingCountry |
503 | The identity provider could not be reached to verify the token β transient, retry with backoff |
Next Steps
- Verification Sessions β creating a session, and the
prefillthat uses this same check - Sandbox & Test Data β reserved numbers that return a chosen verdict on demand
