Accept SD-JWT Verifiable Credentials via OID4VCI

In this guide, we take a look at how you can use the walt.id Enterprise wallet service API to accept an SD-JWT Verifiable Credential from an issuer via OID4VCI.

Ensure you have set up a wallet (service) and linked the necessary enterprise services (e.g., Credential Store) before proceeding with this guide.

Credential Offer URL

A credential offer URL is a standardized method, as per the OID4VCI specification, to communicate the issuance of credentials between issuer and wallet. This URL can take various forms, such as a QR code or a link, and generally begins with openid-credential-offer://.

Example Offer URL

openid-credential-offer://issuer.portal.walt.id/?credential_offer=<credential_offer>

Example of a Credential Offer Object for SD-JWT VCs

{
  "credential_issuer": "https://issuer.demo.walt.id",
  "credential_configuration_ids": [
    "identity_credential_vc+sd-jwt"
  ]
  "grants": {
    "authorization_code": {
      "issuer_state": "<issuer_state>"
    },
    "urn:ietf:params:oauth:grant-type:pre-authorized_code": {
      "pre-authorized_code": "<pre-authorized_code>",
      "user_pin_required": false
    }
  }
}

Accepting SD-JWT Credential Offers

SD-JWT credentials have built-in selective disclosure capabilities, allowing the holder to choose which claims to share when presenting the credential.

CURL

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

Example Request

curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/wallet-service-api/credentials/receive' \
  -H 'accept: */*' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "offerUrl": "openid-credential-offer://issuer.example.org/issue/?credential_offer_uri=https%3A%2F%2Fissuer.example.org%2FcredentialOffer%3Fabc123xyz789",
  "keyReference": "example.kms.key1",
  "didReference": "example.didstore.did1"
}'

Path Parameters

  • orgID: - When performing operations within an organization, it is essential to use the organization's Base URL or another valid host alias. For example, if your organization is named test, your default Base URL will be test.enterprise-sandbox.walt.dev when using the sandbox environment.
  • target: resourceIdentifier - The target indicates the organization + tenant + wallet which should be used to receive the credential ({organizationID}.{tenantID}.[walletID]), e.g. waltid.tenant1.wallet1

Body Parameters

  • offerUrl String - An OID4VCI offer URL.
  • keyReference (optional) String - The resource ID (target) of the key to which the received credential should be bound.
  • didReference (optional) String - The DID reference of a DID stored in a linked DID Store.
  • key (optional) Object - A key object or reference key object for external KMS.
  • did (optional) String - DID as a string.
  • metadata (optional) Object - Arbitrary JSON object that will be stored together with the credential.
  • runPolicies (optional) Boolean - If set to true, the wallet service will run any holder policies.

Response Codes

  • 201 - SD-JWT Credential received successfully.

Body

{
    "offeredCredential": {
      "format": "vc+sd-jwt",
        "vct": "http://org.enterprise.localhost:3000/v1/org.tenant.issuer2/issuer-service-api/openid4vc/draft13/identity_credential",
        "credential_definition": {},
        "cryptographic_binding_methods_supported": [
          "jwk"
        ]
    },
    "credentialResponse": {
      "format": "vc+sd-jwt",
        "credential": "eyJraWQiOiJkaWQ6a2V5OnptWWc5YmdLbVJpQ3FUVGQ5TUExdWZWRTl0ZnpVcHR3UXA0R01SeHB0WHF1Sld3NFVqNWRCUVY3QlBQQm5oSEd6RGF3UlJxSmltdnM3c1FZMUVOWTJ3SEdaU2RBN3BQQWhvYThqV0pYR3JaWHNVSFdMI3ptWWc5YmdLbVJpQ3FUVGQ5TUExdWZWRTl0ZnpVcHR3UXA0R01SeHB0WHF1Sld3NFVqNWRCUVY3QlBQQm5oSEd6RGF3UlJxSmltdnM3c1FZMUVOWTJ3SEdaU2RBN3BQQWhvYThqV0pYR3JaWHNVSFdMIiwidHlwIjoidmMrc2Qtand0IiwiYWxnIjoiRWREU0EifQ.eyJnaXZlbl9uYW1lIjoiSm9obiIsImZhbWlseV9uYW1lIjoiRG9lIiwiZW1haWwiOiJqb2huZG9lQGV4YW1wbGUuY29tIiwicGhvbmVfbnVtYmVyIjoiKzEtMjAyLTU1NS0wMTAxIiwiYWRkcmVzcyI6eyJzdHJlZXRfYWRkcmVzcyI6IjEyMyBNYWluIFN0IiwibG9jYWxpdHkiOiJBbnl0b3duIiwicmVnaW9uIjoiQW55c3RhdGUiLCJjb3VudHJ5IjoiVVMifSwiaXNfb3Zlcl8xOCI6dHJ1ZSwiaXNfb3Zlcl8yMSI6dHJ1ZSwiaXNfb3Zlcl82NSI6dHJ1ZSwiaWQiOiJ1cm46dXVpZDplMzUxY2VhZi0zYWIwLTRkYTQtYjY2NC0zNmFjNjk0YzI0NWEiLCJpYXQiOjE3NjEzMTgzODksIm5iZiI6MTc2MTMxODM4OSwiZXhwIjoxNzkyODU0Mzg5LCJfc2RfYWxnIjoic2hhLTI1NiIsImlzcyI6ImRpZDprZXk6em1ZZzliZ0ttUmlDcVRUZDlNQTF1ZlZFOXRmelVwdHdRcDRHTVJ4cHRYcXVKV3c0VWo1ZEJRVjdCUFBCbmhIR3pEYXdSUnFKaW12czdzUVkxRU5ZMndIR1pTZEE3cFBBaG9hOGpXSlhHclpYc1VIV0wiLCJjbmYiOnsia2lkIjoiZGlkOmp3azpleUpyZEhraU9pSlBTMUFpTENKamNuWWlPaUpGWkRJMU5URTVJaXdpYTJsa0lqb2lVVFExVWtvNVdIcGxiM0pqVTFaamVpMVdaRmhQV0VSMmJFaDNkMkpaZDJWWlREQjRkR0ZrZWs5Vk9DSXNJbmdpT2lKTVVXVTRhVzlqUlhkWWIzRkNVSFI1VWt0NVFteEpPR3BUTkVoeGFUZG1Sa2s1UjFwRFVDMW1VbDlySW4wIn0sInZjdCI6Imh0dHA6Ly9vcmcuZW50ZXJwcmlzZS5sb2NhbGhvc3Q6MzAwMC92MS9vcmcudGVuYW50Lmlzc3VlcjIvaXNzdWVyLXNlcnZpY2UtYXBpL29wZW5pZDR2Yy9kcmFmdDEzL2lkZW50aXR5X2NyZWRlbnRpYWwiLCJkaXNwbGF5IjpbXSwiX3NkIjpbIi1WUFBOUEphMkdTbWo5WHlBZXRzb1laWkYtYkRyRHFEb2lkUWl4WTQwcEkiXX0.7DItRsC1Pg6dcV5GFbyiFQpB3k3FnKF0bUlBmuaEgZEsWNRehBTR2Scfj3mHkFs11JIUOHpxewJEvBfr-5C_Aw~WyJOODdkTTNJZnJhdF9PeW45UVFSZC1BIiwiYmlydGhkYXRlIiwiMTk0MC0wMS0wMSJd~",
    }
}
Last updated on November 4, 2025