Auth0’s Mobile Driver’s License Verification Service is in Early Access. To enable this feature, review and complete the Terms and Conditions form, and our team will be in contact with you. To learn more about Auth0’s release stages, read Product Release Stages.
Auth0’s Mobile Driver’s License Verification Service allows you to initiate a verification request for a user’s Mobile Driver’s License (mDL) to validate mDL claims, such as age and country of residence. mDL verification is useful for a variety of use cases, such as allowing end users to rent cars or access age-restricted products.

Verification Presentation Request

To create a Verification Presentation Request, your application calls the mDL Verification API to initiate a verification flow. The Verification Presentation Request returns a URI with the presentation request information for the user’s digital wallet to consume. Your application presents the URI to the user in the form of a link and prompts them to share their credential with your application. The Verification Presentation Request also returns a verificationId. Your application uses the verificationId to poll the status of the request.

Update .env file

The instructions follow along with the hands-on lab using a Next.js application. You can access our GitHub repository.
If you want to embed the mDL Verification API to use inside your application, you need to update your .env file. The API calls to create and poll the verification request require repeated access to Auth0 variables. We recommend you set these variables as environment variables in your application. For a Next.js application, edit the .env.local file and set the corresponding values:
  • AUTH0_DOMAIN: The Domain specified under the application’s BasicInformation in . Defines the Application performing the Verification Request.
  • PROTOCOL: The protocol determines the method used for interacting with the wallet.
  • TEMPLATE_ID: The Template ID from the template you created.
  • VERIFICATION_BEARER_TOKEN: The Verification Bearer Token that is generated based on your , , , and Grant Type that allows your application to call the Verification Service.

Verification Template

The Verification Template defines the fields you want to request from a user’s digital wallet, including mDL claims. The Verification Template is part of the first call to the mDL Verification API. You can create the Verification Template using the Auth0 Dashboard or . Currently, Auth0 only supports the mDoc credential type. An mDoc is a binary data object for representing a driver’s license as defined in Annex A of the ISO/IEC TS 18013-7:2024 standard.
You should only request verification data that is essential for your business purposes.

mDL claims

Claims, which are different from claims, are specific to the mDL Verifiable Credential. The claims are attributes associated with the user that could be sensitive, personally identifiable information (PII). You can request the following claims:
  • family_name
  • given_name
  • birth_date
  • issue_date
  • expiry_date
  • issuing_country
  • issuing_authority
  • portrait
  • driving_privileges
  • resident_address
  • portrait_capture_date
  • age_in_years
  • age_birth_year
  • age_over_NN
  • issuing_jurisdiction
  • nationality
  • resident_city
  • resident_state
  • resident_postal_code
  • resident_country
  • family_name_national_character
  • given_name_national_character

Create a Verification Template

  1. Navigate to Auth0 Dashboard > Credentials > Verification.
  2. Select + Add Verification Template.
  3. Name the template.
  4. Choose the claims you want to request from the user’s mDL.
  5. Select Create Verification Template.
After you review the supported mDL claims, use the Auth0 Dashboard or Management API to create a Verification Template.

Create a Verification Presentation Request

