Get ready to accept the EU Digital Identity Wallet.
Every EU Member State must offer an EU Digital Identity (EUDI) Wallet by 24 December 2026, and regulated businesses must accept it by 24 December 2027. Didit runs five national electronic IDs (eIDs) today, and EUDI Wallet acceptance is coming soon to the same workflow.
The EUDI Wallet is a free app that every EU Member State must offer under Regulation (EU) 2024/1183, known as eIDAS 2. It holds person identification data (PID), meaning name, date and place of birth and nationality, plus electronic attestations of attributes such as a driving licence or a diploma. Using it is voluntary.
When a business asks for data, the person sees who is asking and shares only the attributes requested. This is called selective disclosure: a site can learn that someone is over 18 without seeing a birth date. The wallet works at assurance level high, the strongest of the three eIDAS levels, and the business checks the issuer signature before it relies on the data.
Last reviewed: 5 October 2026. Not legal advice.
Key dates
Wallets by the end of 2026. Acceptance by 24 December 2027.
These are the dates in Regulation (EU) 2024/1183 and its implementing acts that a business should plan around.
30 April 2024
eIDAS 2 published
Regulation (EU) 2024/1183, which amends the eIDAS Regulation (EU) No 910/2014, appears in the Official Journal of the EU. It enters into force on the twentieth day after publication.
24 December 2024
First wallet rules in force
The first five implementing regulations for the wallet enter into force: person identification data, core functions, notifications, certification, and protocols and interfaces. They start the 24-month and 36-month clocks below.
15 July 2026
Wallet rules updated
The Commission adopts Implementing Regulation (EU) 2026/1731. It sets the two credential formats, SD-JWT VC and ISO/IEC mdoc, and schedules the mandatory portrait for 2028.
23 July 2026
ARF v3.0.0
The Architecture and Reference Framework (ARF), the technical blueprint that wallets and relying parties build on, reaches version 3.0.0.
24 December 2026
Wallets in every Member State
Each Member State must provide at least one EUDI Wallet. The rules for registering relying parties, Implementing Regulation (EU) 2025/848, apply from the same day.
24 December 2027
Private businesses must accept it
Private businesses that must use strong user authentication by law or by contract, other than micro and small enterprises, must accept the wallet when a user asks to use it (Article 5f(2)). That deadline is 36 months after the first implementing acts entered into force on 24 December 2024, so by 24 December 2027.
11 August 2028
Portrait and registration checks
The portrait becomes part of the mandatory person identification data, and wallets must authenticate and validate the registration certificate of each relying party.
Who must accept it
Who has to accept the wallet, and when.
Article 5f of the eIDAS Regulation, as amended by Regulation (EU) 2024/1183, sets the acceptance duties. In every case the user chooses to use the wallet, and you keep your other ways to identify people.
Who
What it means, in plain English
Article · date
Who
Public sector bodies
What it means, in plain English
Where a Member State requires electronic identification to access a public online service, that service must also accept the EUDI Wallet.
Article · date
Art. 5f(1)
Who
Private services that must use strong user authentication
What it means, in plain English
If a law or a contract requires you to use strong user authentication for online identification, you must also accept the EUDI Wallet. The trigger is that requirement, not your sector.
Article · date
Art. 5f(2) · 24 Dec 2027
Who
Areas the article names
What it means, in plain English
Transport, energy, banking, financial services, social security, health, drinking water, postal services, digital infrastructure, education and telecommunications. The article says “including”, so the list gives examples and is not closed.
Article · date
Art. 5f(2)
Who
Micro and small enterprises
What it means, in plain English
Exempt from the private-sector duty, as defined in Commission Recommendation 2003/361/EC. They may still accept the wallet if they choose to.
Article · date
Art. 5f(2)
Who
Only at the user's request
What it means, in plain English
Acceptance is due when the user asks to use the wallet. Using it is voluntary for people, and services must stay open to other identification and authentication means.
Article · date
Arts. 5f(2), 5a(15)
Who
Very large online platforms
What it means, in plain English
Platforms designated under the Digital Services Act that require user authentication must accept the wallet at the user's request, for the minimum data the service needs. The text sets no separate date for this duty.
Article · date
Art. 5f(3)
Relying parties must also register in the Member State where they are established, and may request only the data they registered (Article 5b). Last reviewed: 5 October 2026. Not legal advice.
How a business accepts it
How a relying party accepts the EUDI Wallet, in five steps.
Step 01 / 05
01
Register as a relying party
Register in the Member State where you are established, with your details and the data you intend to request. You receive an access certificate, which authenticates you to the wallet, and, where your Member State issues one, a registration certificate that lists the attributes you registered.
Request only what you need
Ask for specific attributes, for example age over 18, with OpenID for Verifiable Presentations (OpenID4VP) and a Digital Credentials Query Language (DCQL) query, or with ISO/IEC 18013-7. You may not request data beyond your registration.
The user consents in the wallet
On the same phone, the browser hands over to the wallet app. On a computer, the user scans a QR code. The wallet shows who is asking, checks that you are not asking for more than you registered, and the user approves or declines.
Verify the presentation
Check the issuer signature against the trusted lists, check that the credential has not been revoked, and check the device binding, which shows the credential was not copied or replayed.
Receive the attributes and decide
You receive only the attributes the user shared, signed by the issuer. The onboarding or access decision, and the record you keep, stay with you.
Didit will run these steps for you when EUDI Wallet acceptance launches (coming soon).
What you receive vs what KYC still needs
The wallet proves who someone is. Due diligence needs more.
Under the Anti-Money Laundering Regulation (AMLR), Regulation (EU) 2024/1624, electronic identification at assurance level substantial or high is one of the two ways to verify identity (Article 22(6)). It does not carry everything know your customer (KYC) checks ask for. Here is what the person identification data (PID) holds, and how Didit covers each item today.
Due diligence needs
In the EUDI Wallet PID
How Didit covers it today
Due diligence needs
All names and surnames
AMLR Art. 22(1)(a)
In the EUDI Wallet PID
Family name and given name, both mandatory.
How Didit covers it today
Live national eIDs return the full name. The document route reads it from 14,000+ document types.
Due diligence needs
Place and full date of birth
AMLR Art. 22(1)(a)
In the EUDI Wallet PID
Date of birth and place of birth, both mandatory.
How Didit covers it today
Live national eIDs return the date of birth. The document route reads the place of birth where the document prints it.
Due diligence needs
Nationalities
AMLR Art. 22(1)(a)
In the EUDI Wallet PID
Nationality, mandatory, one or more countries.
How Didit covers it today
The document route reads the nationality from the identity document or its chip.
Due diligence needs
National identification number, where applicable
AMLR Art. 22(1)(a)
In the EUDI Wallet PID
Personal administrative number, optional. Each Member State decides whether to issue it.
How Didit covers it today
Live national eIDs return a scheme identifier: the Swedish personnummer, the Finnish personal identity code or the Baltic personal code. MitID returns a pseudonymised identifier, not the CPR number.
Due diligence needs
Usual place of residence
AMLR Art. 22(1)(a)
In the EUDI Wallet PID
Address fields are optional and often missing. AMLA's final draft standards say missing attributes must be obtained through other means.
How Didit covers it today
No live national eID returns an address. Proof of Address checks a utility bill, bank statement or government letter.
Due diligence needs
Tax identification number, where available
AMLR Art. 22(1)(a)
In the EUDI Wallet PID
Not part of the PID.
How Didit covers it today
Collect it with a questionnaire step in the same workflow.
Due diligence needs
The person matches the identity
ARF · user binding
In the EUDI Wallet PID
The portrait stays optional until it becomes mandatory on 11 August 2028.
How Didit covers it today
Passive liveness and a 1:1 face match against the document photo or the chip portrait, inside the full KYC check at $0.33.
Due diligence needs
Beneficial owners of a company
AMLR Art. 20(1)(b)
In the EUDI Wallet PID
Not in the PID. A wallet identifies a person, not who owns a company.
How Didit covers it today
Business Verification pulls registry data and owners where the registry holds them, with an identity check for each owner.
Due diligence needs
Sanctions and politically exposed persons (PEPs)
AMLR Art. 20(1)(d), (g)
In the EUDI Wallet PID
Not in the PID.
How Didit covers it today
AML Screening against 1,300+ sanctions, PEP and watchlists, at $0.20 per check.
Due diligence needs
Purpose of the relationship and ongoing monitoring
AMLR Arts. 25, 26
In the EUDI Wallet PID
Not in the PID.
How Didit covers it today
Questionnaires record the purpose of the relationship. Ongoing monitoring re-screens customers every day for $0.07 per person per year.
Customer due diligence stays your obligation. Didit supplies checks and evidence and does not make you compliant. AMLR applies from 10 July 2027, and AMLA's technical standards are a final draft dated 30 September 2026, not law.
Readiness by country
Where the national wallets stand, dated and sourced.
This is what each country has published, or what a named source reports, with the date and a link for every row.
Status as of October 5, 2026
Country
Wallet or app
Status
Date
What is known
Country
Italy
Wallet or app
IT-Wallet (app IO)
Status
Live app
Date
February 17, 2026
What is known
Live in the IO app, with 10.1 million activations and 17.3 million documents loaded by 17 February 2026. Free and optional for adults, who sign in with CIE or SPID.
AltID is live with a digital ID card and proof of age, and 281,390 people had created one by 4 August 2026. The Agency for Digital Government is implementing the wallet in stages.
Public sandbox since December 2025. The app is due in early 2027, starting with the ID function. The implementing law had its first Bundestag reading on 23 September 2026.
Not listed: Austria, Belgium, Estonia, Hungary, Latvia, Lithuania, Luxembourg, Malta, Portugal, Slovenia. We found no public status for them on this date. We update this table as national apps launch.
How Didit gets you there · Five rows
Accept national eIDs now. Add the EUDI Wallet next.
The EUDI Wallet adds a route; it does not replace the others. Build the workflow once: national eIDs and documents today, and EUDI Wallet acceptance in the same ID Verification step when it launches.
Accept the national eIDs your customers already use.
Five national eIDs are live on Didit across seven countries: MitID, BankID Sweden, Finnish Trust Network, Smart-ID and Mobile-ID. The user signs in with their eID, and the session receives signed attributes: full name, date of birth, a scheme identifier (for example the Swedish personnummer; MitID returns a pseudonymised identifier) and the level of assurance the scheme asserted. Only completed sign-ins are billed.
Levels as Didit labels them. No address or portrait is returned.
02 · EUDI Wallet, coming soon
EUDI Wallet acceptance, on the same workflow.
EUDI Wallet acceptance is coming soon. Our wallet catalog lists it for 30 EEA countries, in the same ID Verification step as the national eIDs. There is no date or price yet.
Not everyone will have or use a wallet, and the law keeps other means open. The document route reads the chip in passports and ID cards by NFC ($0.15), runs passive liveness and matches the face to the document photo, across 14,000+ document types in 220+ countries and territories.
The EUDI Wallet can prove that someone is over 18 without a birth date. Until wallets are common, age estimation from a selfie costs $0.10 per check and sends borderline results to an ID verification fallback. A live eID sign-in also returns a signed date of birth without a document photo.
Screening, monitoring and companies, in one place.
Identity is one part of customer due diligence. In the same workflow, screen people against 1,300+ sanctions, PEP and watchlists ($0.20 per check), re-screen them every day with ongoing monitoring ($0.07 per person per year), and verify companies and their owners.
A cross-device presentation as the ARF describes it: the person starts on a computer and finishes on the phone that holds the wallet.
01Scan to continue
Scan the QR code
The service shows a QR code, and the person scans it with the wallet app.
02Online shop asks for: age over 18
Review the request
The wallet shows who is asking and which attributes.
03Share 1 attribute
Share
The person approves, and only the requested attributes leave the phone.
04Verified
Verified
The service checks the issuer signature and continues. Nothing else was shared.
An illustration of the standard flow. Didit's EUDI Wallet acceptance is coming soon.
Integrate today
Integrate today, and keep it when the wallet arrives.
There is no EUDI-specific Didit API yet. Create a session for a workflow that accepts the live national eIDs and documents, then read the result. EUDI Wallet acceptance is planned for the same ID Verification step.
Copy this prompt into your coding agent. It builds the workflow you can run today, live national eIDs with a document fallback, plus the session call and the signed webhook. It invents no EUDI endpoint, because none exists yet.
didit-integration-prompt.md
# Didit: get ready for the EUDI Wallet with the ID Verification step you run today
You are adding electronic identification to my_stack so the product is ready
for the EU Digital Identity (EUDI) Wallet. Every URL, header and enum value
below is canonical. Do not paraphrase or "improve" them.
## 0. What exists today, and what does not
- EUDI Wallet acceptance on Didit is coming soon. There is NO EUDI-specific
endpoint, wallet id, field or flag to integrate yet. Do not invent one, do
not send any EUDI identifier in a workflow, and do not build an OpenID4VP
verifier yourself as part of this task.
- What is live: national digital ID wallets inside the ID Verification step,
with document capture (chip reading, liveness, face match) as the fallback.
EUDI Wallet acceptance is planned for the same ID Verification step, so the
workflow, session call and webhook you build now are the ones you keep.
- The live wallets, as listed by the methods catalog:
- MitID: wallet id mitid, country keys DNK (Denmark)
- BankID: wallet id bankid_se, country keys SWE (Sweden)
- Finnish Trust Network: wallet id ftn, country keys FIN (Finland)
- Smart-ID: wallet id smart_id, country keys EST (Estonia), LVA (Latvia), LTU (Lithuania), BEL (Belgium)
- Mobile-ID: wallet id mobile_id, country keys EST (Estonia), LTU (Lithuania)
Check the catalog for your environment before you go live. Never
hard-code dates.
## 1. Provision an account
- Sign up: https://business.didit.me (no credit card required).
- Copy the API key of your application from the console.
## 2. Read the methods catalog
Availability is server-driven per country. Only wallets marked available can
be enabled on a live application.
- Business Console: your application -> Workflows -> the ID Verification
step -> Countries -> "Wallets accepted". Coming-soon wallets are listed
but cannot be switched on. https://docs.didit.me/console/id-verification-methods
- Didit MCP server (https://mcp.didit.me/mcp), tool
didit_workflow_get_id_verification_methods_catalog; pass country as ISO
3166-1 alpha-3 to narrow it. The MCP server signs in with "Log in with
Didit" (OAuth). It does not accept the x-api-key.
https://docs.didit.me/integration/mcp/tools
- Public coverage table (no sign-in, read-only):
https://docs.didit.me/core-technology/id-verification/digital-id-wallets#supported-wallets
If your code holds only an API key, it cannot read the catalog itself: use the
wallet ids listed in this prompt, and treat the answer of the workflow save as
the check. A live application answers 400 for a wallet that is not available
in that country ("<wallet> is not offered in <ISO3>", "unknown wallet").
## 3. Create the workflow (ID Verification = feature OCR)
POST https://verification.didit.me/v3/workflows/
-H "x-api-key: <your-api-key>"
-H "Content-Type: application/json"
{
"workflow_label": "eID onboarding",
"features": [
{
"feature": "OCR",
"config": {
"methods": {
"DNK": {
"document": { "enabled": true },
"wallet": {
"enabled": true,
"providers": ["mitid"],
"on_failure": "fallback_to_document"
}
},
"EST": {
"document": { "enabled": true },
"wallet": {
"enabled": true,
"providers": ["smart_id", "mobile_id"],
"on_failure": "fallback_to_document"
}
}
}
}
}
]
}
Response: 201. The workflow id is uuid (workflow_id carries the same value);
the workflow is published straight away. Create it once and keep the id:
every call to this endpoint makes a new workflow.
is_desktop_allowed defaults to false: on a desktop browser the hosted flow
then shows a QR code to continue on a phone. Add "is_desktop_allowed": true
next to workflow_label to let people finish on desktop.
Rules the API enforces:
- OCR is UPPERCASE; ID_VERIFICATION is rejected in this body (the decision
later lists the step as ID_VERIFICATION in its features)
- country keys are ISO 3166-1 alpha-3; method keys are document, id_lookup, wallet
- providers is an accept-list, not a ranking; the end user picks
- on_failure is fallback_to_document or decline
- a wallet the catalog does not mark available rejects the whole save (400)
- every other country keeps document capture, so people without an eID
can still verify
- this body runs document capture only. Chip reading, liveness and face
match are their own features: add { "feature": "NFC" },
{ "feature": "LIVENESS" } and { "feature": "FACE_MATCH" } to features
when your policy needs them
## 4. Create a session
POST https://verification.didit.me/v3/session/
-H "x-api-key: <your-api-key>"
-H "Content-Type: application/json"
-d '{ "workflow_id": "<id from step 3>", "vendor_data": "<your user id>" }'
Response: 201 with session_id, session_token, url and status "Not Started".
Redirect the user to url (hosted flow) or open it in the Web, iOS, Android,
React Native or Flutter SDK. The field is named url on this response.
One unfinished session exists per workflow_id and vendor_data pair: calling
create again with the same pair answers 201 again with that same session.
## 5. Webhook
Register a destination in the console (API & Webhooks), or over the API:
POST https://verification.didit.me/v3/webhook/destinations/
-H "x-api-key: <your-api-key>"
-H "Content-Type: application/json"
-d '{
"label": "Verification webhooks",
"url": "https://<your-public-host>/webhooks/didit",
"webhook_version": "v3",
"subscribed_events": ["status.updated", "data.updated"]
}'
label, url and subscribed_events are required. url must be a public HTTPS
address: Didit does not deliver to localhost or private addresses. Response:
201 with uuid and secret_shared_key. Store secret_shared_key as the webhook
secret (DIDIT_WEBHOOK_SECRET); it is unique to this destination. Remove a
destination with DELETE /v3/webhook/destinations/{uuid}/ (204).
What arrives:
- webhook_type is "status.updated" (the session changed status) or
"data.updated" (verification data was corrected after the fact)
- a destination receives the events of every session of the application,
so filter on workflow_id or vendor_data when several flows share it
- creating a session already sends status.updated with status
"Not Started". The decision key is present only when status is Approved,
Declined, In Review or Abandoned.
Verify every delivery:
Header: X-Signature-V2 (not X-Signature, not X-Signature-Simple)
Algorithm: HMAC-SHA256, hex digest, over the canonical JSON of the payload
(Python json.dumps(sort_keys=True, separators=(",", ":"),
ensure_ascii=False) after whole-valued floats become ints).
Never hash the raw request bytes under this header.
Freshness: the signed body field timestamp is the dispatch time (Unix
seconds). Reject when abs(now - timestamp) > 300 seconds, and
reject when the X-Timestamp header does not equal it.
Idempotency: event_id is the same on every retry of one event, so store it
and skip a delivery you already processed. One session can
still send the same status under two event ids, and the
console's Try Webhook test deliveries carry no event_id, so
also make the handler safe to run twice for one
(session_id, status, webhook_type).
Compare: constant-time (crypto.timingSafeEqual)
Reference handler (Express). Keep the verification lines as written.
The handler is a fragment. Put this above it and app.listen(process.env.PORT)
below it. It needs Express and Node 21 or newer (an older Node rejects
every delivery). It expects a JSON body: answer 400 yourself if you accept
anything else on this route, and refuse to start without the secret.
const express = require("express");
const app = express();
const SECRET = process.env.DIDIT_WEBHOOK_SECRET; // secret_shared_key of the destination
// Your endpoint receives a signed payload
const crypto = require("node:crypto"); // ESM: import crypto from "node:crypto"
// X-Signature-V2 = HMAC over the canonical JSON, never the raw bytes. Match the sender byte for
// byte: keys sorted by code point, integers digit for digit, floats in Python's repr.
class Num { constructor(src) { this.src = src; } } // a number as written on the wire, not a double
const num = (s) => { if (/^-?\d+$/.test(s)) return BigInt(s).toString(); const n = +s; // ints stay exact
if (Number.isInteger(n)) return BigInt(n).toString(); const [m, e] = n.toExponential().split("e"); // 27.0 -> 27
return +e >= -4 ? String(n) : `${m}e-${String(-e).padStart(2, "0")}`; }; // 1e-05, not 0.00001
const byCodePoint = (a, b) => Buffer.compare(Buffer.from(a), Buffer.from(b)); // UTF-8 order = Python's
const canon = (v) => Array.isArray(v) ? `[${v.map(canon)}]` : v instanceof Num ? num(v.src)
: v && typeof v === "object" ? `{${Object.keys(v).sort(byCodePoint).map((k) => `${JSON.stringify(k)}:${canon(v[k])}`)}}`
: JSON.stringify(v);
// Read the body as text: express.json() would round 1000000000000000129 to a double first.
// Register this route ABOVE any global app.use(express.json()): the first parser to run
// consumes the stream, and a body it already parsed has lost the digits the signature covers.
app.post("/webhooks/didit", express.text({ type: "application/json" }), (req, res) => {
const exact = JSON.parse(req.body, (k, v, c) => typeof v === "number" ? new Num(c.source) : v); // Node 21+
const body = JSON.parse(req.body);
const mac = crypto.createHmac("sha256", SECRET).update(canon(exact), "utf8").digest("hex");
const sig = Buffer.from(String(req.headers["x-signature-v2"] ?? ""));
// Freshness comes from the signed body timestamp; the header alone is unsigned and replayable.
const ts = body.timestamp, fresh = String(ts) === req.headers["x-timestamp"]
&& Math.abs(Date.now() / 1000 - ts) <= 300;
if (!fresh || sig.length !== mac.length
|| !crypto.timingSafeEqual(sig, Buffer.from(mac))) return res.sendStatus(401);
const { status, decision } = body;
// One entry per ID Verification node; pick yours by node_id when you run several.
const [idv] = decision?.id_verifications ?? [];
// idv.verification_method: "document" | "id_lookup" | "wallet"
res.sendStatus(200);
});
Status values (exact strings): Not Started, In Progress, Approved, Declined,
In Review, Resubmitted, Expired, Abandoned, Kyc Expired. Awaiting User only
appears on business verification sessions.
## 6. Read the result
The same V3 decision reaches you two ways:
- webhook body: body.decision.id_verifications[]
- GET https://verification.didit.me/v3/session/{session_id}/decision/
-H "x-api-key: <your-api-key>"
This response IS the decision object. Read id_verifications at the top
level: there is no decision wrapper here.
Until the user finishes the ID step, status is "Not Started" or "In Progress"
and id_verifications is null, not an empty array. Guard for it.
id_verifications[] has one entry per ID Verification node; with a single step
take index 0. A wallet sign-in sets:
verification_method "wallet"
assurance "cryptographic"
wallet_provider the catalog wallet id the user picked
wallet_verification provider, provider_name, issuing_authority,
issuing_country, credential_type, level_of_assurance,
verified_at, signature_valid, attributes, portrait
(null for the live wallets), face_match_score
fallback_from { method, reason, action } when the wallet sign-in failed
and on_failure declined the session; otherwise
null. After a document fallback that succeeds the
entry reads verification_method "document" with
fallback_from null
full_name, the normalised identity fields, on the entry itself
date_of_birth
On a live application, check wallet_verification.signature_valid before you
trust attributes. The
live wallets return name, date of birth and a scheme identifier (for example
the Swedish personnummer; MitID returns a pseudonymised identifier), never an
address or a portrait: collect those through other steps if your policy
needs them.
Reference: https://docs.didit.me/core-technology/id-verification/digital-id-wallets
## 7. Billing
Only completed wallet sign-ins are billed; cancelled, timed-out and failed
ones are free. Prices per wallet: https://didit.me/pricing
## 8. Verify your integration
Sandbox (an application in sandbox mode: nothing is billed and no real eID is
called). https://docs.didit.me/integration/sandbox-testing
- a sandbox application can enable every wallet in the catalog, the
coming-soon ones included. A workflow that saves in sandbox can still be
refused on a live application, so only use wallets marked available.
- open the session url, pick the wallet and confirm: the default approve
scenario simulates the sign-in. The entry then has verification_method
"wallet", assurance "cryptographic" and wallet_provider set, and the
normalised full_name and date_of_birth are filled. But
wallet_verification.signature_valid and level_of_assurance are null and
attributes is { "sandbox": true }: no real credential was checked.
Assert signature_valid === true and the level of assurance only against
a live application.
- to exercise on_failure, create the session with
"sandbox_scenario": "wallet_cancelled" (also wallet_timeout and
wallet_provider_error). The wallet sign-in then fails and the flow moves
to document capture or declines, as on_failure says. A fallback that
ends in an approved document reads verification_method "document".
- POST /v3/session/{session_id}/simulate/ forces a final status but writes
no id_verifications entry, so it cannot stand in for a sign-in.
Checks:
- create the workflow, create a session, and read its decision: expect 201,
201 with url, and 200 with status "Not Started"
- run one sandbox session per accepted wallet through the hosted flow and
assert verification_method is "wallet" and wallet_provider is the wallet
you picked
- run one session with sandbox_scenario "wallet_cancelled" and assert the
flow offers document capture
- assert the webhook accepts a correctly signed payload and rejects a wrong
X-Signature-V2, a changed body, and a payload whose signed timestamp is
older than 300 seconds, even when X-Timestamp is refreshed
- on a live application, assert wallet_verification.signature_valid is true
Docs: https://docs.didit.me/core-technology/id-verification/digital-id-wallets
Compliant by design
Open a new country in one click. We do the hard work.
We open the local subsidiaries, secure the licenses, run the penetration tests, earn the certifications, and align with every new regulation. To ship verifications in a new country, flip a toggle. 220+ countries live, audited and pen-tested every quarter, the only identity provider an EU member-state government has formally called safer than in-person verification.
500 free verifications every month, forever. Then pay only when a module runs. Custom contracts, data residency, and service level agreements (SLAs) on Enterprise.
Free
$0/ month · no card
For building, testing, and your first users.
Everything you need to start:
500 full KYC verifications every month
ID, liveness, face match, device & IP
200+ fraud signals, blocklist, duplicates
Reusable KYC across the Didit network
Workflow builder, case management, SDKs
AI supportIn-console AI agent, docs, and community.