Docs
PATH ID
Subjects, verified identifiers and portable attestations — the pillar that answers who someone is without moving their documents.
LIVE partially — subjects and identifiers are implemented; signed attestations are DRAFT.
What it is for
Verification is expensive and gets repeated. A customer verified by one institution arrives at another and does it all again — same documents, same wait, same abandonment rate. Not because the first verification was inadequate, but because there is no way to carry it that the second institution can check.
PATH ID moves attestations, never documents. The regulated issuer stays the regulated party; the protocol carries a signed statement about what it established, and nothing more.
Three layers, kept apart
This is the part to get right. Most identity failures in payment systems come from merging two of these.
| Layer | Question | What goes wrong if merged |
|---|---|---|
| Authentication | Is this session the subject it claims? | A signed-in user is treated as having a verified phone number |
| Identifiers | Does the subject control this identifier? | An unverified number is indexed, and someone else becomes reachable at it |
| Consent | Did they agree to this disclosure, to this party? | Verified silently means findable, and nobody opted in |
Three separate records. A disclosure requires all three, and an implementation that stores them in one table will eventually make one of the mistakes in the right-hand column.
The subject
{
"id": "sub_9f2c41a8",
"subject_type": "natural_person",
"created_at": "2026-09-09T10:00:00Z"
}Carries no personal data. Names, dates of birth and documents stay in the operator's own systems, referenced by an internal key the protocol never sees. A subject is a hook to hang identifiers and addresses on, not a profile.
subject_type is natural_person or legal_entity, and the distinction is load-bearing: a legal
entity's identifiers are public by nature, an individual's are not. See
discoverability defaults below.
Identifiers
An identifier is something the world already uses to refer to a subject. PATH does not invent new ones.
| Type | Form | Notes |
|---|---|---|
phone | E.164 — +221771234567 | Normalisation is part of the protocol |
email | Lower-cased, trimmed | |
bank_account | iban:… or bban:… | Scheme in the value, never inferred from a country |
lei | 20 characters, ISO 17442 | The global identifier for a legal entity |
reg | reg:COUNTRY:REGISTRY:VALUE | The registry is always named |
tax | tax:COUNTRY:VALUE | VAT, TIN and equivalents |
reg:SN:RCCM:… and reg:SN:NINEA:… are two different identifiers of the same Senegalese company.
Encoding only the country would make them indistinguishable, and where two registries in one country
use overlapping numeric formats it would collide two different companies onto one entry. Name the
registry.
There is deliberately no siret type. A SIRET is a value of the French SIRET registry. A protocol
that puts one country's registry at the top level is that country's protocol.
Normalisation is normative
Two implementations that normalise differently produce different hashes for the same person, and the
directory silently splits in two — with no error anywhere. +221 77 123 45 67 and +221771234567
must produce the same entry.
Verification
{
"identifier_type": "phone",
"verified_at": "2026-09-09T10:02:00Z",
"verification_method": "otp_sms"
}verified_at is set only when a method is stated. An unverified identifier may still be registered
— it is useful for matching — but a counterparty reading an attestation can tell the difference,
which is the only reason to record it.
Reasonable methods per type: a one-time code for phone, a confirmation link for email, a
micro-deposit or a payee-name check for bank_account, a registry lookup plus documents for company
identifiers.
Discoverability defaults
Per entry, because the threat is not the same per type:
| Type | The actual threat | Default |
|---|---|---|
phone | A small, dense space — someone simply tries every number | network |
email | Not enumeration: replay of a breach list, hundreds of millions at once | network, separate budget |
bank_account | Enumerable once the bank is known; already printed on invoices | private |
lei, reg, tax | The value is already public by construction | public |
A migration must never move an entry towards public. Someone becoming publicly findable without
asking is the one error here that cannot be walked back.
Withdrawal
Applies at the subject level and removes every identifier at once.
Someone who opts out expects to disappear everywhere. A per-entry toggle that leaves them findable by email after they removed their phone number is a promise half kept, which is worse than none.
Attestations
DRAFTA signed statement by an issuer about a subject.
{
"kind": "attestation",
"subject": "sub_9f2c41a8",
"claim": "kyc_level",
"value": "standard",
"issuer": "member-slug",
"issued_at": "2026-09-09T10:00:00Z",
"expires_at": "2027-09-09T10:00:00Z",
"revocation_ref": "https://api.example.com/.well-known/path-revocations",
"kid": "op_example_2026_01",
"signature": "…"
}Three rules that matter more than the shape:
Never settle on a cached credential status. Revocation is checked at execution, not at issuance. A credential valid this morning may be revoked now, and "we checked recently" is not a defence.
An attestation is a claim, not a document. It says a level was established, by whom and when. It never carries the underlying evidence.
Expiry is mandatory. An attestation without one is a claim about the past presented as a claim about the present.
Selective disclosure — proving "over 18" without revealing a birth date — is RESERVED. It is a real goal and a poor reason to block a first version.
What PATH ID is not
It is not a KYC provider, an identity wallet, or a replacement for regulated verification. It is the envelope that lets an existing verification travel and be checked by someone who was not there.