DEV Community

DSP
DSP

Posted on

DigitProof: one API for every check digit, and it fixes the wrong ones

Every codebase I have ever worked in has a graveyard of half-remembered validation rules. The IBAN check is mod-97, but only after you rearrange the string. The ISBN-10 check digit can be the letter X. A VIN has a check digit at position 9, unless it was built for a market that does not use one. Each identifier has its own standard, its own math, and its own way of quietly going wrong.

DigitProof is my attempt to put all of that in one place. It is a single API that validates nine families of structured identifiers, parses them, and, this is the part I actually wanted, tells you the correct check digit when the one you have is wrong.

What it validates

  • IBAN: length and structure for 86 countries, mod-97 check digits, BBAN parsing (bank code, branch code, account number) for 22 countries, SEPA flag, grouped formatting
  • LEI: the ISO 17442 format and its mod-97 check digits, with the LOU prefix broken out
  • ISIN: country and NSIN structure with the Luhn check digit
  • ISBN-10 and ISBN-13, including conversion between them
  • GTIN-8, UPC-A, EAN-13, and GTIN-14, detected from length
  • VIN: 17 characters, the North American position-9 check digit, make hints and model year decoding
  • Payment cards: Luhn, brand detection, and the networks' published test numbers flagged as test_only
  • UUID: version and variant parsing
  • EU and GB VAT numbers: per-country formats, with check digits verified where a country defines them

It is format and checksum validation only. There are no bank directories or registry lookups behind it, and the listing says so plainly. A valid result means the identifier is well-formed and its math checks out.

A taste

Send a known-good IBAN:

curl -X POST "https://digitproof.p.rapidapi.com/v1/validate" \
  -H "X-RapidAPI-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"value": "GB29 NWBK 6016 1331 9268 19"}'
Enter fullscreen mode Exit fullscreen mode

You get back the parsed structure, not just a yes:

{
  "type": "iban",
  "valid": true,
  "details": {
    "country_code": "GB",
    "sepa": true,
    "bank_code": "NWBK",
    "branch_code": "601613",
    "account_number": "31926819",
    "formatted": "GB29 NWBK 6016 1331 9268 19"
  }
}
Enter fullscreen mode Exit fullscreen mode

Now the interesting part. Change the last digit of that account number and the checksum fails, and instead of a bare false you get the expected check digits and the corrected identifier:

{
  "valid": false,
  "errors": [
    { "code": "bad_checksum", "expected_check_digits": "56", "actual_check_digits": "29" }
  ],
  "correction": "GB56NWBK60161331926818"
}
Enter fullscreen mode Exit fullscreen mode

There is also a dedicated check-digit endpoint that computes the digit even when the check position holds a placeholder, auto-detection if you do not know what kind of identifier you are holding (a 13-digit 978 number comes back as both ISBN-13 and GTIN-13), and batch validation for up to 100 identifiers per call.

How it is built

FastAPI on the free tier of Render, with the validation logic kept pure and separate from the web layer. Every validator runs on published standards and official test vectors, and the test suite caught me three real math bugs before launch, including one in the French VAT key formula. The API is stateless and stores nothing: values are processed in transit and forgotten.

Pricing

Every endpoint is available on every plan, including the free tier. The validate, batch, check-digit, and types endpoints are all there from the start, with no Pro-only identifier types and no correction feature held back to force an upgrade. Upgrading simply gets you more requests per month: start free with 150 requests a month (and remember, one request can carry a batch of 100), move up to Pro at $9/month for 5,000, Ultra at $19/month for 20,000, or Mega at $49/month for 100,000. You pay for volume, not for access.

The listing is here: https://rapidapi.com/darksundarker/api/digitproof

Feedback very welcome, especially the "I wish it also validated X" kind. That is how the next identifier on the list gets chosen.

Top comments (0)