---
title: "Verifying SD-JWT VC Credentials via OID4VC"
description: "Learn how to request and verify SD-JWT VC via OID4VP using the walt.id Enterprise Verifier API."
stack: "Enterprise Stack (commercial) — version 0.21.0"
stack_version: "0.21.0"
stack_comparison: https://docs.walt.id/community-vs-enterprise.md
canonical_url: https://docs.walt.id/enterprise-stack/services/verifier-service/credential-verification/sd-jwt-vc-oid4vc
generated: 2026-07-08
---
# Verifying SD-JWT VC credentials via OID4VC

This guide provides a comprehensive walkthrough for verifying a SD-JWT VC credentials based on
the [IETF standard](https://datatracker.ietf.org/doc/draft-ietf-oauth-sd-jwt-vc/) using
the walt.id Enterprise verifier API. The verification process will utilize the OID4VCI protocol, an extension of OpenID,
facilitating secure and standardized communication between identities.

**SD-JWT VC**: A digital equivalent of physical credentials such as a driver's license or university
degree. VCs are cryptographically secure, privacy-respecting, and instantly verifiable.

**OID4VCI**: A protocol specifying how parties can issue VCs and present these credentials in a way that's consistent
and secure across platforms ensuring interoperability.

## Enterprise Service Dependencies

To verify credentials, you need to have the following enterprise services setup:

1. [Verifier Service](https://docs.walt.id/enterprise-stack/services/verifier-service/overview.md) - Have a running verifier service. Setup instructions can be found [here](https://docs.walt.id/enterprise-stack/services/verifier-service/setup.md).

## Preparing the Verification

First, determine the type of SD-JWT VC Credential to be verified. Although this guide focuses on a "VerifiableDiploma,"
you can use any credential type compliant with the IETF standard.

The verification process will be as follows:

1. Specify the credential type(s) to request from a user and the verification policies to be applied to the credential(
   s).
2. Optionally provide a success and failure redirect URL, which the user will be redirected to after the verification
   process is completed.

After you have provided the required information:

1. The API generates
   a [Presentation Definition](https://identity.foundation/presentation-exchange/#presentation-definition).
2. API returns a URL which can passed to OIDC-compliant wallet to fulfill the request.

If you have provided a success or failure redirect URL, the user will be redirected to that URL. You can then access the
verification results by using the id of the verification session, which can be found in the URL generated by the API, as
well as in the query or path parameters of the redirect URL.

### Example Verification Request

In this example, we specify the credential we want to verify by supplying the type.

**Option: CURL**

```bash
curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/verifier-service-api/credentials/verify' \
  -H 'accept: */*' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'authorizeBaseUrl: openid4vp://authorize' \
  -H 'responseMode: direct_post' \
  -H 'successRedirectUri: https://example.com/success?id=$id' \
  -H 'errorRedirectUri: https://example.com/error?id=$id' \
  -H 'statusCallbackUri: https://example.com/verificationResult' \
  -H 'statusCallbackApiKey: myAPIKey' \
  -H 'stateId: myUniqueStateValue' \
  -H 'Content-Type: application/json' \
  -d '{
  "request_credentials": [
   { "vct": "https://issuer.demo.walt.id/VerifiableDiploma", "format": "vc+sd-jwt" }
  ]
}'
```

**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 + verifier service with which to
  execute
  the credential verification (`{organizationID}.{tenantID}.{verifierServiceID}`), e.g. `waltid.tenant1.verifier1`

**Header Parameters**

- **authorizeBaseUrl** - is used to modify the start of the OID4VC request URL. The default value
  is `openid4vp://authorize` which
  is fine for most use-cases. If you however are required to use the HAIP OID4VC profile, you need to update the value
  as follows: `haip://`

- **responseMode** - should be `direct_post` as the other options are not yet supported.
- **successRedirectUri** (optional) - is used to redirect the user if verification is successful. You can use the `$id`
  placeholder
  to get access to the id of verification session in your application in order to retrieve the verification results.
  E.g. `/success?id=$id` will be replaced with `/success?id=1234567890`
- **errorRedirectUri** (optional) - is used to redirect the user if verification is unsuccessful. You can use the `$id`
  placeholder
  to get access to the id of verification session in your application in order to retrieve the verification results.
  E.g. `/error?id=$id` will be replaced with `/error?id=1234567890`
- **statusCallbackUri** (optional) - URL that should be called when the presentation request has been fulfilled by a
  wallet. The request
  sent will be a `POST` including the whole presentation
  result. [See Verification Status Policies Response](#verification-status-policies-response)
- **statusCallbackApiKey** (optional) - If the endpoint you provide via `statusCallbackUri` is protected, you can use
  the `statusCallbackApiKey` to authenticate.
  The provided key will be appended as Authorization Header to the request.
- **stateId** (optional) - overwrite the unique `state` value which gets created for each verification request with your
  own.
- **openId4VPProfile** (optional) - Define profile for VP (Verifiable Presentation) request. The default is W3C
  OpenID4VP, which can optionally provided as `DEFAULT`.
  Apart from that, you can choose from the following options:
    - `HAIP`: For the OID4VC HAIP profile.
    - `EBSIV3`: For EBSI V3 compliant VP. Learn more [here](https://docs.walt.id/community-stack/verifier/ecosystems/ebsi/overview.md).
    - `ISO_18013_7_MDOC`: For mdoc Openid4VP.

**Body Parameters**

- **vp_policies** - Policies applied to the Verifiable Presentation. A list of policies can be
  found [here](https://docs.walt.id/enterprise-stack/services/verifier-service/policies/overview.md)
- **vc_policies** - Policies applied to all requested credentials. A list of policies can be
  found [here](https://docs.walt.id/enterprise-stack/services/verifier-service/policies/overview.md).
- **request_credentials** - An array of objects detailing the credentials to be requested from the user. Each object
  varies based on the type of credential being requested.
- **expires_in_seconds** - (Optional) _Integer_ - The number of seconds the generated URL will be valid for. If not
  specified, the default will never expire.

  <br/>
  <details><summary>Expand To Learn More</summary>

  Below are the possible credential types and their respective object structures:

    1. **SD-JWT VC Credential (IETF Standard)**

    - **vct**: Specifies the type of credential (e.g., https://issuer.com/identity_credential). This maps to
      the `vct`
      attribute in the SD-JWT VC credential.
    - **format**: Describes the format of the credential. For SD-JWT VC credentials, this would be
      vc+sd-jwt.: Describes the format of the credential. For SD-JWT VC credentials, this would be `vc+sd-jwt`.
       ```json
       { "vct": "test.com/identity_credential", "format": "vc+sd-jwt" }
       ```

    2. **W3C JWT Credential**

    - **type** Specifies the type of credential (e.g., `VerifiableID`, `VerifiableDiploma`). This maps to the `type`
      attribute in W3C credentials.
    - **format**: Describes the format of the credential. For W3C JWT credentials, this would
      be `jwt_vc_json`.
      ```json
      { "type": "ProofOfResidence", "format": "jwt_vc_json" }
      ```

    3. **mDL Credential (ISO/IEC 18013-5)**

    - **doc_type**: Specifies the type of credential (e.g., org.iso.18013.5.1.mDL). This maps to the doc_type
      attribute of
      the mdoc document.
    - **format**: Describes the format of the credential. For mDL credentials, this would be `mso_mdoc`.
      ```json
      { "doc_type": "org.iso.18013.5.1.mDL", "format": "mso_mdoc" }
      ```

  **Optional Parameters**
  <br />
  Next to describing the type and format of the credential, the objects also take an optional `policies` and `id`
  attribute

    - **policies**: An array of policies to apply to the specified credential. A list of all policies can be
      found [here](https://docs.walt.id/enterprise-stack/services/verifier-service/policies/overview.md).
    - **id**: Used to set a specific id for the
      generated [Presentation Definition](https://identity.foundation/presentation-exchange/spec/v1.0.0/#presentation-definition).
      If not set,
      the verifier API auto-assigns a generated one.

  **Full Examples**
    ```json
     {
      "vct": "ProofOfResidence",
      "format": "vc+sd-jwt",
      "policies": [
        "schema",
        {
          "policy": "webhook",
          "args": "https://example.org/abc/xyz"
        }
      ],
      "id": "test123"
     } 

    ```

</details>

### Example Verification Request 2 - Defining VC/VP Policies

**Error:**

Please note that if you are using the HAIP profile, you cannot specify custom policies at this point.

<br/>

In this example, we're not only specifying the types of credentials to verify, but also defining specific policies that
should be executed upon their verification. These include Verifiable Credential (VC) policies applied to credentials,
or Verifiable Presentation (VP) policies applied to the VP. The default policy applied for both VP and VC(s) is the
signature policy. A list of available policies can be found [here](https://docs.walt.id/enterprise-stack/services/verifier-service/policies/overview.md).

It's important to note that VC policies, once defined, are applied globally - that is, they are enacted on all requested
credentials within the scope of the verification. In a subsequent section, we'll delve into how to customize and
apply specific policies to individual credentials.

We will now specify these in the verification request alongside the `request_credentials` parameter (previously
explained)
using `vc_policies` and `vp_policies`. These represent lists of policies - either one, or both, can be provided.
The structure for both is identical.

VC and VP policies are formatted as lists: the policy can be represented as a string if no arguments are required,
or as an object if arguments are needed.

**Example Polices**

```json
[
  "signature",
  // policy without argument
  "expired",
  // policy without argument
  "not-before",
  // policy without argument
  {
    "policy": "webhook",
    "args": "https://example.org/abc/xyz"
  }
  // policy with argument
]
```

**Initiation Request**

**Option: CURL**

```bash
curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/verifier-service-api/credentials/verify' \
  -H 'accept: */*' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'authorizeBaseUrl: openid4vp://authorize' \
  -H 'responseMode: direct_post' \
  -H 'successRedirectUri: https://example.com/success?id=$id' \
  -H 'errorRedirectUri: https://example.com/error?id=$id' \
  -H 'statusCallbackUri: https://example.com/verificationResult' \
  -H 'statusCallbackApiKey: myAPIKey' \
  -H 'stateId: myUniqueStateValue' \
  -H 'Content-Type: application/json' \
  -d '{
      "vp_policies": ["signature", "expired", "not-before"],
      "vc_policies": ["signature", "expired", "not-before",
       {"policy": "webhook", "args": "https://example.org/abc/xyz"}],
      "request_credentials": [
       { "vct": "https://issuer.demo.walt.id/VerifiableDiploma", "format": "vc+sd-jwt" }
      ]
   }'
```

**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 + verifier service with which to
  execute
  the credential verification (`{organizationID}.{tenantID}.{verifierServiceID}`), e.g. `waltid.tenant1.verifier1`

**Header Parameters**

- **authorizeBaseUrl** - is used to modify the start of the OID4VC request URL. If you are using the
  cross-device
  flow, where you will display the URL as a QR code, you can leave the value as `openid4vp://authorize` or if you don't
  know the wallet the user will be using to claim the credential. If you are using the same device flow, where you
  already
  know the user's wallet and want the user to be able to go directly to it, you can use the wallet URL path that is able
  to
  receive an OIDC request as a query parameter. Our wallet for example can receive OID4VC requests here
  `https://wallet.demo.walt.id/wallet-api/wallet/{wallet}/exchange/useOfferRequest`.

- **responseMode** - should be `direct_post` as the other options are not yet supported.
- **successRedirectUri** (optional) - is used to redirect the user if verification is successful. You can use the `$id`
  placeholder
  to get access to the id of verification session in your application in order to retrieve the verification results.
  E.g. `/success?id=$id` will be replaced with `/success?id=1234567890`
- **errorRedirectUri** (optional) - is used to redirect the user if verification is unsuccessful. You can use the `$id`
  placeholder
  to get access to the id of verification session in your application in order to retrieve the verification results.
  E.g. `/error?id=$id` will be replaced with `/error?id=1234567890`
- **statusCallbackUri** (optional) - URL that should be called when the presentation request has been fulfilled by a
  wallet. The request
  sent will be a `POST` including the whole presentation
  result. [See Verification Status Policies Response](#verification-status-policies-response)
- **statusCallbackApiKey** (optional) - If the endpoint you provide via `statusCallbackUri` is protected, you can use
  the `statusCallbackApiKey` to authenticate.
  The provided key will be appended as Authorization Header to the request.
- **stateId** (optional) - overwrite the unique `state` value which gets created for each verification request with your
  own.
- **openId4VPProfile** (optional) - Define profile for VP (Verifiable Presentation) request. The default is W3C
  OpenID4VP, which can optionally provided as `DEFAULT`.
  Apart from that, you can choose from the following options:
    - `HAIP`: For the OID4VC HAIP profile.
    - `EBSIV3`: For EBSI V3 compliant VP. Learn more [here](https://docs.walt.id/community-stack/verifier/ecosystems/ebsi/overview.md).
    - `ISO_18013_7_MDOC`: For mdoc Openid4VP.

**Body Parameters**

- **vp_policies** - Policies applied to the Verifiable Presentation. A list of policies can be
  found [here](https://docs.walt.id/enterprise-stack/services/verifier-service/policies/overview.md)
- **vc_policies** - Policies applied to all requested credentials. A list of policies can be
  found [here](https://docs.walt.id/enterprise-stack/services/verifier-service/policies/overview.md).
- **request_credentials** - An array of objects detailing the credentials to be requested from the user. Each object
  varies based on the type of credential being requested.
  <br/>
  <details><summary>Expand To Learn More</summary>

  Below are the possible credential types and their respective object structures:

    1. **SD-JWT VC Credential (IETF Standard)**

    - **vct**: Specifies the type of credential (e.g., https://issuer.com/identity_credential). This maps to
      the `vct`
      attribute in the SD-JWT VC credential.
    - **format**: Describes the format of the credential. For SD-JWT VC credentials, this would be
      vc+sd-jwt.: Describes the format of the credential. For SD-JWT VC credentials, this would be `vc+sd-jwt`.
       ```json
       { "vct": "test.com/identity_credential", "format": "vc+sd-jwt" }
       ```

    2. **W3C JWT Credential**

    - **type** Specifies the type of credential (e.g., `VerifiableID`, `VerifiableDiploma`). This maps to the `type`
      attribute in W3C credentials.
    - **format**: Describes the format of the credential. For W3C JWT credentials, this would
      be `jwt_vc_json`.
      ```json
      { "type": "ProofOfResidence", "format": "jwt_vc_json" }
      ```

    3. **mDL Credential (ISO/IEC 18013-5)**

    - **doc_type**: Specifies the type of credential (e.g., org.iso.18013.5.1.mDL). This maps to the doc_type
      attribute of
      the mdoc document.
    - **format**: Describes the format of the credential. For mDL credentials, this would be `mso_mdoc`.
      ```json
      { "doc_type": "org.iso.18013.5.1.mDL", "format": "mso_mdoc" }
      ```

  **Optional Parameters**
  <br />
  Next to describing the type and format of the credential, the objects also take an optional `policies` and `id`
  attribute

    - **policies**: An array of policies to apply to the specified credential. A list of all policies can be
      found [here](https://docs.walt.id/enterprise-stack/services/verifier-service/policies/overview.md).
    - **id**: Used to set a specific id for the
      generated [Presentation Definition](https://identity.foundation/presentation-exchange/spec/v1.0.0/#presentation-definition).
      If not set,
      the verifier API auto-assigns a generated one.

  **Full Examples**
    ```json
     {
      "vct": "ProofOfResidence",
      "format": "vc+sd-jwt",
      "policies": [
        "schema",
        {
          "policy": "webhook",
          "args": "https://example.org/abc/xyz"
        }
      ],
      "id": "test123"
     } 

    ```

</details>

Upon execution, the system generates a URL, which can be shared directly with users or displayed as a QR code.

### Example Verification Request 3: Applying Policies to Specific Credentials

**Error:**

Please note that if you are using the HAIP profile, you cannot specify custom policies at this point.

<br/>

In this example, which builds up on the previous ones, we'll demonstrate how to apply specific policies to a distinct
credential in the verification process. This is achieved by specifying next to the required credential type and format,
the policies that should be applied as an array in the credential specification object which goes into the
`requested_credentials` array. A list of supported policies can be
found [here](https://docs.walt.id/enterprise-stack/services/verifier-service/policies/overview.md).

Here's how it looks in practice:

```json
{
  "vp_policies": [
    "signature",
    "expired"
  ],
  "vc_policies": [
    "signature",
    "expired"
  ],
  "request_credentials": [
    {
      "vct": "https://issuer.demo.walt.id/VerifiableId",
      "format": "vc+sd-jwt"
    },
    {
      "vct": "https://issuer.demo.walt.id/ProofOfResidence",
      "format": "vc+sd-jwt"
    },
    {
      "vct": "https://issuer.demo.walt.id/OpenBadgeCredential",
      "format": "vc+sd-jwt"
      "policies": [
        "signature",
        {
          "policy": "webhook",
          "args": "https://example.org/abc/xyz"
        }
      ]
    }
  ]
}
```

In this code snippet, we extended the regular credential specification object that goes into `request_credentials`
to include policies that should be applied only to the "OpenBadgeCredential". The first policy "signature" doesn't
require any arguments and can therefore be provided as a string. The "webhook" policy does require an argument and is
therefore provided as an object. A list of different types of policies and their required arguments can be
found [here](https://docs.walt.id/enterprise-stack/services/verifier-service/policies/overview.md).

Meanwhile, the other requested credentials, "VerifiableId" and "ProofOfResidence", don't specify and custom policies,
meaning they will be verified against the globally defined "vp_policies" and "vc_policies".

**Initiation Request**

**Option: CURL**

```bash
curl -X 'POST' \
'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/verifier-service-api/credentials/verify' \
-H 'accept: */*' \
-H 'Authorization: Bearer {yourToken}' \
-H 'authorizeBaseUrl: openid4vp://authorize' \
-H 'responseMode: direct_post' \
-H 'successRedirectUri: https://example.com/success?id=$id' \
-H 'errorRedirectUri: https://example.com/error?id=$id' \
-H 'statusCallbackUri: https://example.com/verificationResult' \
-H 'statusCallbackApiKey: myAPIKey' \
-H 'stateId: myUniqueStateValue' \
-H 'Content-Type: application/json' \
-d '{
  "vp_policies": [
    "signature",
    "expired"
  ],
  "vc_policies": [
    "signature",
    "expired"
  ],
  "request_credentials": [
    {
      "vct": "https://issuer.demo.walt.id/VerifiableId",
      "format": "vc+sd-jwt"
    },
    {
      "vct": "https://issuer.demo.walt.id/ProofOfResidence",
      "format": "vc+sd-jwt"
    },
    {
      "vct": "https://issuer.demo.walt.id/OpenBadgeCredential",
      "format": "vc+sd-jwt"
      "policies": [
        "signature",
        {
          "policy": "webhook",
          "args": "https://example.org/abc/xyz"
        }
      ]
    }
  ]
}'
```

**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 + verifier service with which to
  execute
  the credential verification (`{organizationID}.{tenantID}.{verifierServiceID}`), e.g. `waltid.tenant1.verifier1`

**Header Parameters**

- **authorizeBaseUrl** - is used to modify the start of the OID4VC request URL. If you are using the
  cross-device
  flow, where you will display the URL as a QR code, you can leave the value as `openid4vp://authorize` or if you don't
  know the wallet the user will be using to claim the credential. If you are using the same device flow, where you
  already
  know the user's wallet and want the user to be able to go directly to it, you can use the wallet URL path that is able
  to
  receive an OIDC request as a query parameter. Our wallet for example can receive OID4VC requests here
  `https://wallet.demo.walt.id/wallet-api/wallet/{wallet}/exchange/useOfferRequest`.

- **responseMode** - should be `direct_post` as the other options are not yet supported.
- **successRedirectUri** (optional) - is used to redirect the user if verification is successful. You can use the `$id`
  placeholder
  to get access to the id of verification session in your application in order to retrieve the verification results.
  E.g. `/success?id=$id` will be replaced with `/success?id=1234567890`
- **errorRedirectUri** (optional) - is used to redirect the user if verification is unsuccessful. You can use the `$id`
  placeholder
  to get access to the id of verification session in your application in order to retrieve the verification results.
  E.g. `/error?id=$id` will be replaced with `/error?id=1234567890`
- **statusCallbackUri** (optional) - URL that should be called when the presentation request has been fulfilled by a
  wallet. The request
  sent will be a `POST` including the whole presentation
  result. [See Verification Status Policies Response](#verification-status-policies-response)
- **statusCallbackApiKey** (optional) - If the endpoint you provide via `statusCallbackUri` is protected, you can use
  the `statusCallbackApiKey` to authenticate.
  The provided key will be appended as Authorization Header to the request.
- **stateId** (optional) - overwrite the unique `state` value which gets created for each verification request with your
  own.
- **openId4VPProfile** (optional) - Define profile for VP (Verifiable Presentation) request. The default is W3C
  OpenID4VP, which can optionally provided as `DEFAULT`.
  Apart from that, you can choose from the following options:
    - `HAIP`: For the OID4VC HAIP profile.
    - `EBSIV3`: For EBSI V3 compliant VP. Learn more [here](https://docs.walt.id/community-stack/verifier/ecosystems/ebsi/overview.md).
    - `ISO_18013_7_MDOC`: For mdoc Openid4VP.

**Body Parameters**

- **vp_policies** - Policies applied to the Verifiable Presentation. A list of policies can be
  found [here](https://docs.walt.id/enterprise-stack/services/verifier-service/policies/overview.md)
- **vc_policies** - Policies applied to all requested credentials. A list of policies can be
  found [here](https://docs.walt.id/enterprise-stack/services/verifier-service/policies/overview.md).
- **request_credentials** - An array of objects detailing the credentials to be requested from the user. Each object
  varies based on the type of credential being requested.
  <br/>
  <details><summary>Expand To Learn More</summary>

  Below are the possible credential types and their respective object structures:

    1. **SD-JWT VC Credential (IETF Standard)**

    - **vct**: Specifies the type of credential (e.g., https://issuer.com/identity_credential). This maps to
      the `vct`
      attribute in the SD-JWT VC credential.
    - **format**: Describes the format of the credential. For SD-JWT VC credentials, this would be
      vc+sd-jwt.: Describes the format of the credential. For SD-JWT VC credentials, this would be `vc+sd-jwt`.
       ```json
       { "vct": "test.com/identity_credential", "format": "vc+sd-jwt" }
       ```

    2. **W3C JWT Credential**

    - **type** Specifies the type of credential (e.g., `VerifiableID`, `VerifiableDiploma`). This maps to the `type`
      attribute in W3C credentials.
    - **format**: Describes the format of the credential. For W3C JWT credentials, this would
      be `jwt_vc_json`.
      ```json
      { "type": "ProofOfResidence", "format": "jwt_vc_json" }
      ```

    3. **mDL Credential (ISO/IEC 18013-5)**

    - **doc_type**: Specifies the type of credential (e.g., org.iso.18013.5.1.mDL). This maps to the doc_type
      attribute of
      the mdoc document.
    - **format**: Describes the format of the credential. For mDL credentials, this would be `mso_mdoc`.
      ```json
      { "doc_type": "org.iso.18013.5.1.mDL", "format": "mso_mdoc" }
      ```

  **Optional Parameters**
  <br />
  Next to describing the type and format of the credential, the objects also take an optional `policies` and `id`
  attribute

    - **policies**: An array of policies to apply to the specified credential. A list of all policies can be
      found [here](https://docs.walt.id/enterprise-stack/services/verifier-service/policies/overview.md).
    - **id**: Used to set a specific id for the
      generated [Presentation Definition](https://identity.foundation/presentation-exchange/spec/v1.0.0/#presentation-definition).
      If not set,
      the verifier API auto-assigns a generated one.

  **Full Examples**
    ```json
     {
      "vct": "ProofOfResidence",
      "format": "jwt_vc_json",
      "policies": [
        "schema",
        {
          "policy": "webhook",
          "args": "https://example.org/abc/xyz"
        }
      ],
      "id": "test123"
     } 

    ```

</details>

Upon execution, the system generates a URL, which can be shared directly with users or displayed as a QR code.

### Example Verification Request 4: Implementing a Custom Presentation Definition

In this example, we'll explore how you can provide your own `input_descriptor` that will be merged with the
autogenerated
presentation definition.
You can specify your custom `input_descriptor` for
the [presentation definition](https://identity.foundation/presentation-exchange/#presentation-definition)
via an object in the `request_credentials` array, see example blow.

**Note:**

Important: Please also provide an id in the `input_descriptor` object.

**Example**

```json
{
  "vp_policies": [
    ...
  ],
  "vc_policies": [
    ...
  ],
  "request_credentials": [
    {
      "vct": "VerifiableId",
      "format": "vc+sd-jwt"
    },
    {
      "format": "vc+sd-jwt",
      "vct": "https://issuer.com/identity_credential",
      "input_descriptor": {
        "id": "234",
        "constraints": {
          "fields": [
            {
              "path": [
                "$.birthdate"
              ],
              "filter": {
                "type": "string",
                "pattern": ".*"
              }
            }
          ]
        }
      }
    }
  ]
}
```

On execution the verifier API will auto-generate the input descriptor for the `VerifiableId` credential that we
specified via
the regular object and merge it with our custom input descriptor of the `identity_credential` to form the final
presentation definition.

**Note:**

When using the `input_descriptor` make sure to also provide the `presentation-definition` policy in the
`vp_policies` array to ensure the constraints specified are checked during verification.

### Example Verification Request 5: Using Relational Constraints

The `presentation-definition` policy also implements the
[relational constraint feature](https://identity.foundation/presentation-exchange/#relational-constraint-feature).
These constraints let you define relations between issuer, holder and multiple credentials
within the `input_descriptor`.

#### subject_is_issuer

Use this constraint when you want to ensure that the credential was self issued by the presenter. The verification will only succeed if the issuer DID matches the credential subject.

```json
{
  "vp_policies": ["presentation-definition"],
  "request_credentials": [
    {
      "input_descriptor": {
        "id": "OpenBadgeCredential",
        "format": { "jwt_vc_json": { "alg": ["EdDSA"] } },
        "constraints": {
          "subject_is_issuer": "required",
          "fields": [
            {
              "path": ["$.vc.type"],
              "filter": { "type": "string", "pattern": "OpenBadgeCredential" }
            }
          ]
        }
      }
    }
  ]
}
```

#### is_holder

The `is_holder` constraint ensures that the presenter is the rightful holder of
the credential. Only credentials issued to the presenter will satisfy the
selected field references.

```json
{
  "vp_policies": ["presentation-definition"],
  "request_credentials": [
    {
      "input_descriptor": {
        "id": "OpenBadgeCredential",
        "format": { "jwt_vc_json": { "alg": ["EdDSA"] } },
        "constraints": {
          "is_holder": [
            { "field_id": ["achname"], "directive": "required" }
          ],
          "fields": [
            {
              "path": ["$.vc.type"],
              "filter": { "type": "string", "pattern": "OpenBadgeCredential" }
            },
            {
              "id": "achname",
              "path": ["$.vc.credentialSubject.achievement.name"]
            }
          ]
        }
      }
    }
  ]
}
```

#### same_subject

Apply `same_subject` to confirm that multiple credentials describe the same
entity. The verifier cross-checks the provided field IDs and requires their
subjects to be identical.

```json
{
  "vp_policies": ["presentation-definition"],
  "request_credentials": [
    {
      "input_descriptor": {
        "id": "OpenBadgeCredential",
        "format": { "jwt_vc_json": { "alg": ["EdDSA"] } },
        "constraints": {
          "same_subject": [
            { "field_id": ["obc_achievement", "udc_degree"], "directive": "required" }
          ],
          "fields": [
            {
              "path": ["$.vc.type"],
              "filter": { "type": "string", "pattern": "OpenBadgeCredential" }
            },
            {
              "id": "obc_achievement",
              "path": ["$.vc.credentialSubject.achievement.name"]
            }
          ]
        }
      }
    },
    {
      "input_descriptor": {
        "id": "UniversityDegreeCredential",
        "format": { "jwt_vc_json": { "alg": ["EdDSA"] } },
        "constraints": {
          "fields": [
            {
              "path": ["$.vc.type"],
              "filter": { "type": "string", "pattern": "UniversityDegreeCredential" }
            },
            {
              "id": "udc_degree",
              "path": ["$.vc.credentialSubject.degree.name"]
            }
          ]
        }
      }
    }
  ]
}
```

## Presenting the Credential via walt.id Wallet

Using the URL returned by the verification request, we can fulfill the request using the
[hosted wallet](https://wallet.demo.walt.id) by walt.id. Either show the URL as QR code and scan it with a camera or provide
the URL as is in the
text field below the camera once you click on "Scan to receive or present credentials" in the web wallet credentials
overview page in the top right corner.

## Retrieving the Verification Status

After the user presents the credential(s), you can verify the status by performing the following call with the
`state` value obtained from the URL query params you shared with the user previously.

**Example**

```
openid4vp://authorize?...state=waltid.tenant1.verifier1.fb94470b-bcee-4ed7-93f5-906a4f5f585d...
```

Making the call to receive the verification result

```bash
curl -X 'GET' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/verifier-service-api/credentials/sessions/view' \
  -H 'accept: */*'
  -H 'Authorization: Bearer {yourToken}'
```

**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 + verifier service + sessionID to request
   (`{organizationID}.{tenantID}.{verifierServiceID}.{sessionID}`),
  e.g. `waltid.tenant1.verifier1.fb94470b-bcee-4ed7-93f5-906a4f5f585d`

## Verification Status Policies Response

The response of the verification status call will contain the status of the verification policies applied to the
credential(s) presented by the user. The policy results will be in the following format:

```json
{
  "verificationResult": true,
  "policyResults": {
    "results": [
      {
        "credential": "VerifiableDiploma",
        "policies": [
          {
            "policy": "signature",
            "is_success": true
          }
        ]
      }
    ]
  }
}
```

The `verificationResult` field will be `true` if all policies were successful, otherwise it will be `false`.

The `policyResults` field will contain the results of the policies applied to each credential. The `credential` field
will contain the name of the credential, and the `policies` field will contain the results of the policies applied to
the credential. The `policy` field will contain the name of the policy, and the `is_success` field will contain the
result of the policy.
