A Legal Entity Identifier is twenty characters, and the last two of them are a check digit computed with ISO 7064 MOD 97-10 — the same arithmetic that validates an IBAN. That makes it tempting to treat the identifier as self-verifying: run the sum, get a true, move on. The sum is worth running, and it is worth running in your own form before you spend anything. But it settles one question and not the one most integrations think it settles. This guide is about which is which, and how the answer keeps them apart.
What the arithmetic actually does
Each character of the identifier becomes its base-36 value, the whole string is read as one very long number, and a correctly formed identifier leaves a remainder of 1 when divided by 97. The number runs far past what a 64-bit integer holds, so it is accumulated digit by digit; that is the only subtlety in it. There is no lookup, no network call and no dataset — the check is pure arithmetic over the twenty characters in front of you.
What that catches is a mistyped or transposed character. Someone reads an identifier off a PDF, swaps two digits, and the remainder stops being 1. Someone pastes nineteen characters because the twentieth fell off the end of a spreadsheet cell, and the string is not an identifier at all.
What it cannot catch is everything else. A check digit says the string is well formed. It does not say the identifier was ever issued, or issued to the company whose name sits beside it in your database, or that the registration behind it is still current. Those are register questions, and only a register answers them.
The measurement, and the three exceptions
It is fair to ask how solidly the checksum holds on real data, because a rule that fails on live records is worse than no rule.
Measured against the published register on 8 September 2026: of 45,515 consecutive real identifiers, 45,512 satisfy the checksum. The three that do not are all ANNULLED registrations — identifiers issued in error and withdrawn afterwards.
So a record can exist in the register with a failing check digit. That is precisely why Spaw reports checksum_valid beside the register answer rather than letting one stand in for the other: found: true with checksum_valid: false is a real state, and it tells you something specific — this identifier is carried, and it was probably issued in error.
Four fields, four questions
| Field | Question it answers | Where it comes from |
|---|---|---|
checksum_valid |
Is this string a well-formed identifier? | Arithmetic over the characters. null for identifiers that carry no check digit — a UK company number has none. |
found |
Does a register on this server carry it? | A read of the synced register file. |
registration_status |
Has anyone renewed the registration? | The register's own status: ISSUED, LAPSED, RETIRED, ANNULLED, MERGED, DUPLICATE. |
status |
Is the entity behind it still live? | The register's status for the entity, folded to active, inactive, dissolved or unknown. |
Reading those four as one fact is the mistake this product is designed to make hard. An entity can be alive with a lapsed registration; an identifier can be well formed and never issued; a record can exist with a bad check digit. Each field is reported on its own so you can branch on the one you actually care about.
The four ways an answer says no
found: false always carries a reason, and the four are not interchangeable.
reason |
What happened | What it does not mean | Cost |
|---|---|---|---|
malformed_identifier |
The string never reached a register: not twenty characters of the permitted alphabet, or a company number longer than the register's eight. | Nothing about any company. | Free |
unknown_identifier |
A register answered, and carries no such row. | That the entity does not exist. It means this register does not carry it. | Free |
unsupported_register |
No register is installed for that identifier type, or that country. Company numbers are unique only inside their own register, so GB is the one installed today. |
That the number is wrong. | Free |
register_unavailable |
The register is installed but has not been synced, so there is nothing to read. | Anything at all about the identifier. | Free |
Every one of those is free, because none of them told you something you could not have worked out. Only an answer a register gave costs a credit.
And none of them is a verdict on the company. Write your integration so that found: false reads as this server could not answer, never as this entity is not real. The reasons above are the whole difference between an honest gap and an accusation.
Validate before you spend
Because the checksum is public arithmetic, you can run it yourself at the point of entry. That is the cheapest possible improvement to a form that asks for an identifier: reject the typo where the person can still see what they typed, and send only well-formed identifiers to an API.
Two things to keep in mind if you do.
A valid check digit is not a reason to skip the lookup. It only means the string could be an identifier. The register answers whether it is one.
A UK company number has no check digit at all. Nothing can be validated offline there beyond its shape. What Spaw does with it is normalise it the way the register writes it: punctuation dropped, case folded, left-padded with zeros to eight characters, so 445790 and 00445790 are the same company. Anything longer than eight is a malformed_identifier. If you key your own records on a company number, pad them the same way, or you will hold one company twice.
Where the answer comes from, and what it is not
Identifier reference data is published by the Global Legal Entity Identifier Foundation under a CC0 1.0 public-domain dedication, as a golden copy refreshed daily. Spaw syncs that file and answers from its own copy, so nothing about your lookup leaves this server. Spaw is not affiliated with, endorsed by or connected to that foundation in any way, and an answer here is Spaw's rather than theirs.
The response also carries nothing that would locate anybody. There is no registered address in it and there will not be: a registered address is very often somebody's home, and an identifier on its own does not say whether a limited company or a sole trader stands behind it. The lookup answers "is this a real, live entity" and stops there.
sources names every register behind the answer with the date of the copy it read. Check it whenever the age of a record could matter to the decision you are about to make.
What to do next
- Run an identifier through the free company lookup and read
checksum_valid,foundandregistration_statusas three separate answers. - Read the business verification guide for every field and every reason.
- Check the request and response shape on the POST /api/v1/entity reference.
- See what happens when a LEI record and a national register describe the same company differently in when two registers disagree about a company.