![Natalia Markoborodova](https://web.dev/images/authors/nmarkoborodova.jpg) Natalia Markoborodova [X](https://twitter.com/nmarkoborodova) [GitHub](https://github.com/ewewraw) [LinkedIn](https://www.linkedin.com/in/natalia-markoborodova) [Bluesky](https://bsky.app/profile/nmarkoborodova.bsky.social) ![José Luis Zapata](https://web.dev/images/authors/zapata.jpg) José Luis Zapata [GitHub](https://github.com/zapata131) [LinkedIn](https://www.linkedin.com/in/zapata131) [Bluesky](https://bsky.app/profile/zapata131.bsky.social) [Homepage](https://www.zapata131.com)

<br />


Published: October 3, 2025

<br />

We're excited to announce that the [Digital Credentials API](https://www.w3.org/TR/digital-credentials/)
is now enabled by default from Chrome 141. Additionally, iOS 26 adds
[support for the Digital Credentials API](https://webkit.org/blog/17333/webkit-features-in-safari-26-0/#digital-credentials-api)
to Chrome and other browsers. This API brings a new level of security and privacy to identity
verification on the web, enabling a standardized way for websites to request and receive verifiable
information from users.

After a successful [Origin Trial](https://developer.chrome.com/blog/digital-credentials-api-origin-trial),
the Digital Credentials API now supports both same-device credential presentation on Android and cross-device
presentation on desktop Chrome.

## Background

Verifying identity online has so far been a complex process, often requiring users to upload scans
of their IDs. This practice often means sharing more data than necessary, which creates significant
privacy concerns for the users. For developers, it also creates risk, as they must ensure their
solution is capable of processing and storing often non-uniform sensitive data in a secure and
privacy-preserving way.

At the same time, regulations like [eIDAS 2.0](https://ec.europa.eu/digital-building-blocks/sites/spaces/EUDIGITALIDENTITYWALLET/pages/694487738/EU+Digital+Identity+Wallet+Home)
are mandating that governments provide means of digital identification to the public. These digital
identity wallets must be able to hold various credentials, including proof of identity and age.
Online service providers can request these credentials to verify user identity.

Recognizing the potential of digital credentials to meet both user demands for privacy and developer
needs to verify user data, the web standards community in the W3C has developed a solution:
[The Digital Credentials API](https://www.w3.org/TR/digital-credentials/#:%7E:text=Commit%20history-,Editors,-%3A).
The Digital Credentials API aims to address the problem by introducing a built-in interface for
verifying user information, which improves security, privacy, and the user experience compared to
the alternatives. With this API, users no longer need to upload sensitive documents like ID scans to
multiple websites. Instead, websites can build trust with their users by requesting only the
specific, cryptographically-signed data they need from trusted issuers.

## Core features

The Digital Credentials API is built on three core principles: privacy, cross-platform support, and
standardization.

### Privacy

The Digital Credentials API enhances online privacy and security. It allows users to present a
digital ID from their mobile wallets to websites to verify specific facts without disclosing the
underlying sensitive data. For example, the API can verify a user is over 18 without revealing their
full date of birth. This principle of "selective disclosure" ensures that websites only receive the
minimum information necessary.

The Digital Credentials API is also compatible with
[Zero Knowledge Proofs (ZKPs)](https://blog.google/technology/safety-security/opening-up-zero-knowledge-proof-technology-to-promote-privacy-in-age-assurance/)
protocols, such as Google's Longfellow ZK, which ensures user privacy by returning a cryptographic
proof that a certain identity assertion is true without revealing any other information.

### Cross-platform support

The Digital Credentials API aims to support different platforms, so that users can conveniently
present verified information across devices.

**On Android:** Provides a built-in user interface, allowing users to select credentials from their
installed wallet app.
Digital Credentials API: Credential presentation flow on Android

**On desktop:** Users can present credentials from their mobile wallet to a website in their desktop
browser. By scanning a QR code, the system establishes a secure, end-to-end encrypted, and
phishing-resistant connection between the desktop and mobile device. This connection uses the
[CTAP protocol](https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html)
to verify the user's proximity through BLE, ensuring they are physically present and in control of
both devices.
Digital Credentials API: Cross-device credential presentation flow

### Standardization

Interoperability is key. In Chrome, the Digital Credentials API is protocol platform-independent
and is compatible with various presentation protocols, for example,
[OpenID4VP](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html) and
[Annex C of ISO 18013-7](https://github.com/ISOWG10/ISO-18013/blob/main/Working%20Documents/Working%20Draft%20WG%2010_N2544_18013-7%20second%20edition%20DTS%20candidate%20-%20NTC.pdf).
Apple has also introduced [support for the Digital Credentials API](https://webkit.org/blog/17333/webkit-features-in-safari-26-0/#digital-credentials-api)
from Safari 26.0.

Additionally, the Digital Credentials API builds on the built-in credential management support in
Android and a growing ecosystem of compatible wallets. Google Wallet is an early adopter, with
support from Samsung Wallet and 1Password on the way.

## What's new since the Origin trial?

For those who participated our earlier [origin trial](https://developer.chrome.com/blog/digital-credentials-api-origin-trial),
you'll notice the Digital Credentials API has moved from `navigator.identity.get()` to
`navigator.credentials.get()`, aligning it with the broader identity unification effort with the
[Credential Management API](https://web.dev/articles/security-credential-management).
Additionally, the `providers` parameter has been renamed to `requests`, and `request` has been renamed to `data`.

## Implementation

Integrating the Digital Credentials API involves two main steps: feature detection, and requesting
the credential. Developers should also implement custom logic to determine if their application can
use the credentials.

### Feature detection

Before you show a "Verify with Digital Credential" button, check if the Digital Credentials API is
available in the user's browser.

    if (typeof DigitalCredential !== "undefined") {
      // Digital Credentials API is supported
    } else {
      // Digital Credentials API is not supported
    }

### Request a credential

Requesting a credential involves a call to `navigator.credentials.get()` with a `digital`
parameter. Within the digital credential type, add a `requests` array that contains
[DigitalCredentialGetRequest](https://www.w3.org/TR/digital-credentials/#the-digitalcredentialgetrequest-dictionary)
with the following basic parameters:

- `protocol`: Specify an exchange protocol with a string. For example,`"openid4vp"` or
  `"org-iso-mdoc"`. Detect whether the protocol is supported by the browser as follows:

      if (DigitalCredential.userAgentAllowsProtocol("example-protocol")) {
          // Create a request with this protocol
        } else {
          // Protocol is not supported
      }

- `data`: An [object](https://www.w3.org/TR/digital-credentials/#the-digitalcredentialgetrequest-dictionary)
  with the parameters digital wallet apps accept for the specified protocol. For `"openid4vp"`,
  parameters are defined in [OpenID for Verifiable Presentation (OID4VP)](https://openid.net/specs/openid-4-verifiable-presentations-1_0-final.html)
  for the W3C Digital Credentials API specification.

      try {
        const digitalCredential = await navigator.credentials.get({
          digital: {
            requests: [{
              protocol: "openid4vp-v1-unsigned",
              data: {
                response_type: "vp_token",
            nonce: "[some-nonce]",
                client_metadata: {...},
            dcql_query: {...}
              }
          }]
          }
        });

        // Decrypt payload respons and verify credentials on the backend
        const response = await fetch("/verify", {
          method: "POST",
            body: JSON.stringify(digitalCredential.data),
            headers: {
                'Content-Type': 'application/json'
            }
        });
      } catch (e) {
        // Handle errors, such as the user canceling the request
        console.error(e);
      }

For example, to request a user's family name, given name, and a boolean value indicating whether
the user is over 21 years, you can specify the following payload:

    {
      protocol: 'openid4vp-v1-unsigned',
      data: {
        response_type: 'vp_token',
        nonce: '[some-nonce]',
        // Contains the Verifier metadata values, including supported credential formats and response encryption public key
        client_metadata: {
      // Supported credential formats. Refer to the documentation for specific values
            vp_formats_supported: {...},
       // Public key(s). Refer to the documentation for more detail.
            jwks: {...}
        },
        dcql_query: {
          // A wallet will try to find credentials it holds that match these definitions.
          credentials: [
            {
              // A locally unique identifier for this credential definition within the query.
              id: "cred_vc",
              format: "dc+sd-jwt",
              meta: {
                // 'vct_values' specifies the Verifiable Credential allowed type.
                // In this case, it's a European Digital Identity (EUDI) Personal Identification Data (PID) credential.
                vct_values: [
                  "urn:eudi:pid:1"
                ]
              },
              // 'claims' is an array of specific data that's being requested.
              claims: [
                {
                  // The path ["age_equal_or_over", "18"] corresponds to accessing `credential.age_equal_or_over['18']`.
                  path: [
                    "age_equal_or_over",
                    "18"
                  ]
                }
              ]
            }
          ]
        }
      }
    }

In this example, the `client_metadata` must specify a list of supported formats. Refer to the
[specification](https://openid.net/specs/openid-4-verifiable-presentations-1_0-final.html#name-metadata)
to see which values can be used. The [optional `jwks` value](https://openid.net/specs/openid-4-verifiable-presentations-1_0-final.html#name-encrypted-responses)
set in `client_metadata` must contain public keys used for encryption of the response. You can also
check the [demo code](https://github.com/openwallet-foundation/multipaz) for more examples.

> [!NOTE]
> **Note:** The Digital Credentials API is in a state of active development. For the most recent implementation details, refer to the [Digital Credentials documentation](https://digitalcredentials.dev/docs/intro) or the [Digital Credentials specification](https://www.w3.org/TR/digital-credentials/). See the [OpenID for Verifiable Presentations specification](https://openid.net/specs/openid-4-verifiable-presentations-1_0-final.html) for details on openid4vp protocol.

Here's an example of a
[DigitalCredential](https://www.w3.org/TR/digital-credentials/#dom-digitalcredential) object
encrypted response payload:

    {
        // This is an example for a response using an OpenID4VP protocol.
        // The format of the 'data' object will differ for other protocols.
        "protocol": "openid4vp-v1-unsigned",
        "data": {
            // To decrypt this JWE payload, use the private key.
       // The decrypted payload will be a JSON object containing the
           // Verifiable Presentation in the 'vp_token' claim.
            "response": "[jwe-token]"
        }
    }

In this example, the system requests the credential with the `openid4vp-v1-unsigned`
protocol and the response contains `response` in the `data` property.

The exact way to parse the response depends on the protocol. You normally need to:

1. **Decrypt the response payload** . The decryption method depends on the protocol used. See how to decrypt the payload for [`openid4vp`](https://openid.net/specs/openid-4-verifiable-presentations-1_0-final.html) (using JWE) and [`org-iso-mdoc`](https://developer.apple.com/documentation/IdentityDocumentServices/Requesting-a-mobile-document-on-the-web#Receive-an-mdoc-response) (using Hybrid Public Key Encryption).
2. **Verify signatures and issuer** . For more detail see the [Online Acceptance of Digital Credentials](https://developers.google.com/wallet/identity/verify/accepting-ids-from-wallet-online#steps_to_validate_credential_response) documentation.

To see code samples for different protocols, check out the [code for the demo](https://github.com/openwallet-foundation/multipaz)
or the [live hosted version](https://verifier.multipaz.org/).

### Verify trust in the issuer

The digital credentials' cryptographic signature proves that the credential is authentic. However,
developers must verify that the issuer is suitable and trusted for their specific use case. For
example, to grant a university student discount, an ecommerce site would require a credential
issued by an accredited university, and would reject a credential signed by any other entities. A
common way to verify trust in the issuer is to maintain a list of approved issuers and reject any
issuer that doesn't match.

## Get started

Ready to start building? Here's what you need to know.

- **Availability:** Chrome 141 or newer enables the Digital Credentials API by default across different platforms.
- **Prerequisites:** Users need a compatible device, for example, Android running Google Play services version 24.0 or higher, or an iOS device running version 26 or later. The device must have an installed digital wallet application that supports the Digital Credentials API, for example, Google Wallet or a [demo wallet](https://apps.multipaz.org/).
- **Try the demo:** The best way to understand the user experience and test your implementation is to try the live demo at <https://verifier.multipaz.org> with Chrome 141 or newer.

## Resources

For more information, check out the following resources:

- **Developer guide:** [Digital Credentials API](https://digitalcredentials.dev/)
- **Specification:** [W3C Digital Credentials](https://www.w3.org/TR/digital-credentials/)
- **Android support:** [Android support of Digital Credentials](https://android-developers.googleblog.com/2025/04/announcing-android-support-of-digital-credentials.html)

## Share your feedback

Now that the Digital Credentials API is shipped, we'd like to hear about your experience building
with it. [File an issue](https://issues.chromium.org/issues/new?component=1518527&template=2146639)
to share your feedback or report any bugs.