Home / API / Remote Identity Verification

Remote Identity Verification (Web mDL)

Verify a person remotely for high-risk actions — a controlled-substance prescription, a large wire transfer — with cryptographic non-repudiation. Your agent sends a secure link or prompts the customer's portal; the customer taps "Verify with Wallet", confirms with their device biometric, and their wallet presents a mobile driver's license (ISO 18013-5 mDL) over the W3C Digital Credentials API + OpenID4VP. X-Auth verifies it end-to-end and hands your dashboard the proof.

Base URL: https://id.x-auth.com Agent auth: X-Tenant-Id header Format: JSON
i

How it works

It's a decoupled, consumer-facing flow. Your backend creates a verification; the customer presents their mDL from a separate moment/device; X-Auth verifies the issuer signature (COSE_Sign1 + IACA chain), the MSO value-digests for every disclosed field, and the device signature over a session transcript that is bound to a per-request nonce — so the result can't be replayed or repudiated. On success we mint a signed Verified Identity Token (RS256 JWT) carrying a hash of the disclosed claims.

1

Create a verification

POST /v1/verifications — name the reason, list the mDL claims you need, and pick a channel. You get a one-time verifyUrl to send (or open) for the customer.

request
curl -X POST -H "X-Tenant-Id: acme" \
  -H "Content-Type: application/json" \
  -d '{"purpose":"Authorize wire transfer of $48,000",
       "claims":["family_name","given_name","birth_date","document_number"],
       "channel":"link"}' \
  https://id.x-auth.com/v1/verifications
201 Created
{
  "id": "vrf_8Qx...",
  "status": "pending",
  "verifyUrl": "https://id.x-auth.com/v/9aB...",
  "expiresAt": "2026-06-19T09:10:00Z"
}
2

The customer verifies

The customer opens verifyUrl — same-device (a prompt in your portal) or cross-device (a secure link / QR). The page hands the OpenID4VP request to navigator.credentials.get({ digital }); the OS shows the wallet and a biometric prompt, then returns a vp_token (an mdoc DeviceResponse) which the page posts back to POST /v1/verifications/{id}/response. No login — the wallet biometric is the authentication.

Browser support for the Digital Credentials API is currently limited to Chrome on Android with a platform wallet; the page feature-detects and degrades gracefully elsewhere.

3

Read the result

GET /v1/verifications/{id} — poll until verified. You get the disclosed claims, an assurance tier, whether the issuer chain anchored and the credential was device-bound, and the signed proof token.

200 OK
{
  "id": "vrf_8Qx...",
  "status": "verified",
  "result": {
    "claims": {
      "family_name": "Mustermann",
      "given_name": "Erika",
      "birth_date": "1985-03-12",
      "document_number": "D1234567"
    },
    "issuerTrusted": true,
    "deviceBound": true,
    "issuerCommonName": "State DMV Document Signer",
    "assurance": "high",
    "signals": ["device_signature_valid", "issuer_trusted"],
    "proofToken": "eyJhbGciOiJSUzI1Ni␣...",
    "verifiedAt": "2026-06-19T09:03:11Z"
  }
}

Verify the proofToken against https://id.x-auth.com/.well-known/jwks.json.

4

Assurance tiers

Each verified result carries an assurance tier from the strongest signals present.

TierMeaning
highIssuer chain anchored to a trusted IACA root and device-bound (proof of possession).
mediumDevice-bound, but the issuer chain didn't anchor to a configured root.
lowStructural only — no device binding established.

Production trust of real state mDLs uses the issuing authorities' IACA roots (AAMVA / state), supplied to the service out-of-band; none are bundled.

Try it

Open the agent console to create a verification and watch a live result.

Open agent console →

The console and the customer "Verify with Wallet" page are served from https://id.x-auth.com.

Next steps

Add high-assurance identity proof to your support and telehealth flows.