A Verification Presentation Request keeps track of a verification request in Auth0. To initiate a Verification Presentation Request within your application:
  1. Create a new folder named api in the same folder where the index.js file is located.
  2. Create a new folder named verify in the api folder you created.
  3. Create a new file named start.js in the api/verify folder.
  4. Add the following code snippet to the start.js file:
    import fetch from "node-fetch";
    
    The snippet imports the node-fetch module, which you use to make HTTP calls to the Mobile Driver’s License Verification API.
  5. Map the environment variables from the .env.local file. If you are using Next.js, it will parse this file by default and map the variables to the process.env object:
    const AUTH0_DOMAIN = process.env.AUTH0_DOMAIN;
    const TEMPLATE_ID = process.env.TEMPLATE_ID;
    const PROTOCOL = process.env.PROTOCOL;
    const VERIFICATION_BEARER_TOKEN = process.env.AUTH0_CLIENT_ID;
    
    if (!AUTH0_DOMAIN) throw new Error("AUTH0_DOMAIN not set");
    if (!TEMPLATE_ID) throw new Error("TEMPLATE_ID not set");
    if (!PROTOCOL) throw new Error("PROTOCOL not set");
    if (!VERIFICATION_BEARER_TOKEN) throw new Error("VERIFICATION_BEARER_TOKEN not set");
    
  6. Add the code snippets to the start.js file.
    1. The handler() function handles HTTP requests in an API route.
    2. The run() function makes a POST request to the Mobile Driver’s License Verification API to start a verification request. The returned object has two variables:
      • engagement: The URIwith the verification request information for the end user’s wallet to consume.
      • verificationId: Auth0’s unique identifier of the verification request.
        export default async function handler(req, res) {
            try {
                const result = await run();
                res.status(200).json(result);
            } catch (err) {
                res.status(500).send({ error: err.message });
            }
        }
        
        async function run() {
        
            const result = await fetch(`https://${AUTH0_DOMAIN}/vdcs/verification`, {
                method: "post",
                headers: {
                    "authorization": `bearer ${VERIFICATION_BEARER_TOKEN}`,
                    "content-type": "application/json",
                },
                body: JSON.stringify({
                    template_id: TEMPLATE_ID,
                    protocol: PROTOCOL,
                }),
            })
        
            const { verificationId, engagement } = await result.json();
        
            return {verificationId, engagement };
        }
        

Prompt the user to present a credential

To prompt the user to present a credential, you must provide the returned engagement URI. The first API request to initiate the verification request returns an engagement URI and Verification ID for the user. We recommend you display the engagement link in the form of a QR code or link. If the user is on a device that their wallet is not, such as a tablet or computer, a QR code is helpful. To learn more, review the Node.js example. If the user is on their mobile device, the link prompts the end user to open their wallet and based on the requested type of credentials, the wallet may auto-select an appropriate credential. The user is usually prompted for consent.

Check the Verification Presentation Request’s status

Once you create a verification request, the application needs to know if the user consented to submit a credential to Auth0. To do that, we need to poll the status of the Verification Presentation Request. To do so:
  1. Create a new file named check.js in the /api/verify folder you already created.
  2. Import the node-fetch library and load the required environment variables.
    const AUTH0_DOMAIN = process.env.AUTH0_DOMAIN;
    const VERIFICATION_BEARER_TOKEN = process.env.AUTH0_CLIENT_ID;
    
    if (!AUTH0_DOMAIN) throw new Error("AUTH0_DOMAIN not set");
    if (!VERIFICATION_BEARER_TOKEN) throw new Error("VERIFICATION_BEARER_TOKEN not set");
    
  3. The HTTP handler is similar to the previous one, but the Verification ID must be extracted from the Verification POST request body so your application can exchange the requested claims with Auth0:
    export default async function handler(req, res) {
        try {
            const verificationId = req.body.verificationId;
            const result = await run(verificationId);
            res.status(200).json(result);
        } catch (err) {
            res.status(500).send({ error: err.message });
        }
    }
    
  4. Implement the run() function. This function uses the Verification ID to exchange the requested claims with Auth0 and returns the result.
    async function run(verificationId) {
        if (!verificationId) throw new Error("verificationId not found");
    
        const result = await fetch(
            `https://${AUTH0_DOMAIN}/vdcs/verification/${verificationId}`,
            {
                method: "get",
                headers: {
                    "authorization": `bearer ${VERIFICATION_BEARER_TOKEN}`,
                    "content-type": "application/json",
                },
            }
        );
    
        const data = await result.json();
    
        if (data.presentation) {
            data.presentation = JSON.parse(data.presentation);
        }
    
        return data;
    }
    
The endpoint that checks the status of the Verification Presentation Request can return several different status codes, which indicates the request is ongoing, unsuccessful, or successful. To learn more, read Mobile Driver’s License API.

Verification Request data storage

The claims requested will be available in the result and can be used based on your business needs. If additional storage is required, read Understand How Metadata Works in User Profiles.
Auth0 metadata is not a secure data store and should not be used to store sensitive information. This includes secrets and high-risk PII like social security numbers or credit card numbers, etc. Auth0 customers are strongly encouraged to evaluate the data stored in metadata and only store that which is necessary for identity and access management purposes. To learn more, read Auth0 General Data Protection Regulation Compliance.