Get started with the Verify with Wallet API

Apps that require age or identity verification can use the Verify with Wallet API to quickly and securely verify a person’s information using their digital driver’s license or state ID stored in Apple Wallet.

iPhone sending identity verification with the Verify with Wallet API

Overview

Streamline your verification process

Verify with Wallet lets people share information from their ID card in Apple Wallet for an easier and faster verification experience within your app. Instead of requiring cumbersome activities, such as scanning documents or taking selfies, apps can reduce friction and abandonment by letting people complete verification with a simple one-tap experience.

Verified and authenticated identity data

Identity information that your app gets via Verify with Wallet has been verified by the state issuing authority. In order to add an ID card to Apple Wallet, the user must prove ownership of a valid driver’s license or state ID card. During this proofing process, the issuing authority confirms that the user’s driver’s license or state ID card is authentic and belongs to that user.

Additionally, in order to present their ID information to your app, the user needs to authenticate with the same Face ID or Touch ID that they used to add the ID card to Apple Wallet.

Privacy preserving

When you integrate with Verify with Wallet, you provide full transparency into the identity information your app requests and for how long. Your app will be entitled to request only the specific data required to complete the transaction. This prevents users from having to overshare their identity information. Furthermore, neither the state issuing authority nor Apple can see when and where a user shares their license or ID.

Requirements and availability

Verify with Wallet requires iPhone 8 or later running iOS 16 or later.

The Verify with Wallet API requires Xcode 14 or later.

ID cards in Wallet are currently supported in Arizona, Colorado, Georgia, and Maryland in the United States.

Eligible categories:

  • Air Travel
  • Car Rental
  • Financial Services
  • Government Services
  • Healthcare
  • Alcohol Purchase (Order Ahead and Delivery)

To express interest in additional categories for future consideration, please describe how you’d like to use the Verify with Wallet API in the entitlement request form.

Request the entitlement

If you’d like to use the Verify with Wallet API, you’ll need to have an entitlement assigned to your developer account. Account Holders in the Apple Developer Program can submit an entitlement request for the Verify with Wallet API. Requests are granted per bundle ID (the app’s unique identifier) and assigned entitlements can only be used with the single binary associated with the bundle ID.

In order to be eligible, your app must:

  • Be in one of the following categories: Air Travel, Car Rental, Financial Services, Government Services, Healthcare, or Alcohol Purchase (Order Ahead and Delivery).
  • Already require an equivalent age or identity verification process for each user who obtains the same goods or services for the relevant jurisdiction.
  • Be subject to a legal requirement in each jurisdiction where Verify with Wallet will be used to verify a user’s age or identity in connection with providing certain goods or services.

Information you’ll need to provide

  1. App information

    • App name
    • Bundle ID (the app’s unique identifier)
    • App Store or TestFlight URL
    • App Clip App ID (if applicable)
    • Description of the good or service being offered through your app that requires age or identity verification
    • Legal requirements for the jurisdictions that require age or identity verification
    • Screenshots of your existing identity or age verification process for one of the jurisdictions where you plan to use the Verify with Wallet API
  2. Legal information

    When you select the data type your app requires for the purposes of age or identity verification, you’ll need to cite the specific legal requirement (federal, state, and/or local) for each data request. The following data types are available in the Verify with Wallet API.

    Age verification data:

    • Age Over XX Flag
    • Age in Years
    • Issuing Authority
    • ID Photo

    Identity verification data:

    • Given Name
    • Family Name
    • Address
    • Date of Birth
    • Document Number
    • Document Issue Date
    • Document Expiration Date
    • Driving Privileges
  3. Usage information

    • Describe the good or service being offered through your app that requires age or identity verification.
    • If your app needs to verify a user’s age or identity to offer certain goods or services in specific geographic locations, please list those locations and the applicable law (city, county, state, and federal) for each location listed.
    • Upload screenshots of your app’s existing age or identity verification process.
    • Does your existing age or identity verification process apply to all users in every jurisdiction in which you verify and are required to verify identity or age?
  4. Data processing information

    • What data elements does your existing age or identity verification process collect, and how are those data elements verified?
    • Will the requested data elements be processed (used, stored, or disclosed) in a manner different than the data elements you collect through your existing verification process?
    • Are you required to retain any data elements after the verification process is completed?
    • Will any of the data elements be processed by a third party (service provider, affiliates, non-affiliated entities)?
    • If available, you may optionally provide the URL link to your app’s data retention policy, and the data retention policy for each third party that will retain any data elements.

