Present W3C Verifiable Credentials via OID4VP

To follow this guide, you need a wallet (wallet-service) configured with an additional service like the credential store for storing received credentials. For more information on different setups, please go here.


This guide works for both the Verifier Service and the Verifier2 Service.
You will notice examples for Presentation Definitions, which are used in the draft OpenID4VP specifications implemented by the Verifier Service.
The Verifier2 Service uses the new OpenID4VP 1.0 specification, which does not support Presentation Definitions. Instead, it supports DCQL (Digital Credential Query Language).


This guide refers specifically to W3C Verifiable Credential standard without selective disclosure. It is possible to wrap a W3C Verifiable Credential within an SD-JWT in order to support selective disclosure. To understand more, check out the Issue W3C Credentials (JWT / SD-JWT) via OID4VC guide.


There are several methods by which a user (wallet) can present a credential to a verifier, and all are supported by the wallet API:

  1. User may receive a direct link, which opens the wallet and prompts credential sharing.
  2. A website may display a QR code for the user to scan and share the credential.
  3. The user may manually input a credential presentation request URL string into a text field.

Irrespective of the chosen method, these are just different ways of receiving, parsing and fulfilling a credential presenting request.

Credential Authorization Request URL

The authorization URL is a standardised method, as per the OID4VP specification, to communicate the needed credentials and claims from verifier to the wallet.

Example Presentation Request

openid4vp://authorize
?response_type=vp_token
&client_id=<client_id>
&response_mode=direct_post
&state=<state>
&presentation_definition=<presentation_definition>
&client_id_scheme=redirect_uri
&response_uri=<response_uri>
Presentation Definition
DCQL

The Presentation Definition for W3C Verifiable Credentials

The presentation definition specifies the criteria for the wallet to know what credentials and claims should be requested from the user and shared with the verifier.

Example for W3C Verifiable Credentials

{
  "input_descriptors": [
    {
      "id": "VerifiableId",
      "format": {
        "vc+sd-jwt": {
          "alg": [
            "EdDSA"
          ]
        }
      },
      "constraints": {
        "fields": [
          {
            "path": [
              "$.type"
            ],
            "filter": {
              "type": "string",
              "pattern": "VerifiableId"
            }
          }
        ]
      }
    }
  ]
}

The definition specifies that one credential is requested in the W3C Verifiable Credential format, specifically with the algorithm "EdDSA" and it must be of type "VerifiableId".

Steps To Fulfill Presentation Request

To fulfill the presentation request received by the verifier, we will need to perform the following steps:

  1. Find credentials matching the presentation definition in the linked credential store of the wallet.
  2. Present matched credentials

1. Find Credentials To Present

To locate the credentials that align with the dcql query provided by the verifier, we will utilize the credential store API.

CURL

Endpoint: /v1/{target}/credential-store-service-api/credentials/query/document/schema | API Reference

Example Request

curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/credential-store-service-api/credentials/query/document/schema' \
  -H 'accept: */*' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '[
  {
        "id": "pid",
        "format": "dc+sd-jwt",
        "meta": {
          "vct_values": [
            "http://org.enterprise.localhost:3000/v1/org.tenant.issuer2/issuer-service-api/openid4vc/draft13/identity_credential"
          ]
        },
        "claims": [
          {
            "path": [
              "given_name"
            ]
          },
          {
            "path": [
              "family_name"
            ]
          },
          {
            "path": [
              "address",
              "street_address"
            ]
          }
        ]
      }
]'

Response Codes

  • 200 - Matching credentials

2. Present Matched Credentials

CURL

Endpoint: /v1/{target}/wallet-service-api/credentials/present | API Reference

Example Request

curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/wallet-service-api/credentials/present' \
  -H 'accept: */*' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "requestUrl": "openid4vp://authorize?client_id=did%3Ajwk%3AeyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5Iiwia2lkIjoiU05JZ1ItTHZzSEUtNkhUUGxYYUpQVDVubHRZMFpqZlA0VkpTWEwzQ2ZkMCIsIngiOiJIVWM1ZHY1eFREV3VMVmZQcFdvVXBWTjZ1QTNJNzBsVzVnNEhoMG5VaDQ0In0&request_uri=http%3A%2F%2Forg.enterprise.localhost%3A3000%2Fv1%2Forg.tenant.verifier%2Fverifier2-service-api%2Fbb3f89d1-8bc9-4d04-9418-12bc70bd76e9%2Frequest",
  "keyReference": "example.kms.key1",
  "didReference": "example.didstore.did1",
  "credentials": [
    {
      "credential": "waltid.tenant22.credential-store-wallet1.3d629d4b-4111-461d-9233-b2224fd64486",
      "disclosures": [
        "$.dateOfBirth",
      ]
    }
  ]
}'

Body Parameters

  • requestUrl String - An OID4VCP Authorization URL.
  • credentials (optional) Array - You can optionally provide a list of credential IDs from the linked credential store that you want to present. If you do not provide a list, the wallet will attempt to find matching credentials based on the dcql query specified in the request URL.
  • keyReference (optional) String - The resource ID (target) of the key which owns the credential.
  • didReference (optional) String - The DID reference of a DID stored in a linked DID Store.

Response Codes

  • 200 - Presentation was accepted

Last updated on November 4, 2025