Inyo

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": "dl: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

Countrydrivers_licensepassportidentity_cardssn / 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 typeissuingCountryissuingStateNotes
drivers_license (US)USAthe state, e.g. PA
drivers_license (Canada)CANthe province or territory, e.g. ON
drivers_license (Brazil)BRAβ€”The CNH is national; the issuing DETRAN does not change the number
passportthe issuing countryβ€”
identity_cardthe issuing countryβ€”
ssn, itinUSAβ€”US-only identifiers; any other country is a 422

Always send issuingCountry. A licence sent without one falls back to USA so pre-issuingCountry integrations keep working, but relying on that fallback is how a non-US licence gets checked against a US state's format. Nothing else infers a country: a passport or identity card without one 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:

ValueMeaningHow to treat it
trueMatches the known format for that jurisdictionAccept
falseViolates the known formatReject before creating the session
nullNo rule exists for that jurisdictionAccept β€” 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:

ruleMeaning
dl:USA:PAA US license checked against Pennsylvania's format
dl:CAN:ONA Canadian licence checked against Ontario's format
dl:BRAA Brazilian CNH checked against the national check digits β€” no subdivision component, because the issuing DETRAN does not change the number
dl:USA:unknown_subdivisionA US license with no resolvable state β€” valid: null
dl:<country>:noneA license from a country we have no license rules for β€” valid: null
dl:unknown_countryNeither country nor subdivision resolved β€” valid: null
passport:USAA passport checked against that country's format
passport:no_country_ruleA passport from a country we have no format for β€” valid: null
id_card:ESPAn identity card checked against that country's national scheme
ssn:USA, itin:USAThe US structural rules

Errors

StatusCause
401Missing or invalid Bearer token
403Token lacks the sessions scope
422issuingCountry could not be resolved to a country
422issuingState sent for a passport or identity card β€” pass the country as issuingCountry
422ssn or itin sent with a non-US issuingCountry

The second one is worth reading twice if you integrated before issuingCountry existed: issuingState used to carry the country for passports and identity cards. Sending it that way now is a hard error rather than a quiet null, because a null read as a pass is the worse failure.


Next Steps