> ## Documentation Index
> Fetch the complete documentation index at: https://docs-staging-quickstart-revamp.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Learn how to use Auth0's Verification Service for with Verifiable Credentials such as Mobile Driver's Licenses.

# Configure Mobile Driver’s License Verification Presentation Request

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Auth0’s Mobile Driver's License Verification Service is in Early Access. To enable this feature, review and complete the [Terms and Conditions form](https://forms.gle/47YuFPkhh3RZVvt76), and our team will be in contact with you. To learn more about Auth0’s release stages, read Product Release Stages.
</Callout>

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](/docs/secure/mdl-verification/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

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  The instructions follow along with the hands-on lab using a Next.js application. You can access our [GitHub repository](https://github.com/auth0/hol-mdl).
</Callout>

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 <Tooltip tip="Auth0 Dashboard: Auth0's main product to configure your services." cta="View Glossary" href="/docs/glossary?term=Auth0+Dashboard">Auth0 Dashboard</Tooltip>. 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 <Tooltip tip="Client ID: Identification value given to your registered resource from Auth0." cta="View Glossary" href="/docs/glossary?term=Client+ID">Client ID</Tooltip>, <Tooltip tip="Client ID: Identification value given to your registered resource from Auth0." cta="View Glossary" href="/docs/glossary?term=Client+Secret">Client Secret</Tooltip>, <Tooltip tip="Client Secret: Secret used by a client (application) to authenticate with the Authorization Server; it should be known to only the client and the Authorization Server and must be sufficiently random to not be guessable." cta="View Glossary" href="/docs/glossary?term=Audience">Audience</Tooltip>, 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 <Tooltip tip="Management API: A product to allow customers to perform administrative tasks." cta="View Glossary" href="/docs/glossary?term=Management+API">Management API</Tooltip>. 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](https://www.iso.org/standard/82772.html) standard.

<Warning>
  You should only request verification data that is essential for your business purposes.
</Warning>

#### mDL claims

Claims, which are different from <Tooltip tip="JSON Web Token (JWT): Standard ID Token format (and often Access Token format) used to represent claims securely between two parties." cta="View Glossary" href="/docs/glossary?term=JWT">JWT</Tooltip> 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

<Tabs>
  <Tab title="Auth0 Dashboard">
    1. Navigate to [**Auth0 Dashboard > Credentials > Verification**](https://manage.auth0.com/#/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**.
  </Tab>

  <Tab title="Management API">
    1. Create a Verification Template similar to the example below. Outline the mDL claims you want to request from the user.

       ```json lines
       {
          "name":"TEMPLATE_NAME",
          "dialect":"simplified/1.0",
          "presentation":{
            "org.iso.18013.5.1.mDL": {
              "org.iso.18013.5.1": {
                "family_name":false,
                "given_name":false,
                "birth_date":false,
                "age_over_18":false
              }
            }
          }
        }
       ```

    2. Make a `POST` request to the [Create a verifiable credential template](https://auth0.com/docs/api/management/v2/verifiable-credentials/post-vc-templates) endpoint with the Verification Template definition as the body and the following request headers:

       1. `Content-Type: application/json`

       2. `Authorization: bearer`

          ```text lines
          curl -X POST --location "https://{domain}/api/v2/verifiable_credentils/templates" \
              -H "Authorization: Bearer {managementAccessToken}" \
              -H "Content-Type: application/json" \
            --data-raw `{
            "name": "{template_name}",
            "type":"mdl",
            "well_known_trusted_issuers": "aamva",
            "dialect": "simplified/1.0",
            "presentation": {
          	"org.iso.18013.5.1.mDL": {
                 "org.iso.18013.5.1": {
                   "family_name":false,
                   "given_name":false,
                   "birth_date":false,
                   "age_over_18":false
                   }
                  }
                 }
                }`
          ```
  </Tab>
</Tabs>

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:

   ```text lines
   import fetch from "node-fetch";
   ```

   <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
     The snippet imports the **node-fetch** module, which you use to make `HTTP` calls to the Mobile Driver's License Verification API.
   </Callout>

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:

   ```javascript lines
   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.

        ```text lines expandable
        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](https://www.npmjs.com/package/qrcode).

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.

   ```javascript lines
   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:

   ```text lines
   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.

   ```text lines
   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](/docs/secure/mdl-verification/mdl-verification-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](/docs/manage-users/user-accounts/metadata).

<Warning>
  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](/docs/secure/data-privacy-and-compliance/gdpr).
</Warning>