When to resubmit a request

If your app was assigned an entitlement, you’ll need to update Apple on any expanded use of the Verify with Wallet API. This includes any of the following scenarios:

  • You expand verification to additional geographic locations subject to legal requirements.
  • You expand verification to additional groups of users who are subject to legal requirements.
  • You expand verification to additional categories of goods or services that are subject to legal requirements.
  • You need access to additional data elements due to legal requirements.

Implement the API

Once you receive the Verify with Wallet API entitlement, you can invoke the Verify with Wallet API in the PassKit framework and specify the information you’re requesting. To offer a consistent experience across apps, the API provides a set of buttons you can use in your app when you need to ask for identity or age verification. Tapping a button displays a sheet that describes your request and lets people agree to share their information or cancel. If they agree, your app will receive an encrypted response which it passes to your server for decryption and verification.

Verify with Apple Wallet
Continue with Apple Wallet
Verify Age with Apple Wallet
Verify Identity with Apple Wallet

Documentation, videos, and resources

Issuing authority certificates

In order to verify a payload from a user’s state issuing authority, you’ll need to download and use its IACA certificate from their website.

Frequently asked questions

Using the API

Once I’ve been granted the entitlement, how do I set up my developer account and Xcode project?

In the "Certificates, Identifiers, & Profiles" section of the Apple Developer website:

  1. Create a merchant ID. If you already have a merchant ID you use for Apple Pay, you can reuse it here.
  2. Create an "Identity Access Certificate" for your merchant ID. This will show up in the "Identity" tab in the "Edit or Configure a Merchant ID" page.
    1. Note that the private key of the encryption certificate will be used by your server to decrypt the encryptedData returned from the API.
  3. Add the "In App Identity Presentment" capability to your App ID. This will appear in the "Additional Capabilities" tab of the "Edit your App ID Configuration" page.
  4. Add the 'In App Identity Presentment Merchant IDs' capability to your App ID and select the associated Merchant IDs.
  5. Generate a new provisioning profile with these changes.

You'll also need to manually configure your app's entitlements plist file.

Entitlement #1:
"com.apple.developer.in-app-identity-presentment": {
    "document-types": [
        "us-drivers-license"
    ],
    "elements": [
        "given-name",
        "family-name",
        "portrait",
        "address",
        "issuing-authority",
        "document-expiration-date",
       	"document-number",
        "driving-privileges",
        "age",
        "date-of-birth"
    ]
},

Filter the list of entitlements to just the ones you requested through the entitlement request.

Entitlement #2:
"com.apple.developer.in-app-identity-presentment.merchant-identifiers": [
    “your-merchant-id-goes-here”
]

Note that you must add this entitlement even if you're using the same merchant ID for Apple Pay. Apple Pay's com.apple.developer.in-app-payments entitlement is NOT recognized for identity verification.

Can the Verify with Wallet API be used from a web browser?

No. The Verify with Wallet API is not currently supported by browsers. However, the World Wide Web Consortium (W3C) is developing a standard for online presentment.

For browser-based online presentment, we intend to support the mDoc request API as developed in the W3C, pending its final definition, in a way that also enables presentment of conforming identity credentials from third party applications that meet appropriate privacy and security guidelines.

How can I test my use of the API?

There are several ways to test your use of the API:

  • Using the iOS simulator. The simulator comes preloaded with mock mobile driver’s license data you can use to test your integration with the API. For details on the keys and other resources needed to validate responses from the simulator’s mock data, download the Sample data and simulator keys bundle.
  • On an iOS device. When you install the Wallet and Apple mDL Developer Integrator profile, the API will return mock data containing a real device signature but no issuer signature.
  • Test sample. The Sample data and simulator keys bundle contains a sample response with all of the keys and certificates needed to validate it. Use this to test your response validation logic.

