Verifies a wallet-held mobile driving licence (mDL, ISO/IEC 18013-5) instead of a PID: given name, family name, birth date, document number, driving privileges, expiry date, and issuing country. Same Nexiel Verify service, same POST /v1/verify/sessions route as every other check type. Only checkType: "mobile-driving-licence" differs.
New to EUDI wallets? Read what an EU Digital Identity Wallet is, and how a session works before this page assumes you already know what OpenID4VP, DCQL, and mdoc mean.
This is not a new verification engine. It is the same OpenID4VP session flow every other Nexiel Verify check type uses, requesting a different credential format: mso_mdoc with doctype_value: "org.iso.18013.5.1.mDL", instead of the PID's dc+sd-jwt format. There is no fallback credential offered for this check. No other credential type in the EUDI wallet ecosystem carries driving-privilege data, so unlike age verification's AV-or-PID choice, there is nothing to offer as an alternative.
Trust for an mDL is resolved separately from a PID or an EU Age Verification (AV) attestation. An mDL is issued under each country's own road-transport authority IACA (Issuing Authority Certificate Authority) program, a different PKI governance chain from the eIDAS PID-Provider Trusted List or the EU AV Attestation Provider list, even though all three verify against the same ISO 18013-5 mdoc mechanics. See production status below for what that means for a live deployment.
This check requests document_number and driving_privileges: real, name-level, potentially sensitive detail beyond Nexiel's existing baseline check types. It does not request a portrait. No check type in Nexiel Verify requests a photo claim.
Production access is gated. mobile-driving-licence is the first Nexiel Verify check type that needs more than an active account. A production request against it needs both an active Nexiel Verify account and a specifically APPROVED entitlement grant for this check type. Having Verify enabled is not enough by itself.
A signed-in member of your organization requests access from the dashboard's CheckType access page: pick mobile-driving-licenceand enter a declared use case (for example, "renter identity and licence check before handing over a vehicle"). That creates a request in a PENDING state, visible on the same page alongside every other request your organization has made. A Nexiel reviewer approves or denies it from a separate reviewer queue. There is no automatic approval path for a gated check type. A denied or still-pending request is not silently retried. You can see its current status on the same dashboard page at any time.
A production request for mobile-driving-licence made before approval, or after a denial, fails closed with a 403:
{
"error": "checktype_entitlement_denied",
"message": "organization \"3f1e6c2a-9b7d-4e3f-8a2c-5d1f9e0b7c44\" has never requested checkType \"mobile-driving-licence\", which requires an approved entitlement grant before it can be used"
}The same three-state message distinguishes a request that was never made from one still PENDING review, or one that was reviewed and DENIED. This gate runs after authentication and after the normal account-active check, and before rate limiting and anomaly tracking for the request.
Sandbox mode has no entitlement gate. An unauthenticated sandbox request (no Authorization header, a self-run instance with no VERIFY_API_MODEset) never reaches this check at all: it is a production, organization-scoped concept, the same "no-op outside production" scoping the account-active gate already uses. Every example below runs against sandbox mode.
Real ISO/IEC 18013-5:2021 mDL data elements, all in the standard org.iso.18013.5.1 namespace:
{
"id": "mobile-driving-licence",
"version": 1,
"dcqlQuery": {
"credentials": [
{
"id": "mdl_check",
"format": "mso_mdoc",
"meta": {
"doctype_value": "org.iso.18013.5.1.mDL"
},
"claims": [
{
"path": [
"org.iso.18013.5.1",
"given_name"
]
},
{
"path": [
"org.iso.18013.5.1",
"family_name"
]
},
{
"path": [
"org.iso.18013.5.1",
"birth_date"
]
},
{
"path": [
"org.iso.18013.5.1",
"document_number"
]
},
{
"path": [
"org.iso.18013.5.1",
"driving_privileges"
]
},
{
"path": [
"org.iso.18013.5.1",
"expiry_date"
]
},
{
"path": [
"org.iso.18013.5.1",
"issuing_country"
]
}
]
}
]
}
}The session-initiate step is a plain HTTP request you can call directly. Completing a session requires a wallet-signed mdoc presentation, which a bare HTTP client cannot produce on its own. The requests and responses below are real, executed against a self-run sandbox-mode instance.
curl -s -X POST https://compliance.nexiel.io/v1/verify/sessions \
-H "Content-Type: application/json" \
-d '{"clientId": "docs-example-client", "checkType": "mobile-driving-licence"}'{
"sessionId": "7c9e2a41-5f18-4b6d-9a2e-6b0d3f8c1a95",
"templateVersion": "mobile-driving-licence@1",
"authorizationRequest": {
"client_id": "https://verify.nexiel.eu",
"response_type": "vp_token",
"response_mode": "direct_post",
"response_uri": "https://compliance.nexiel.io/v1/verify/sessions/7c9e2a41-5f18-4b6d-9a2e-6b0d3f8c1a95/responses",
"dcql_query": {
"credentials": [
{
"id": "mdl_check",
"format": "mso_mdoc",
"meta": {
"doctype_value": "org.iso.18013.5.1.mDL"
},
"claims": [
{
"path": [
"org.iso.18013.5.1",
"given_name"
]
},
{
"path": [
"org.iso.18013.5.1",
"family_name"
]
},
{
"path": [
"org.iso.18013.5.1",
"birth_date"
]
},
{
"path": [
"org.iso.18013.5.1",
"document_number"
]
},
{
"path": [
"org.iso.18013.5.1",
"driving_privileges"
]
},
{
"path": [
"org.iso.18013.5.1",
"expiry_date"
]
},
{
"path": [
"org.iso.18013.5.1",
"issuing_country"
]
}
]
}
]
},
"nonce": "HqK3v9Lp2ZmXcR7bYtF5nW8aQ1sD4jE6gU0iO2kM9pA",
"state": "T6mB1z8v3J0qE9rL2wX5cH7nY4sD8fG1kU3oA6iP0zQ"
},
"authorizationRequestUri": "openid4vp://authorize?client_id=https%3A%2F%2Fverify.nexiel.eu&response_type=vp_token&...(truncated)",
"expiresAt": "2026-08-27T11:42:07.113Z"
}The wallet resolves authorizationRequestUri and answers with the mdoc presentation, POSTed back to response_uri. This check runs no AML or PEP screening at all: it is identity plus a driving licence's own data, nothing more. A wallet whose mDL verifies against a trusted issuer produces:
{
"sessionId": "7c9e2a41-5f18-4b6d-9a2e-6b0d3f8c1a95",
"method": "eudi_wallet",
"booleanProofs": {
"claimsVerified": true
},
"amlResult": null,
"pepFlag": null,
"sanctionedFlag": null,
"listsChecked": [],
"humanReviewRequired": false,
"templateVersion": "mobile-driving-licence@1",
"frozenDecisionArtifact": null
}amlResult, pepFlag, sanctionedFlag, listsChecked, and frozenDecisionArtifact are all null or empty for the same reason they are on an age-verification or login-authentication check: no matching engine ever runs here, so there is no screening decision to human-review or freeze. This callback reply never includes the disclosed licence claims or an evidence pack. See below for how those are delivered instead.
An mDL signed by an issuer this deployment does not trust fails closed. The session is marked failed and the disclosed claims are discarded. No partial result is ever returned.
The disclosed licence claims are never stored by Nexiel as plaintext. They are encrypted into an “evidence pack,” JWE compact serialized (ECDH-ES, A256GCM, P-256), to a public key your organization registers and controls, the same mechanism every other identity-adjacent check type in Nexiel Verify uses. See setting up evidence pack encryption for how to generate and register that key from the dashboard.
This check runs no AML or sanctions screening, so its payload is narrower than an aml-identityevidence pack: no screening decision, no frozen decision artifact, only the disclosed claims and the wallet's issuer signature validation result. Decrypted, it holds:
{
"method": "mobile-driving-licence",
"timestamp": "2026-08-27T11:42:19.402Z",
"disclosedClaims": {
"givenName": "Aoife",
"familyName": "Ní Bhriain",
"birthDate": "1990-05-14",
"documentNumber": "IE-DL-0099213",
"drivingPrivileges": [
{
"vehicle_category_code": "B",
"issue_date": "2010-06-01",
"expiry_date": "2030-06-01"
}
],
"expiryDate": "2030-06-01",
"issuingCountry": "IE"
},
"issuerSignatureValidation": {
"valid": true,
"credentialProofRef": "4a7f1e9c2b6d8305f1a9c7e2b4d6f8305a1c7e9b2d4f6a8305c1e7b9d2f4a6c8"
}
}credentialProofRef is a SHA-256 hash of the presented wallet token, never the raw token itself, the same convention every other evidence pack in Nexiel Verify uses. Every optional claim (birthDate, documentNumber, drivingPrivileges, expiryDate, issuingCountry) is included only when the wallet disclosed it.
Nexiel's own retention for this check stops at a minimal audit row: the session id, client id, timestamp, template version, and a SHA-256 hash of the delivered ciphertext, proof a pack was generated and handed off, never its contents. Whatever record-keeping obligation a car rental company, or any other relying party, has for a driver's licence and driving-privilege data is that organization's own responsibility on its own systems, the same way it is for every check type Nexiel Verify offers.
Collect it the same way as an aml-identity evidence pack: a follow-up GET /v1/verify/sessions/{sessionId} call.
claimsVerified: true). Nothing else.Sandbox mode is fully real and usable today,exactly as shown above, no entitlement request or bearer token required. Production is gated behind a real, external infrastructure gap, not a code gap: verifying an mDL against a real issuer requires this deployment to be configured with that issuer's trust anchors (its IACA root or an intermediate Document Signer CA), and no EU-wide, publicly fetchable trusted list of mDL issuer roots has been confirmed to exist for this integration, unlike the EU AV Attestation Provider list or the eIDAS PID-Provider Trusted List. A production deployment populates trust anchors per issuing jurisdiction as it obtains and verifies them out of band. Without one configured, production verification of a real mDL fails closed, the same discipline every credential type in Nexiel Verify uses when it cannot resolve trust.
This is independent of the entitlement gate above. An organization can be fully approved for mobile-driving-licenceand still have every production request fail closed at the trust-resolution step until this deployment has a real jurisdiction's mDL trust anchors configured.
There is no separate mobile driving licence API reference. Every route, parameter, and response schema this page uses is documented on the Verify API reference. The routes this page walks through are POST /v1/verify/sessions and POST /v1/verify/sessions/{sessionId}/responses, with checkType: "mobile-driving-licence".