EMIR & MiCA Compliance — DTI and LEI Validation for Crypto
Crypto-asset derivatives under EMIR and crypto-asset services under MiCA both require validated identifiers. Here's how to validate DTI and LEI codes for regulatory reporting — and what happens when you don't.
In this guide
- 1. EMIR and MiCA — what crypto firms need to report
- 2. DTI — identifying the digital token
- 3. LEI — identifying the counterparty
- 4. DTI validation — format + DTIF registry lookup
- 5. LEI validation — MOD-97 + GLEIF lookup
- 6. Validating both in parallel
- 7. cURL examples
- 8. Regulatory edge cases
- 9. Summary checklist
1. EMIR and MiCA — what crypto firms need to report
Two EU regulations now require crypto firms to submit validated identifiers with every report. If you trade crypto-asset derivatives or operate a crypto-asset service, you need both DTI and LEI — and both must pass validation before submission.
EMIR (European Market Infrastructure Regulation)
EMIR requires reporting of all derivative contracts to trade repositories (TRs). Since the EMIR Refit (2024), crypto-asset derivatives — Bitcoin futures, Ethereum options, stablecoin swaps — fall under the same reporting obligation as traditional derivatives.
Key reporting fields:
- Underlying asset — identified by DTI (when the underlying is a crypto-asset)
- Counterparties — both sides identified by LEI
- UPI — the Unique Product Identifier, which incorporates the DTI for crypto underliers
MiCA (Markets in Crypto-Assets Regulation)
MiCA entered into force in June 2023 (transitional) with full application from December 2024. It requires Crypto-Asset Service Providers (CASPs) to:
- Identify all crypto-assets they list or trade using DTI
- Identify themselves and their clients using LEI
- Report to NCAs with valid, unambiguous identifiers
2. DTI — identifying the digital token
A Digital Token Identifier (DTI) is a 9-character code defined by ISO 24165 that uniquely identifies a crypto-asset. The DTI uses a restricted 30-character alphabet (digits 0-9 plus 20 consonants, no vowels) and includes a check character as the 9th character.
| Token | DTI |
|---|---|
| Bitcoin | 4H95J0R2X |
| Ethereum | X9J9K872S |
| Tether USD | TNJP1WF2Z |
Two types of identifiers exist in the DTIF registry:
- DTI (Digital Token Identifier) — identifies the token itself
- DLI (Distributed Ledger Identifier) — identifies the blockchain/ledger
For EMIR: the underlying asset DTI must be included in the trade report. For MiCA: every crypto-asset listed on a CASP must have a valid DTI.
3. LEI — identifying the counterparty
A Legal Entity Identifier (LEI) is a 20-character alphanumeric code (ISO 17442) that uniquely identifies a legal entity. Every participant in a regulated transaction must have a valid, current LEI.
| Entity | LEI |
|---|---|
| Goldman Sachs | 784F5XWPLTWKTBV3E584 |
| Deutsche Bank | 7LTWFZYICNSX8D621K86 |
For EMIR: both counterparties must have active LEIs. For MiCA: CASPs must have LEIs, and institutional clients should be identified by LEI.
LAPSED registration status means the entity failed to renew. Regulators reject reports with LAPSED LEIs — always check registrationStatus before submitting.4. DTI validation — format + DTIF registry lookup
The IsValid DTI API performs two checks in a single call:
Format check
9 characters, restricted alphabet, first char ≠ 0
DTIF registry lookup
Confirms the DTI has been officially assigned
Response — Bitcoin DTI (found in registry)
{ "valid": true, "normalized": "4H95J0R2X", "payload": "4H95J0R2", "checkChar": "X", "found": true, "identifierType": "token", "name": "Bitcoin", "shortName": "BTC", "dtiType": "protocol" }
What to check for compliance
valid === true— format is correctfound === true— officially registered with DTIFidentifierType— tells you if it's a"token"(DTI) or"ledger"(DLI)
found: false is not registered with DTIF. Using unregistered DTIs in regulatory reports will be rejected.5. LEI validation — MOD-97 + GLEIF lookup
The IsValid LEI API performs a multi-step verification chain:
ISO 17442 MOD-97 checksum
Same algorithm as IBAN — remainder must equal 1
GLEIF database lookup
2.3M records from GLEIF Golden Copy — dataSource: "gleif-db"
GLEIF API fallback
If not found locally, query GLEIF REST API — dataSource: "gleif-api"
LOU resolution
Entity details, registration status, and managing LOU returned
Response — Goldman Sachs (entity found)
{ "valid": true, "lei": "784F5XWPLTWKTBV3E584", "louCode": "784F", "checkDigits": "84", "found": true, "dataSource": "gleif-db", "entity": { "legalName": "GOLDMAN SACHS GROUP INC", "country": "US", "entityStatus": "ACTIVE", "registrationStatus": "ISSUED", "category": null, "initialRegistrationDate": "2012-06-06", "lastUpdate": "2024-08-14", "nextRenewal": "2025-08-14", "managingLou": "EVK05KS7XY1DEII3R011" }, "lou": null }
What to check for compliance
valid === true— format and checksum are correctfound === true— entity exists in GLEIFentity.registrationStatus === "ISSUED"— not"LAPSED"entity.entityStatus === "ACTIVE"— entity is currently operating
6. Validating both in parallel
A crypto derivative trade report needs three validated identifiers: the underlying asset (DTI), the buyer (LEI), and the seller (LEI). Validate all three in parallel using Promise.all:
// emir-mica-validator.mjs const API_KEY = process.env.ISVALID_API_KEY; const BASE = 'https://api.isvalid.dev'; const headers = { Authorization: `Bearer ${API_KEY}` }; async function callApi(path, params) { const url = new URL(path, BASE); Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v)); const res = await fetch(url, { headers }); if (!res.ok) throw new Error(`${path}: ${res.status}`); return res.json(); } async function validateCryptoReport({ dti, buyerLei, sellerLei }) { const [dtiResult, buyerResult, sellerResult] = await Promise.all([ callApi('/v0/dti', { value: dti }), callApi('/v0/lei', { value: buyerLei }), callApi('/v0/lei', { value: sellerLei }), ]); const errors = []; // DTI checks if (!dtiResult.valid) errors.push('DTI: invalid format'); else if (!dtiResult.found) errors.push('DTI: not registered with DTIF'); // Buyer LEI checks if (!buyerResult.valid) errors.push('Buyer LEI: invalid checksum'); else if (!buyerResult.found) errors.push('Buyer LEI: entity not found in GLEIF'); else if (buyerResult.entity?.registrationStatus === 'LAPSED') errors.push('Buyer LEI: registration LAPSED — must be renewed'); // Seller LEI checks if (!sellerResult.valid) errors.push('Seller LEI: invalid checksum'); else if (!sellerResult.found) errors.push('Seller LEI: entity not found in GLEIF'); else if (sellerResult.entity?.registrationStatus === 'LAPSED') errors.push('Seller LEI: registration LAPSED — must be renewed'); return { valid: errors.length === 0, errors, dti: dtiResult, buyer: buyerResult, seller: sellerResult, }; } // ── Example: Bitcoin futures trade ────────────────────────────────────────── const report = await validateCryptoReport({ dti: '4H95J0R2X', // Bitcoin buyerLei: '784F5XWPLTWKTBV3E584', // Goldman Sachs sellerLei: '7LTWFZYICNSX8D621K86', // Deutsche Bank }); if (report.valid) { console.log('✓ All identifiers valid — ready for TR submission'); console.log(' Token:', report.dti.name, `(${report.dti.shortName})`); console.log(' Buyer:', report.buyer.entity.legalName); console.log(' Seller:', report.seller.entity.legalName); } else { console.log('✗ Validation errors:'); report.errors.forEach(e => console.log(' ', e)); }
For high-volume reporting, validate a batch of trades before submission:
// Validate a batch of crypto derivative reports const trades = [ { dti: '4H95J0R2X', buyerLei: '784F5XWPLTWKTBV3E584', sellerLei: '7LTWFZYICNSX8D621K86' }, { dti: 'JW7SD9THP', buyerLei: '784F5XWPLTWKTBV3E584', sellerLei: 'HWUPKR0MPOU8FGXBT394' }, ]; const results = await Promise.all(trades.map(validateCryptoReport)); const failed = results.filter(r => !r.valid); console.log(`${results.length} trades validated, ${failed.length} failed`); failed.forEach((r, i) => { console.log(`Trade ${i + 1}:`, r.errors.join(', ')); });
7. cURL examples
Validate a DTI (Bitcoin):
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.isvalid.dev/v0/dti?value=4H95J0R2X"
Validate a LEI (Goldman Sachs — buyer):
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.isvalid.dev/v0/lei?value=784F5XWPLTWKTBV3E584"
Validate a LEI (Deutsche Bank — seller):
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.isvalid.dev/v0/lei?value=7LTWFZYICNSX8D621K86"
8. Regulatory edge cases
LAPSED LEI
The most common EMIR/MiCA rejection. LEIs expire annually — if registrationStatus is "LAPSED", the entity must renew before the report can be accepted. Flag and notify the counterparty.
const result = await callApi('/v0/lei', { value: lei }); if (result.valid && result.found && result.entity?.registrationStatus === 'LAPSED') { console.warn(`LEI ${lei} is LAPSED — renewal required before reporting`); // Notify the counterparty: their LEI must be renewed // Do NOT submit to the trade repository }
Unregistered DTI
A crypto-asset that has no DTI assigned by DTIF. This can happen with newly launched tokens or tokens on niche blockchains. For EMIR Refit, the DTI must be registered — an unregistered DTI will be rejected by the trade repository.
const result = await callApi('/v0/dti', { value: dti }); if (result.valid && !result.found) { console.warn(`DTI ${dti} is not in the DTIF registry`); // The token may exist but has no official DTI // Contact DTIF to request registration before reporting }
DLI vs DTI confusion
The DTIF registry contains both Digital Token Identifiers (DTI) and Distributed Ledger Identifiers (DLI). Bitcoin the token (4H95J0R2X) and the Bitcoin blockchain are different identifiers. Check the identifierType field — use "token" for asset reporting, "ledger" for infrastructure reporting.
const result = await callApi('/v0/dti', { value: dti }); if (result.valid && result.found) { if (result.identifierType === 'ledger') { console.warn(`${dti} is a DLI (ledger), not a DTI (token)`); // For EMIR/MiCA asset reporting, you need a token identifier // This DLI identifies the blockchain, not the asset } }
Cross-regulation: EMIR + MiCA overlap
A CASP that trades crypto-asset derivatives falls under both EMIR (for derivatives) and MiCA (for the spot crypto business). Both validations apply. The same LEI is used for both, but DTI usage may differ — EMIR requires it for the underlying asset in a derivative contract, MiCA requires it for the listed asset on the exchange. Both regulations reject invalid or unregistered identifiers, so validate once and use the result for both reporting obligations.
9. Summary checklist
See also
Start validating for EMIR & MiCA
Free tier includes 100 API calls per day. No credit card required. DTI registry lookup and LEI validation included.