Elements

What is the difference between the ISO 18013-5 and AAMVA namespaces?

In the ISO 18013-5 specification supports namespaces that allow different sets of elements to coexist within an identity document. ISO 18013-5 defines a set of standard elements within the org.iso.18013.5.1 namespace. The American Association of Motor Vehicle Administrators (AAMVA) defines its own namespace containing additional information specific to US driver’s licenses.

For more information about the namespaces and elements supported by Verify with Wallet, see the PKIdentityDriversLicenseDescriptor documentation.

What does the address field consist of? Is it possible to get city, state, and zip code as well?

Yes. The “address” element in the request provides the street address, city, state, country and zip code.

What's the difference between age and age threshold?

Age is the user’s age in years. Age threshold is a boolean indicating whether the user is above a certain age. For example, if the user is 42 years old:

  • Age would return 42
  • AgeThresholdElementWithAge:18 would return true
  • AgeThresholdElementWithAge:65 would return false

If you only need to verify whether the user is above or below a certain age, you should use an age threshold element as it is the most privacy preserving approach.

What does issuing authority refer to? Is it is the name of the state issuing the license or ID?

This corresponds to the “issuing authority”, “issuing jurisdiction”, “issuing country” and “un distinguishing sign” elements described in the ISO 18013-5 specification.

What is the structure of the name elements?

The API defines two name elements: given name and family name. These correspond to the “given_name” and ”family_name“ elements defined in the ISO 18013-5 specification. When available, requesting given name will also return the ”given_name_truncation“, ”aka_given_name“, ”name_suffix“, and ”aka_suffix“ elements from the AAMVA namespace. Likewise, when available, requesting family name will also return the ”family_name_truncation“ and ”aka_family_name“ elements from the AAMVA namespace.

The ISO 18013-5 specification does not include an element for middle name(s). Generally, middle names are included with the given name field, but that’s ultimately at the discretion of each issuer.

Is it possible to verify whether a driver’s license is a compliant REAL ID?

REAL ID status is not available through the API.

Does Apple Wallet also allow for non-standard Driver's Licenses (DLs) such as probationary and provisional DLs? If so, what's the best way for us to differentiate between different kinds of DLs?

If provided by the issuer, these license types would be part of the driving privileges structure. This structure is defined in section 7.2.4 of ISO 18103-5. (see https://www.iso.org/standard/69084.html)

For US driver’s licenses, AAMVA has their own variant called “domestic driving privileges” that will also be returned if available (see page 19: https://www.aamva.org/getmedia/c4fe2a21-91ff-449d-9df3-5a7e33cf3a8e/mDL-Implementation-Guidelines-1-0_2021.pdf)

Response format

Where is the session transcript used?

While decrypting the response, you will construct a session transcript object. The session transcript is used as the “info” parameter during HPKE decryption, and is used again while verifying the device signature as defined in ISO 18013-5. See Verifying Wallet Identity Requests for more details.

What is an IACA certificate? Which IACA certificates should I support?

The IACA (issuing authority certificate authority) certificate is the root of trust used to verify that an identity document was created by a valid issuer, such as a state’s Department of Motor Vehicles.

The IACA certificates used by the Verify with Wallet API are listed above. In order to authenticate information returned from IDs in Wallet, your server will need to trust these IACA certificates.

Why must I verify the response on my server?

Verifying the response on a server is necessary in order to ensure that the identity document was created by a valid issuer and was presented from the correct device. Skipping verification or performing the verification within your app leaves you vulnerable to identity documents tampered with by malicious users.

How do I know which issuer issued the identity document?

You can obtain the issuer (such as a state’s Department of Motor Vehicles) that issued a given identity document by requesting the issuing authority element. Alternatively, you can identify the issuer through the IACA certificate corresponding to the identity document’s signing certificate.