> For the complete documentation index, see [llms.txt](https://docs.indicio.tech/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.indicio.tech/developer/indicio-proven-r/how-to-guides/sd-jwt-vcs.md).

# SD-JWT VCs

## Issuance

#### Create Credential-Supported (Schema):

* Before issuing a credential, you will need to create the “blueprint” (AKA class, schema, credential-type, etc.). See the following code example.&#x20;

### Example curl Command:

```
curl --location 'https://buckets4life.share.zrok.io/api/v1/oid4vci/credentials-supported' \
--header 'x-api-key: HuNsaIP9w0LsM5vqRhWprqLShgWLvb2yMAyuYUjWqd4=' \
--header 'Content-Type: application/json' \
--header 'Cookie: sessionId=s%3AIxantPaS5ZGMmrHZDetRQHQIVTRBiNBL.DAjBpQO8pxrjJdM4jQUYJU%2FlxzGAGIJcUzM%2FM7zltk0' \
--data '{
  "format": "vc+sd-jwt",
  "id": "IDCard",
  "format_data": {
      "vct": "ExampleIDCard",
      "claims": {
          "given_name": {
              "mandatory": true,
              "value_type": "string"
          },
          "family_name": {
              "mandatory": true,
              "value_type": "string"
          },
          "something_nested": {
              "key1": {
                  "key2": {
                      "key3": {
                          "mandatory": true,
                          "value_type": "string"
                      }
                  }
              }
          },
          "age_equal_or_over": {
              "12": {
                  "mandatory": true,
                  "value_type": "boolean"
              },
              "14": {
                  "mandatory": true,
                  "value_type": "boolean"
              },
              "16": {
                  "mandatory": true,
                  "value_type": "boolean"
              },
              "18": {
                  "mandatory": true,
                  "value_type": "boolean"
              },
              "21": {
                  "mandatory": true,
                  "value_type": "boolean"
              },
              "65": {
                  "mandatory": true,
                  "value_type": "boolean"
              }
          }
      }
  },
  "vc_additional_data": {
      "sd_list": [
          "/given_name",
          "/family_name",
          "/age_equal_or_over/12",
          "/age_equal_or_over/14",
          "/age_equal_or_over/16",
          "/age_equal_or_over/18",
          "/age_equal_or_over/21",
          "/age_equal_or_over/65"
      ]
  }
}'
```

### Request:

* `format` {string}: The format of the credential. Will always be `vc+sd-jwt` for issuing SD-JWTs.
* `id` {string}: The name of the credential (unique to Proven).
* `format_data.cryptographic_binding_methods_supported` {object}: Not currently in use; should be ignored.
* `format_data.display` {object}: Not currently in use; should be ignored.
* `format_data.vct` {object}: String or url that identifies the type of SD-JWT.
* `format_data.claims` {object}: An object with the body of your credential. The `mandatory` (optional) field signifies if the field is required to issue the credential. The `value_type` (optional) is the `data_type` of the field. It can accept the following types: string, number, and image media types such as image/jpeg as defined in IANA media type registry for images (<https://www.iana.org/assignments/media-types/media-types.xhtml#image>). Other values may also be used.
* `vc_additional_data.sd_list` {array}: Paths to values that can be asked for specifically and/or omitted. If the path to a value is not in the `sd_list`, then the value will be present each time that credential is presented.

### Response:

* `supported_cred_id` {string}: You will need this for the next step, so make sure to copy it.

### Issue Credential:

* After creating the credential supported, you will see a `supported_cred_id`. Make sure to copy it, as you will need it in the following step.&#x20;
* Now that you have your `credential_supported` record, you will be able to issue credentials using that `credential_supported`.

### Example curl Command:

```
curl --location 'https://buckets4life.
    share.zrok.io/api/v1/oid4vci/issue' \
--header 'x-api-key:
    HuNsaIP9w0LsM5vqRhWprqLShgWLvb2yMAyuYUj
    Wqd4=' \
--header 'Content-Type: application/json' \
--header 'Cookie:
    sessionId=s%3AIxantPaS5ZGMmrHZDetRQHQIV
    TRBiNBL.
    DAjBpQO8pxrjJdM4jQUYJU%2FlxzGAGIJcUzM%2
    FM7zltk0' \
--data '{
    "supported_cred_id":
        "4e1a5734-629d-41ae-abc1-345732ce75
        ab",
    "credential_subject": {
        "given_name": "Alice",
        "family_name": "Smith",
        "something_nested": {
            "key1": {
                "key2": {
                    "key3": "something
                        nested"
                }
            }
        },
        "source_document_type": "id_card",
        "age_equal_or_over": {
            "12": true,
            "14": true,
            "16": true,
            "18": true,
            "21": true,
            "65": false
        }
    }
}'
```

### Request:

* `supported_cred_id` {string}: This is the `supported_cred_id` you copied from the previous step.
* `credential_subject` {object}: It should match your `credential_supported.format_data.claims` object from the previous step. However, instead of having an object with `value_type` or `mandatory`, you will have the key equal to the value.

### Response:

* In the response you will see an `offer_uri`. This can be either turned into a QR code or put into the SDK to accept the offer and receive the credential. If you hit the `GET https://{{host}}/api/v1/oid4vci/exchanges` endpoint, then you will be able to check on the status of your credential request.&#x20;

## Presentation (Verifying the Credential)

#### Presentation Definition (Schema):

* Before you can present a credential, you will need to create the “blueprint” (AKA class, schema, credential-type, etc.). Use the following example to complete the step.&#x20;

### Example curl Command:

```
curl --location 'https://buckets4life.share.zrok.io/api/v1/oid4vp/presentation-definitions' \
--header 'x-api-key: HuNsaIP9w0LsM5vqRhWprqLShgWLvb2yMAyuYUjWqd4=' \
--header 'Content-Type: application/json' \
--header 'Cookie: sessionId=s%3AIxantPaS5ZGMmrHZDetRQHQIVTRBiNBL.DAjBpQO8pxrjJdM4jQUYJU%2FlxzGAGIJcUzM%2FM7zltk0' \
--data '{
  "pres_def": {
      "purpose": "Present basic profile info",
      "id": "<<put uuid_v4 here>>",
      "input_descriptors": [
          {
              "format": {
                  "vc+sd-jwt": {}
              },
              "id": "ID Card",
              "name": "Profile",
              "purpose": "Present basic profile info",
              "constraints": {
                  "limit_disclosure": "required",
                  "fields": [
                      {
                          "path": [
                              "$.vct"
                          ]
                      },
                      {
                          "path": [
                              "$.given_name"
                          ]
                      },
                      {
                          "path": [
                              "$.family_name"
                          ]
                      },
                      {
                          "path": [
                              "$.something_nested.key1.key2.key3"
                          ]
                      }
                  ]
              }
          }
      ]
  }
}'
```

* `pres_def.purpose` {string}: Enter a useful description of this presentation definition.&#x20;
* `pres_def.id`: This is a unique UUID for presentation definition.
* `pres_def.input_descriptors` {array}:  This is an array of credentials you will need for this presentation.&#x20;
  * `format` will be the credential type
  * `id` must not conflict with other IDs in `input_descriptors`
  * `name` will be a human-friendly name for you
  * `purpose` will also be a human-friendly field for you
* `pres_def.input_descriptors.constraints.limit_discolsure` {boolean}:&#x20;
  * `required` : This indicates that the [Conformant Consumer](https://identity.foundation/presentation-exchange/spec/v2.0.0/#term:conformant-consumer) MUST limit submitted fields to those listed in the fields array (if present). [Conformant Consumers](https://identity.foundation/presentation-exchange/spec/v2.0.0/#term:conformant-consumers) are not required to implement support for this value, but they MUST understand this value sufficiently to return nothing (or cease the interaction with the [Verifier](https://identity.foundation/presentation-exchange/spec/v2.0.0/#term:verifier)) if they do not implement it.
  * `preferred`: This indicates that the [Conformant Consumer](https://identity.foundation/presentation-exchange/spec/v2.0.0/#term:conformant-consumer) SHOULD limit submitted fields to those listed in the fields array (if present).
* `pres_def.input_descriptors.constraints.fields` {array}:  These are objects with the path to the values you would like to see when they are disclosed.

### Presentation Request:

After creating the presentation definition, you will see a `pres_def_id`. Make sure to copy it, as you will need it in the following step.&#x20;

Now that you have your presentation definition record, you will be able to present credentials using that presentation definition.

### Example curl Command:

```
curl --location 'https://buckets4life.share.zrok.io/api/v1/oid4vp/request' \
--header 'x-api-key: HuNsaIP9w0LsM5vqRhWprqLShgWLvb2yMAyuYUjWqd4=' \
--header 'Content-Type: application/json' \
--header 'Cookie: sessionId=s%3AIxantPaS5ZGMmrHZDetRQHQIVTRBiNBL.DAjBpQO8pxrjJdM4jQUYJU%2FlxzGAGIJcUzM%2FM7zltk0' \
--data '{
  "pres_def_id": "51bcd5fb-a95a-4650-808f-d9ed91847d51",
  "vp_formats": {
      "vc+sd-jwt": {
          "sd-jwt_alg_values": [
              "ES256",
              "ES384"
          ],
          "kb-jwt_alg_values": [
              "ES256",
              "ES384"
          ]
      }
  }
}'
```

### Request:

* `pres_def_id` {string}: Copy the `pres_def_id` from the previous step.
* Keep the rest of this request the same.&#x20;

### Response:

In the response, you will see a `request_uri`. This can be either turned into a QR code or put into the SDK to accept the presentation and send the credential. If you hit the `GET https://{{host}}/api/v1/oid4vp/presentations` endpoint, then you will be able to check on the status of your credential presentation.

## Verifications - Read Verifications By ID (JSON-LD)

```
/api/v1/verifications/json-ld/<verification_id> - GET
```

This endpoint fetches a JSON-LD verification request record by using its `verification_id`.

### **Response Body Information:**

The response body is an array of records. The following information is the data of each record:

<table data-header-hidden><thead><tr><th></th><th width="147"></th><th></th><th></th></tr></thead><tbody><tr><td><strong>Field name</strong></td><td><strong>Expected type/ values</strong></td><td><strong>Examples</strong></td><td><strong>Notes</strong></td></tr><tr><td>verification_id</td><td>integer</td><td>10</td><td>Primary identifier for the verification request record</td></tr><tr><td>connection_id</td><td>string</td><td>e2aed3c4-c0a1-4711-902e-f0a9eba618da</td><td>Identifier that ties the used connection to the verification request record</td></tr><tr><td>contact_id</td><td>string</td><td>contact123</td><td>Optional contact ID string used for processing the request record by known contact. Used with invitation_id, has first priority</td></tr><tr><td>invitation_id</td><td>integer</td><td>123</td><td>Optional integer used to process the request record by a connection tied to the invitation_id. Used with contact_id, has second priority</td></tr><tr><td>context</td><td>array</td><td>[“...”, “...”]</td><td>List of contexts used for the verification record</td></tr><tr><td>attributes</td><td>array</td><td>[...]</td><td>List of attributes to be verified</td></tr><tr><td>wallet_id</td><td>string</td><td>407e6215-17c5-4c81-901e-d75d9cc1a75a</td><td>Identifier that ties this record to an existing wallet</td></tr><tr><td>label</td><td>string</td><td>Email</td><td>Label for the verification request record</td></tr><tr><td>timeout</td><td>integer</td><td>10</td><td>Number of seconds the initial request waited for a completed request record</td></tr><tr><td>rule</td><td>string</td><td>“no rule”</td><td>Rules for the verification request</td></tr><tr><td>meta_data</td><td>object</td><td>null</td><td>Metadata for the verification request record</td></tr><tr><td>state</td><td>string</td><td>done</td><td>Current state of the verification request record</td></tr><tr><td>complete</td><td>boolean</td><td>true</td><td>This field does not indicate a verified request record, only that the request record has finished its process. </td></tr><tr><td>result</td><td>boolean</td><td>true</td><td>Indicates a verified request record. This field should be used alongside “complete” to determine a successful request record.</td></tr><tr><td>result_string</td><td>string</td><td>Verified</td><td>Custom string for helping to define the state of the request</td></tr><tr><td>result_data</td><td>array</td><td>[...]</td><td>Contains the verified attributes</td></tr><tr><td>presentation_exchange_id</td><td>array</td><td>[...]</td><td>Contains unique IDs for each proof request</td></tr><tr><td>error</td><td>string</td><td>“Controller Error! ….”</td><td>Error message caught while processing the request record</td></tr><tr><td>created_at</td><td>timestamp</td><td>2025-01-06T11:51:10.169Z</td><td>Date/time this record was created</td></tr><tr><td>updated_at</td><td>timestamp</td><td>2025-01-06T11:51:10.169Z</td><td>Date/time this record was last updated</td></tr></tbody></table>

### **Sample Response Body:**

```
{
  "verification_id": 1,
  "connection_id": "e2aed3c4-c0a1-4711-902e-f0a9eba618da",
  "contact_id": null,
  "invitation_id": 1,
  "context": [
    "https://www.w3.org/2018/credentials#VerifiableCredential",
    "https://www.w3.org/2018/credentials/v1",
    "https://purl.imsglobal.org/spec/vc/ob/vocab.html#OpenBadgeCredential"
  ],
  "attributes": [
    "id",
    "criteria"
  ],
  "wallet_id": "407e6215-17c5-4c81-901e-d75d9cc1a75a",
  "label": "your label here",
  "timeout": 15,
  "rule": "no rule",
  "meta_data": null,
  "state": "done",
  "complete": true,
  "result": false,
  "result_string": "Not Verified",
  "result_data": null,
  "presentation_exchange_id": [
    "52778677-a7be-4017-9b21-d146372f07e8"
  ],
  "error": "",
  "created_at": "2025-01-06T13:40:59.623Z",
  "updated_at": "2025-01-06T13:41:02.640Z"
}
```

<figure><img src="/files/AT6rY1DOR8yVo5rsaNQ0" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.indicio.tech/developer/indicio-proven-r/how-to-guides/sd-jwt-vcs.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
