# Truvera overview

[Dock Labs' digital identity platform Truvera ](https://truvera.io/)enables companies to turn verified ID data into trusted reusable digital ID credentials, instantly verify their authenticity and get paid when they are verified by third parties. It comprises an API, a Web App and an ID wallet. Dock Labs has been a leader in decentralized digital identity technology since 2017 and trusted by organizations in diverse sectors, including healthcare, finance, and education.

## Products

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Truvera API</strong></td><td><a href="/files/lKZzk9H3C6KK51L8ADNn">/files/lKZzk9H3C6KK51L8ADNn</a></td><td><a href="/pages/vh2aQdDnWBQKqcBl0BmE">/pages/vh2aQdDnWBQKqcBl0BmE</a></td></tr><tr><td><strong>Truvera Workspace</strong></td><td><a href="/files/jTLiqgMKAXzqdQZUqIJQ">/files/jTLiqgMKAXzqdQZUqIJQ</a></td><td><a href="https://certs.dock.io/">https://certs.dock.io/</a></td></tr><tr><td><strong>Truvera Wallet</strong></td><td><a href="/files/Kc2SLXntBnFgKO8l9jai">/files/Kc2SLXntBnFgKO8l9jai</a></td><td><a href="https://www.dock.io/dock-wallet-app">https://www.dock.io/dock-wallet-app</a></td></tr><tr><td><strong>Truvera Wallet SDK</strong></td><td><a href="/files/ol6ukg2IkHZDDVkKThgZ">/files/ol6ukg2IkHZDDVkKThgZ</a></td><td><a href="https://github.com/docknetwork/sdk">https://github.com/docknetwork/sdk</a></td></tr></tbody></table>

[Truvera API](/truvera-api) easily integrates with your system and data sources, simplifying the creation, verification and management of Verifiable Credentials. No blockchain or cryptography knowledge is required.

[Truvera Workspace](https://truvera.io/): A user-friendly platform​ that enables you to issue, verify, manage, and revoke fraud-proof Verifiable Credentials as well create and manage Decentralized Identifiers (DIDs).

[Credential Wallet ](https://www.dock.io/feature/identity-wallet)SDK and white label: Build credential wallet capabilities inside your existing app with Truvera's powerful Wallet SDK, enabling users to effortlessly store, manage and share their verifiable credentials without having to download an extra app. If you don’t have an existing app, Truvera's white label credential wallet is the best option when development speed is a priority. Try the [Truvera Wallet](/credential-wallet) for free.

[Truvera's Credential SDK ](https://github.com/docknetwork/sdk)contains a Javascript library and tooling to interact for working with Verifiable Credentials, DIDs, Claim Deduction and more. Built with PolkadotJS, it is an open source library that powers Truvera's SaaS API.

## **What can you do with Truvera?**

<details>

<summary>Create and manage decentralized identifiers (DIDs)</summary>

Create DIDs on the cheqd oblockchain using `did:cheqd` method or a non-registry based DID using the `did:key` method.

</details>

<details>

<summary>Issue zero-knowledge-proof verifiable credentials</summary>

Issue credentials that are reusable, verifiable and secure against fraud. Protect your users privacy and improve your data minimization practices by issuing zero-knowledge-proof credentials.

</details>

<details>

<summary>Instantly verify credentials</summary>

Create Verification Requests and send Verification QR Codes to your users. They’ll scan them with their wallet app and you’ll receive instant confirmation of the credentials’ authenticity.

</details>

<details>

<summary>Launch your Digital ID Ecosystem</summary>

Truvera's user-friendly workspace and API allow you to invite and manage trusted issuers and verifiers. Simplify the process of identifying which issuers and verifiers are trustworthy within a particular ecosystem.

</details>

<details>

<summary>Embed an ID Wallet into your app</summary>

Build ID wallet capabilities inside your existing app with Truvera's Wallet SDK. Users can manage and share their verifiable credentials without having to download an extra app.

</details>

## Interoperability

We believe that credentials are most useful when they are interoperable across service providers. Our W3C compliant credential format is designed for maximum interoperability. Our anonymous credential format adheres to many W3C standards, but are designed for maximum privacy protection. We also leverage standards from OpenID, IETF, DIF, and related organizations. [Read more about our supported standards.](/key-standards)

## Get Started

Begin your journey with digital identity by signing up and start issuing verifiable credentials.

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>Sign up</td><td><a href="/files/VUTL75T3gR8uan6FfmKJ">/files/VUTL75T3gR8uan6FfmKJ</a></td><td><a href="https://certs.dock.io/">https://certs.dock.io/</a></td></tr><tr><td>Issue Verifiable Credentials</td><td><a href="/files/2BdgarmlrjUU6QbYJw7j">/files/2BdgarmlrjUU6QbYJw7j</a></td><td><a href="/pages/17vrmqtAsIGxgjL5Kvgi">/pages/17vrmqtAsIGxgjL5Kvgi</a></td></tr><tr><td>See API docs</td><td><a href="/files/L8HcD1gaSOWA7GD2qayo">/files/L8HcD1gaSOWA7GD2qayo</a></td><td><a href="/pages/vh2aQdDnWBQKqcBl0BmE">/pages/vh2aQdDnWBQKqcBl0BmE</a></td></tr></tbody></table>


# Decentralized identity explained

Decentralized identity is a way of managing online identities that do not rely on storing personal data in centralized databases such as social media platforms or government ID systems. Decentralized identity systems enable users to completely own and control their data.

## **The three parties of decentralized identity systems**

1. **Issuer:** An organization that has the authority to issue Verifiable Credentials such a KYC company issuing a KYC credential or online course platform issuing completion certificates.
2. **Holder:** User who owns the credential and stores it in their digital wallet.
3. **Verifier:** The party validating or authenticating the credential like an employer needing to check a candidate’s educational credentials or staff at a store that needs to verify that a customer is at least 18.

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

{% hint style="info" %}
Decentralized identity is often used interchangeably with the term Self-Sovereign Identity (SSI).
{% endhint %}

## The technical building blocks of decentralized identity

### Blockchain

Blockchain acts as an immutable registry containing the Decentralized Identifiers (DIDs) of all credential issuers. When verifying a credential, a Verifier will look up the Issuer's DID to see if it was truly that Issuer that signed that credential.

{% tabs %}
{% tab title="What goes on chain?" %}

* Issuers' Decentralized Identifiers (DIDs) and associated Public Keys
* Revocation Registries
  {% endtab %}

{% tab title="What does not go on chain?" %}

* Personally identifiable information
* Verifiable Credentials. Credentials are stored on the users' devices (e.g. their wallets)
  {% endtab %}
  {% endtabs %}

### **Decentralized IDentifiers (DIDs)**

Decentralized identifiers (DIDs) are unique identifiers that are associated with a digital identity. DIDs are made up of a string of letters and numbers that can be stored on the blockchain and can be used to authenticate that identity.

Here’s an example of a DID registered on the cheqd blockchain.

did:cheqd:mainnet:55e92747-1d14-4116-92eb-b1bcf45eb3f0

Every DID that is created comes with a private and public key pair and some DID methods allow multiple key pairs.

Whenever an organization issues someone a Verifiable Credential, their public DID is attached to that credential. Because the public DID (and issuer’s public key) is stored on the blockchain, whenever a party wants to verify the authenticity of the credentials, they can check the DID on the blockchain to see if it was really the issuer’s private key that signed the Credential.

### Verifiable credentials

Digital credentials that conform to the [Verifiable Credentials Data Model 1.0](https://www.w3.org/TR/vc-data-model/) developed by the World Wide Web Consortium (W3C) can be referred to as Verifiable Credentials. This standard is a “specification \[that] provides a standard way to express credentials on the Web in a way that is cryptographically secure, privacy-respecting, and machine-verifiable.”

**Benefits of verifiable credentials:**

* Instantly verifiable, without the need to contact the issuer
* Tamper-resistant with the use of cryptography
* Privacy preserving by giving holders full control of their data


# Subscription plans & billing

Our pricing plans are designed around your needs and you can get started with a free trial. You can find more information about our [subscription plans on our website.](https://www.dock.io/pricing)

You can find you subscription information in the Plan and billing section.

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

## Cancelling a subscription <a href="#h_253e8060a6" id="h_253e8060a6"></a>

You can cancel your subscription any time and you can use all of the features until the end of the billing cycle.

Go to Plan & Billing and click Manage Billing.

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

You will be redirected to Stripe interface where you can cancel your plan.

## Business continuity

To ensure business continuity in the event Dock closes its operations or is no longer able to service the customer, Dock will ensure that the private keys are delivered to the customer in a secure manner. Dock will also provide comprehensive documentation on how to continue using the DIDs for credential issuance and procedures for revoking any outstanding credentials if needed.


# Solutions


# Reusable identity without a wallet application

## Overview

Users are often asked to perform duplicative identity checks when doing business with an organization. Instead of asking repeatedly for the same evidence, it is better to issue a credential that can be verified the next time the user's identity data is required. However, most users will not have an identity wallet application already provisioned. The Truvera Cloud Wallet allows your platform to store credentials on behalf of your users and help your users to access them when needed.

This guide walks through a simple example of provisioning a wallet for credential storage and integrating it in issuer and verifier services. It achieves this using the following Truvera products:

* [**Truvera Wallet SDK**](/credential-wallet/wallet-sdk) ([@docknetwork/wallet-sdk-web](https://www.npmjs.com/package/@docknetwork/wallet-sdk-web)) — which is used by the client-side wallet to store credentials in [the Truvera Cloud Wallet](/credential-wallet/wallet-sdk/cloud-wallet)'s Encrypted Data Vault (EDV)
* [**Truvera REST API**](/truvera-api) — which is accessed by your [credential issuance](/truvera-api/credentials#issue-credentials) and [proof verification](/truvera-api/presentations) services

The flow has three actors: **Issuer** (e.g., a bank), **Holder** (user's cloud wallet), and **Verifier** (e.g., a financial exchange). For simplicity, this example combines these roles by allowing the issuer and verifier to have access to the holder's wallet access key. It also uses [the OpenID4VCs protocol](/key-standards/interoperability-with-openid) which many developers are already familiar with. Once you understand the example, you should review [the next steps](#next-steps) for guidance on a production architecture.

### Example flow

```
1. SETUP   
- Create Issuer DID and Verifier DID in Truvera workspace   
- Create a Proof Template with ZK predicates (e.g., age >= 18)   
- Add Issuer DID to template's trusted issuers
2. ISSUANCE (Bank/Issuer side)
    POST /openid/issuers  --> get issuerId   
    POST /openid/credential-offers --> get offerUrl   
    wallet.addCredential(offerUrl) --> credential stored in EDV
3. VERIFICATION (Exchange/Verifier side)
    POST /proof-templates/{id}/request --> get proofRequestId + qr URL   
    wallet.submitPresentation({ proofRequestUrl: qr }) --> ZKP submitted
    GET /proof-requests/{id}  (poll) --> verified: true
```

***

### Prerequisites

You'll need these items from the [Truvera Workspace](https://truvera.io/):

| Secret                 | Purpose                                                     | Where used                |
| ---------------------- | ----------------------------------------------------------- | ------------------------- |
| TRUVERA\_API\_KEY      | REST API authentication                                     | Issuer / Verifier service |
| TRUVERA\_API\_URL      | Base URL for REST API (e.g., <https://api-testnet.dock.io>) | Issuer / Verifier service |
|                        |                                                             |                           |
| TRUVERA\_ISSUER\_DID   | DID for signing credentials during issuance                 | Issuer service            |
| TRUVERA\_VERIFIER\_DID | DID for creating proof requests during verification         | Verifier service          |

You also need a [**Schema**](/truvera-api/api-docs) and a [**Proof Template**](/truvera-api/presentations/proof-templates) configured in the Truvera workspace with your [Issuer DID](/truvera-api/dids) added as a trusted issuer.

To create the cloud wallet, you will also need to request a key from Truvera Support (<support@dock.io>):

| Secret                  | Purpose                                       | Where used             |
| ----------------------- | --------------------------------------------- | ---------------------- |
| TRUVERA\_EDV\_AUTH\_KEY | Encrypted Data Vault access for cloud wallets | Wallet service backend |

***

## Example

### 1. Wallet SDK - client side

#### Install

```bash
npm install @docknetwork/wallet-sdk-web@^0.0.10
```

#### Initialize a new wallet

```typescript
import TruveraWebWallet from '@docknetwork/wallet-sdk-web';

// Generate a mnemonic (save this -- it's the recovery key)
const { masterKey, mnemonic } = await TruveraWebWallet.generateCloudWalletMasterKey();

// Initialize the cloud wallet
const wallet = await TruveraWebWallet.initialize({
  edvUrl: 'https://edv.dock.io',
  edvAuthKey: '<your-edv-auth-key>',  // fetch from backend, never hardcode
  networkId: 'testnet',               // or 'mainnet'
  mnemonic
});

// Get the wallet's DID
const didDoc = await wallet.getDID();
const did = didDoc.id;  // e.g., "did:dock:5F3s..."
```

> **Tip:** Wallet initialization can intermittently fail with "Vault indices does not exist" errors. Use a retry loop (3 attempts, 1s delay).

#### Restore an existing wallet

```typescript
// Same call, just pass the stored mnemonic
const wallet = await TruveraWebWallet.initialize({
  edvUrl: 'https://edv.dock.io',
  edvAuthKey: '<your-edv-auth-key>',
  networkId: 'testnet',
  mnemonic: '<stored-mnemonic>'
});
```

#### Import a credential (OID4VC)

```typescript
// offerUrl comes from the issuance API (see Section 2)
const credential = await wallet.addCredential(offerUrl);
```

#### List credentials

```typescript
const credentials = await wallet.getCredentials();
// Returns: [{ id: "urn:uuid:...", type: [...], credentialSubject: {...}, ... }]
```

#### Delete a credential

```typescript
// Access the inner wallet object for removeDocument
const innerWallet = (wallet as any).wallet;
await innerWallet.removeDocument(credentialId);
```

#### Submit a zero-knowledge presentation

```typescript
const result = await wallet.submitPresentation({
  credentials: [{
    id: credential.id,
    attributesToReveal: [
      'credentialSubject.age',
      'credentialSubject.bankTenure'
    ]
  }],
  proofRequestUrl: '<qr-url-from-proof-request>'  // the `qr` field from the API
});
```

> **Important:** The attributesToReveal must match the input\_descriptors in your proof template. The proofRequestUrl must be the qr field returned by the API, not a manually constructed URL.

### 2. Truvera REST API - server side

All API calls use dual-header authentication:

```
DOCK-API-TOKEN: <your-api-key>
Authorization: Bearer <your-api-key>
Content-Type: application/json
```

#### 2a. Issue a credential

**Step 1: Create an OpenID Issuer**

```
POST {API_URL}/openid/issuers
```

```json
{
  "claimMap": {
    "age": "age",
    "fullName": "fullName",
    "bankTenure": "bankTenure",
    "dateOfBirth": "dateOfBirth"
  },
  "credentialOptions": {
    "algorithm": "dockbbs",
    "credential": {
      "type": ["VerifiableCredential", "BankIdentity"],
      "subject": {
        "age": 30,
        "fullName": "John Doe",
        "bankTenure": 8,
        "dateOfBirth": "1994-05-15"
      },
      "issuanceDate": "2025-01-01T00:00:00Z",
      "expirationDate": "2026-01-01T00:00:00Z",
      "issuer": "did:dock:<your-issuer-did>"
    }
  }
}
```

Response: { "id": "\<issuer-id>", ... }

> **Critical:** Use algorithm: "dockbbs" for BBS+ signatures. This is required for ZK proof generation.

**Step 2: Generate an OID4VC offer**

```
POST {API_URL}/openid/credential-offers
```

```json
{ "id": "<issuer-id-from-step-1>" }
```

Response: { "url": "openid-credential-offer://...", "id": "..." }

The url is what you pass to wallet.addCredential().

#### 2b. Create a proof request

```
POST {API_URL}/proof-templates/{templateId}/request
```

```json
{ "did": "did:dock:<your-verifier-did>" }
```

Response:

```json
{
  "id": "<proof-request-id>",
  "qr": "https://creds-testnet.dock.io/proof/...",
  ...
}
```

The qr field is the URL you pass to wallet.submitPresentation().

> **Important:** The Issuer DID must be added to the proof template's "trusted issuers" list in the Truvera workspace. Otherwise, proof generation will silently fail.

#### 2c. Poll for verification result

```
GET {API_URL}/proof-requests/{proofRequestId}
```

Response:

```json
{
  "id": "...",
  "verified": true,
  "presentation": { ... },
  "status": "verified"
}
```

Poll this endpoint (e.g., every 3 seconds) until verified === true. Use exponential backoff for network resilience.

***

## Next Steps

Once you understand the above example, you should separate the wallet into a privacy-by-design user-controlled web application. The issuer and verifier should not have direct access to the key for the user's wallet. Instead, we recommend the following flow.

When a user is onboarding,

1. The user will complete identity proofing as required by existing policies,
2. Then the issuer service calls the client wallet service to provision a cloud wallet on behalf of the user,
3. That service [assists the user in defining their key](/credential-wallet/wallet-sdk/cloud-wallet#multi-key-authentication) as required for your use case (using a biometric, passkey, or other login method),
4. The wallet service then returns to the issuer the DID of the new wallet,
5. The issuer service can then call the REST API to issue credentials with the attributes that were established during identity proofing. These credentials can be issued directly into the user's wallet using the DIDComm protocol.

When a user later needs to provide those credentials,

1. The verifier service calls the REST API to create a proof request for the needed data,
2. The verifier service directs the user to the client wallet service with the proof request URL,
3. The wallet server helps the user to generate their access key using the same method as during onboarding, or a recovery method,
4. The user can then approve the sharing of the credentials to fulfill the proof request,
5. And the data is returned to the verifier.


# Biometric-bound credentials

## What are biometric-bound credentials?

Biometric is a a physical characteristic, e.g. eye, finger, face, voice, gait. When a person’s physical attribute is measured it is translated to something that can be stored - an enrollment template.

After the enrollment is complete, to match the biometric the physical attribute is measured again and translated to something that can be matched - a candidate sample. The sample is then matched with the template. The match score is compared with a threshold to return a positive or negative result.

There are different ways to store biometrics.

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><p><strong>Centralized</strong></p><p>Biometric provider stores biometric data from multiple people in a common database. Each relying party integrates with the provider, and may see biometric data.</p></td><td></td><td></td><td><a href="/files/ZOxuCisX537ZmIyxQIk5">/files/ZOxuCisX537ZmIyxQIk5</a></td></tr><tr><td><strong>Decentralized</strong></td><td>Biometric provider stores each person’s data in a different sharded vault which cannot be reconstructed without the biometric vector.</td><td></td><td><a href="/files/88LtoF40w1EfJ3IR19yJ">/files/88LtoF40w1EfJ3IR19yJ</a></td></tr><tr><td><strong>User-stored</strong></td><td>Biometric data is securely stored on the person’s device using tamper-proof credentials.</td><td></td><td><a href="/files/0aU6ddcMqAjK1lEmo2ed">/files/0aU6ddcMqAjK1lEmo2ed</a></td></tr></tbody></table>

### How user stored biometrics work

Relying parties use open standards to verify credentials issued by their trusted biometric providers. Relying parties never see biometric data.

|                                  |                                                                                                                              |
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| ![](/files/nWQaE5RrVa2PbvMxpkh3) | <p>1. Check the biometric and issue an enrollment credential containing the biometric data and a private identifier<br></p>  |
| ![](/files/9SjcwW76LTDxtQDDLxNp) | 2. Check the biometric against the enrollment credential and issue a biometric-check credential with the private identifier  |
| ![](/files/UGMs0LAOOdcAG7UHShta) | 3. Relying parties verify that a biometric-check credential is recent, trusted, and contains the expected private identifier |

### What is a biometric-bound credential?

**Wallet-bound Credential** - the credential was put into a wallet at issuance, and taken from the same wallet at verification. It is assumed that the same person is in control of the wallet at both times.

**Biometric-bound Credential** - the same person who received the credential at issuance presented the credential for verification.

We suggests 2 possible approaches on how to implement biometric-bound credentials and address these concerns.

## How to implement biometric-bound credentials?

### Samples taken by issuer and verifier approach

In this model the issuer and verifier agree on a common provider of biometrics.

Issuer requires holder to enrol in the biometric service and provide a biometric sample through the service before the issuer will issue a credential.

The issued credential contains a link to the biometric template.

At time of verification, verifier requires holder to provide a biometric sample through the same service and checks that it matches the template linked in the credential.

[Documentation how to add a biometric service plugin](/credential-wallet/wallet-sdk/biometric-plugin).

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

| Pros                                                              | Cons                                                                        |
| ----------------------------------------------------------------- | --------------------------------------------------------------------------- |
| Can use biometric hardware provided by the issuer and verifier    | Biometric service can correlate issuer, verifier, and holder \*             |
| Being outside of the holder’s control can mean it is more trusted | Every issuer and verifier needs to integrate with the biometric service\*\* |
|                                                                   |                                                                             |

*\*Some biometric services are designed to be privacy preserving*

*\*\*Biometric standards can reduce cost of integration and lock-in*

### Samples taken by identity wallet approach

In this approach issuer asks the holder to provide a proof of biometric check before issuing a primary credential.

Identity wallet detects the request, processes biometric, enrolls the holder, issues a credential and provides the credential to the issuer.

Primary credential with biometric binding is issued by the issuer.

Verifier asks for primary credential with a proof of biometric check.

Wallet detects the request, processes biometric, and provides compound proof to the verifier.

{% hint style="info" %}
Primary credential: the credential which contains the attributes of interest to the verifier in addition to the biometric binding attributes
{% endhint %}

<figure><img src="/files/5saxTOKU1FWGl5kOY8Ue" alt=""><figcaption></figcaption></figure>

#### Biometric enrollment

Holder sets up a wallet integrated with the biometric service. When a biometric binding is first required, the holder wallet enrolls the holder in the biometric service.

The biometric service issues a credential that generally contains at least the following attributes:

1. An attribute that contains the enrollment template - the reference biometric sample that is stored during enrollment to which future biometric samples are compared
2. Attributes that can be embedded in primary credentials to bind them to valid biometric verification credentials issued to the same holder

{% hint style="info" %}
Biometric data needs to be converted to a text based format so it can be embedded in JSON. The most popular method is to use "Base64" encoding.
{% endhint %}

A sufficiently privacy preserving biometric template can be embedded directly in the primary credential, avoiding the need for an enrollment credential.

The biometric enrollment and initial verification credentials may be issued using the same biometric sample to avoid an additional sample being taken from the holder.

The biometric binding attributes can usually be a smaller size than embedding the biometric template directly in a credential.

The enrollment credential contains the PII that would previously be stored in the BSP’s database.

#### Issuance

Holder requests a primary credential from the issuer. Issuer requests a proof of a recent biometric check.

The holder’s identity wallet detects that the request includes biometric binding attributes, and triggers the associated plugin that requests a biometric verification credential from the biometric service.

Biometric service requests to verify the biometric enrollment credential. Biometric service checks a new biometric sample against the template included in the enrollment credential. Biometric service issues a credential showing a valid biometric check, that contains the biometric binding attributes and a timestamp of the check.

The wallet provides the biometric verification credential to the issuer, who checks that the credential is recent.

Issuer issues the primary credential, with additional biometric binding attributes including the identity of the issuing biometric service.

#### Verification

Verifier requests a compound proof of a primary credential and a recent biometric verification credential.

The holder’s identity wallet detects that the request includes biometric binding attributes, and triggers the associated plugin that requests a biometric verification credential from the biometric service. The wallet’s biometric plugin follows the same process as was used during issuance to obtain a recent biometric verification credential.

Holder provides the biometric verification credential in a compound proof with the primary credential

Verifier checks that the biometric verification credential is from a trusted biometric service provider that was used at issuance and that the biometric binding attributes of the primary credentials matches the biometric binding attributes in the biometric verification credential.

#### Benefits

* Biometric is taken on the device, and only accessed by the biometric service provider
* Biometric service doesn’t have to store holder data, yet has assurance that the data has not been manipulated by the holder
* Issuer and verifier do not need to integrate with the biometric service
* Holder wallet can easily integrate with multiple biometric services
* Trust registry can list biometric services that should be trusted within an ecosystem
* The biometric service providers can enforce that all interactions are with a trusted wallet

### Privacy concerns and suggested solutions

**How to store the enrollment template in a privacy preserving manner?**

Identity Wallet Approach: Have the identity subject hold a tamper-proof verifiable credential issued by the biometric service provider.

Issuer-Verifier Approach: Depends on the specific biometric service used.

**How to bind a credential to a biometric template without correlation by the verifier?**

The verifier checks a Zero-Knowledge Proof (ZKP) comparing the biometric binding attributes of the primary credential with the biometric verification credential without disclosing the binding attributes.

**How to bind a credential to a biometric template without correlation by the issuer?**

Use blind signatures to not disclose the actual binding attribute.


# Caller authentication: Truvera Verified Contact

### Overview

Truvera Verified Contact reduces caller verification time up to 80% by replacing security questions with a biometric check through your existing app.

When a customer calls your support center, verification can be triggered automatically through your IVR system or manually by agents within your existing CRM. The customer receives a push notification in your company's mobile app, unlocks the app using biometrics, and sees a message asking them to confirm if they are speaking with support. They tap a button to confirm and the verification is complete, all without the customer sharing any personal information verbally.

### How it works

Truvera Verified Contact uses two components working together to authenticate callers:

**Truvera API** - Handles secure communication between your call center systems and customer mobile apps using the [DIDComm protocol](https://book.didcomm.org/) for end-to-end encryption.

**Your existing mobile app** - The Truvera Wallet SDK integrates into your company's existing mobile application to handle decryption of DIDComm messages, display authentication prompts, collect biometric confirmation, and send cryptographically signed responses.

### Implementation requirements

#### Call center system integration

Truvera Verified Contact integrates into your existing call center infrastructure rather than requiring a separate portal. Integration points include:

**IVR/ACD integration (recommended)** - Automatically trigger verification requests during call routing, allowing authentication to complete before customers reach agents.

**CRM integration** - Add a verification button to your existing agent interface for manual triggering when needed.

**Technical requirements:**

* REST API integration capability in your IVR or CRM system
* Ability to display verification status in agent interface
* Customer identifier matching between your systems and mobile app (phone number, account ID, etc.)

[View API documentation](https://docs.truvera.io/truvera-api/messaging)

#### Mobile app SDK integration

The Truvera Wallet SDK integrates into your existing customer-facing mobile application, customers do not need to download a separate app. The SDK handles secure message decryption and manages the authentication flow within your app.

**SDK capabilities:**

* Receiving and decrypting encrypted verification requests via DIDComm
* Displaying authentication prompts to customers
* Sending cryptographically signed responses

[View SDK documentation](/credential-wallet/wallet-sdk)

#### Customer onboarding

To use Truvera Verified Contact, you need to associate each customer's account with their wallet's DID (Decentralized Identifier). When you integrate the Truvera Wallet SDK into your mobile app, each instance generates a unique DID that can be retrieved and stored in your customer database.

**Basic setup flow:**

1. Customer installs or updates your mobile app with the integrated Truvera Wallet SDK
2. Your app retrieves the wallet's DID from the SDK
3. Your systems associate this DID with the customer's account record (linked by phone number, account ID, or other identifier)
4. Customer can now authenticate via push notification when calling support

Once you have the customer's DID, your call center systems can send encrypted DIDComm messages directly to their wallet without any additional credentials.

**Optional: Using verifiable credentials**

While not required for basic authentication, you may choose to issue verifiable credentials to customer wallets for enhanced functionality:

* Attribute-based verification (e.g., account tier, geographic location)
* Selective disclosure capabilities
* Additional cryptographic proof of account ownership

[View credential issuance documentation](/truvera-api/credentials)

### Key benefits

**Operational efficiency** - Reduces authentication time by up to 80%. With IVR integration, authentication completes during call routing, allowing agents to begin helping customers immediately upon connection.

**Cost reduction** - Eliminates per-message costs associated with SMS OTP solutions. Saves significant agent time costs from faster authentication.

**Enhanced security** - More resilient than knowledge-based authentication or OTPs, protecting against data breaches, SIM swaps, and phishing attacks.

**Privacy protection** - Eliminates the need for agents to access or hear sensitive personal information, reducing compliance liability and improving customer trust.

**Seamless customer experience** - Works within your existing mobile app that customers already use and trust—no separate download or registration required.

**Flexible implementation** - Integrates with existing call center infrastructure, supports both automated (IVR) and manual (agent-triggered) flows, enables step-up authentication for sensitive operations, and allows smooth re-verification when transferring between teams.


# Truvera Workspace


# Create an organization profile (DID)

In Truvera, an organization profile describes an entity that is interacting with credential holders. The core of an organization profile is a DID that maps to the keys used to issue credentials and prove participation in an ecosystem. The profile also contains a name, logo, and description which helps credential holders and ecosystem participants to recognize the organization.

### What is a DID? <a href="#h_95e2ff9378" id="h_95e2ff9378"></a>

Decentralized identifiers (DIDs) are unique identifiers that are associated with a digital identity. DIDs are made up of a string of letters and numbers that can be stored on the blockchain and can be used to authenticate that identity by referencing public keys. Issuers use DIDs to publish the keys used to verify credentials, and verifiers use DIDs to prove ecosystem membership.

### Create an organization profile (DID) <a href="#h_95e2ff9378" id="h_95e2ff9378"></a>

To create your organization profiles (DIDs) , select Organization Profiles on the left side menu and then click Create Organization Profile.

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

Fill in the Public Name, add the Logo and Public Description you can leave the DID Type to the default setting “cheqd” (learn more about different [DID Types](#choosing-a-did-type)). Then select **Create Organization Profile**.

<div align="left"><figure><img src="/files/BExios1fGVqHj9RYKHsJ" alt="" width="188"><figcaption></figcaption></figure></div>

{% hint style="info" %}
The Logo image should not exeed 1MB in size. Accepted formats: 'jpeg', 'jpg', 'png', 'bmp'. Logo image can be square or round it will be optimized on display.
{% endhint %}

All of your Organization profiles (DIDs) will be listed on this page.

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

***

### Choosing a DID type

Many different types of DIDs exist today, they all support the same basic functionality, but they differ in how a DID is created or where and how the DID document is stored and retrieved.These different types of DIDs are known as DID methods. The second part of the DID identifier format—between the first and second colons—is called the DID method name.

Truvera supports 2 types of DID methods did:key and did:cheqd.

<table><thead><tr><th width="153">Method</th><th width="184">Storage</th><th>Keys</th></tr></thead><tbody><tr><td>did:key</td><td>Stored on the user’s device</td><td>Only one key pair is attached to this DID type, if your keys get exposed you will need to change the DID and all the credentials associated to it</td></tr><tr><td>did:cheqd</td><td>Stored on the cheqd blockchain</td><td>Multiple key pairs can be attached to this DID type, keys can be rotated as needed</td></tr></tbody></table>

***

### Edit an organization profile (DID) <a href="#h_c1052e8bf2" id="h_c1052e8bf2"></a>

Click on Organization Profiles in the menu, click on the three dots of the DID you want to edit, and select **Update DID**.

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

Update the details and select **Update DID**.

### Export an organization profile (DID) <a href="#h_157926b249" id="h_157926b249"></a>

Click on the three dots of the DID you want to export, and select Export DID.

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

You can export your DID to a wallet or another platform. Create a password to encrypt the file and select Export.

![](https://downloads.intercomcdn.com/i/o/797658873/66234318d10e677cec479706/Screenshot+2023-08-01+at+14.37.22.png)

The exported profile will be stored as an [Encrypted Data Vault](https://identity.foundation/edv-spec/).

### Delete an organization profile (DID) <a href="#h_88118e48bc" id="h_88118e48bc"></a>

Click on the three dots of the DID you want to delete, and select Delete DID.

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

{% hint style="warning" %}
Deleting your DID will make it unresolvable. This means that any credentials you issued with it will become invalid and it cannot be looked up on the blockchain anymore. Your associated key pair will also be deleted. This action cannot be undone.
{% endhint %}


# Issue verifiable credentials

## Issuing credentials <a href="#h_c3a1aee140" id="h_c3a1aee140"></a>

In the Credentials menu, click Issue credentials.

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

### Select a credential schema <a href="#h_e6f35266ad" id="h_e6f35266ad"></a>

Select a pre-made credential schema by clicking on it's name or [Create your own schema](/truvera-workspace/create-a-schema). You can click on Preview to see what attributes are included in the template.

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

### Select a design <a href="#h_662fe7eaa5" id="h_662fe7eaa5"></a>

Select a design or [create a new one](/truvera-workspace/create-a-design) for your credentials. Alternatively, you can proceed without a design.

### Add recipients <a href="#h_5fb66344c4" id="h_5fb66344c4"></a>

If you have many credentials to issue, you can issue them in bulk. To do this, select **Import Spreadsheet.**

<figure><img src="https://downloads.intercomcdn.com/i/o/797670167/d0dbab0c2d32c4b8fb42882a/Screenshot+2023-08-01+at+14.51.00.png" alt="" width="375"><figcaption></figcaption></figure>

Download the sample CSV template and fill in the details needed for your credential template. Upload the completed .csv file back to Truvera. [Read how to correctly format the Spreadsheet for CSV upload.](#formatting-the-csv-file-for-recipient-upload)

<figure><img src="https://downloads.intercomcdn.com/i/o/797695179/a28c99740299645f876ce8be/6356f7181e5260685afe7bd9_9-Download+CSV.png" alt=""><figcaption></figcaption></figure>

If you want to add recipients one by one, select Add Manually.

You can distribute your credentials by email or directly to their wallet through their DID.

To send the credential by email, fill in their email in the **Recipient Email** field.

![](https://downloads.intercomcdn.com/i/o/797721246/2840f531c2020bf9df3a117c/64744417375359ce3af2c7ea_1-email+distribution.png)

To send the credential directly to the holders wallet fill in their DID in the Subject ID (Recipient ID) field.

Fill in all other attributes that need to be included in the credential *e.g. Subject name, Credential Title etc.*

### Formatting the CSV file for recipient upload

You can download the CSV sample file to use as a base for you recipient data upload. The sample file has only 3 collumns with the *name*, *did* and *date* attributes.

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

You will need to add columns and remove the ones you do not have in your credential schema.

When uploading a file you will be able to select a charset specification. UTF-8 will bet the choice for most users. If your dataset contains special characters you might need to choose a different charset, based on the one used to encode your data file.

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

{% hint style="info" %}
If you do not know the holders dids you do not have to use it for the import, you can add emails, for the email distribution or distribute credentials manually.
{% endhint %}

You will be asked to match the columns on the csv file to the credential fields. If there are any required fields on the credential schema they must be filled in, otherwise the import will not be successful.

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

### Expire credential <a href="#h_c9b588481e" id="h_c9b588481e"></a>

If you need the credential to expire, turn on the expiration toggle and enter the expiration date.

![](https://downloads.intercomcdn.com/i/o/797671954/0a79de9246c232395c2825c1/Screenshot+2023-08-01+at+14.52.52.png)

### Choose credential options <a href="#h_e26a4957df" id="h_e26a4957df"></a>

After you have added your credential recipients you will be able to select the credential settings. You have the options to:

**Persist credential:** This option will encrypt the credential by providing a password to access it and store it on Truvera's servers. The credential can be accessed and verified by a URL or QR Code. The recipient can scan the QR Code to import the credential into a wallet app. The credential can be deleted from Truvera's cloud whenever you decide.

{% hint style="info" %}
Persisting is a good option for issuers if they want to securely store the credentials as a backup. It encrypts the credentials using Libsodium crypto secretbox Salsa20/Poly1305 algorithm and stores them on our servers that are located in the US and are powered by Amazon Web Services (AWS). Because the credential information is encrypted, Truvera can’t access the information to ensure data privacy and security. ​
{% endhint %}

**Credential revocation:** By selecting Enable Revocation, you leave an option for the credential to be revoked to invalid state at any time. If you leave this option unchecked, the credential can never be revoked and will always be verifiable.

Select which [Organization Profile (DID)](/truvera-workspace/create-an-organization-profile-did) you want to use to issue the credentials.

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

### Choose credential variant <a href="#h_e26a4957df" id="h_e26a4957df"></a>

Truvera offers a choice of 3 different credential variants that have distinct features and are best fit for different use cases.

* **Standard Signature (ed25519)** - a more simple credential variant that is the best option for interoperability with other verifiable credential services.
* **Anonymous (dockbbs23)** - uses BBS+ to enable selective disclosure and zero knowledge proofs. Best for use cases where user data privacy is a top priority.
* **EUDI (SD-JWT-VC) -** follows European identity standards for compliance and interoperability.

\
There is a 4th credential variant **Ecosystem-bound (BBDT16)** that is used for [Ecosystem bound credentials.](/truvera-workspace/monetizing-credentials) It will get automatically selected when a price is assigned to a schema in an ecosystem.

<figure><img src="/files/OCYzriPK6hfzk64Z5Okv" alt="" width="375"><figcaption></figcaption></figure>

### Distribute credentials <a href="#h_22a510abcd" id="h_22a510abcd"></a>

If you have entered the holders DIDs to Subject ID the holder will receive the credential directly in their wallet without any additional communication needed.

![](https://downloads.intercomcdn.com/i/o/797749786/65a19e3bd9bdb27970ce16ea/e4aebe54-e4c5-46b4-b30e-1b9083b74a87.jpeg)

If you have entered the email address, you will have an option to write a message and preview the email that is going to be sent to the receiver of the credential.

<figure><img src="https://downloads.intercomcdn.com/i/o/797730898/839d62e93c6bb388f29eb493/Screenshot+2023-08-01+at+15.57.06.png" alt="" width="375"><figcaption></figcaption></figure>

If you do not have or want to use DIDs for the credential distribution you will need to enter an email of the recipient or persist the credential.

<figure><img src="/files/Macg9BphKX7MTannASCV" alt="" width="375"><figcaption></figcaption></figure>


# Filtering, downloading and deleting credentials

### Filtering credentials <a href="#h_5ef77bc181" id="h_5ef77bc181"></a>

For easier management of the credentials issuers can filter the credential view table by Credential ID, Issue date (use YYYY-MM-DD format), Type (schema used) or subject reference.

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

### Downloading credentials <a href="#h_5ef77bc181" id="h_5ef77bc181"></a>

If you need to download an already issued credential you can do it by selecting credential you want to download and clicking Download.

{% hint style="warning" %}
For a credential to be downloadable you need to select [Persist Credential](https://help.dock.io/en/articles/8200914-issue-verifiable-credentials#h_e26a4957df) when issuing credentials. If the persisting was not selected upon creation the credential an encrypted copy is not stored on our servers and therefore can not be downloaded.
{% endhint %}

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

### Deleting credentials

If you don’t want to see a certain Verifiable Credentials in your account, select the ones you want to remove and click Delete. This does not delete the credentials themselves, it just removes them from the account view.

If the credential is not revocable, then the recipients will still have the credential in their wallet and be able to present it to verifiers because they have full ownership of it. Only credential holders will be able to delete the credential if they chose to.

If you wish to revoke the credential before deleting it see this [article.](/truvera-workspace/revoking-credentials)

<figure><img src="https://downloads.intercomcdn.com/i/o/797888254/e8fbbc3e7be024a587d7d93d/63e69f45b5c87181fe442538_14-digital+credential+platform+delete+credential+from+account+view.jpg" alt=""><figcaption></figcaption></figure>


# Verify credentials

## Verification process <a href="#h_d119e38335" id="h_d119e38335"></a>

In a typical verification process, there are three main parties:

1. **Issuer:** Party that creates and issues a Verifiable Credential to a holder (individual or organization)
2. **Holder:** Person or organization that holds the credential (e.g. degree, professional certificate, or identity document)
3. **Verifier:** Party that checks that the credential is valid and authentic

<figure><img src="https://downloads.intercomcdn.com/i/o/801931889/c9976b09a48fe6e88920e78a/631f7526f09bcf3b4b2e6209_3-certificate+fraud-issuer%2C+holder%2C+verifier.jpeg" alt="" width="563"><figcaption></figcaption></figure>

## Steps for the verifier <a href="#h_4638f9252a" id="h_4638f9252a"></a>

Click on Verification in the left menu and select Create verification template or choose a premade Indentify Verification or Drivers License Verification template.

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

Add the **Template Title** and **Template Purpose**, which the holder will be able to see. Optionally, you can choose a **Verifier DID** which will be shown to the holder so that they know who is verifying their credential.

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

When creating a template you can choose a specific credential schema and attributes included in that schema.

If the **Optional** toggle is selected the holder can decide if they want to share that information or not. If the toggle is turned off the holder will have to share that information or the verification will fail.

{% hint style="info" %}
The information needs to present in the credential if the attribute is not marked as optional. E.g. if Expiration Date is not marked as Optional it will have to be present in a credential and any credential without an expiry date will fail the verification.
{% endhint %}

You can combine verifying multiple credentials in one verification template by adding a credential and selecting schema and attributes.

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

{% hint style="info" %}
The list will have only the attributes that are included in the credential schemas. If you want to include an attribute that is not on the schemas owned by that account it can be typed in instead of the listed attributes.
{% endhint %}

When verifying Zero Knowledge Proof credentials, you can use range proof verification conditions, that will verify the credential without disclosing the actual value of an attribute. For example, if you want to verify that the credential holder is older than 18 you can choose attribute Age and condition is greater than 18.

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

If the verification template contains a paid schema a notification on the bottom will appear.

{% hint style="warning" %}
When verifying ecosystem bound credentials with paid schemas, the issuance date can not be revealed. In order to verify credential issuance date use a date range in the verification temple.
{% endhint %}

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

Last step for a verification request is to click Request, which will generate a QR code. Every time a new request is made, it generates a new QR code.

<figure><img src="/files/8w4bw9QsDmcUcgh8NnDW" alt=""><figcaption></figcaption></figure>

## Steps for the holder <a href="#h_551a4bc680" id="h_551a4bc680"></a>

First step for the holder is to **Scan** the QR code with their wallet and select the credential(s) that contain the information the verifier is requesting.

<div align="left"><figure><img src="/files/Xk400Rr53ZJpuwjoN5Oz" alt="" width="203"><figcaption></figcaption></figure></div>

{% hint style="info" %}
If the credentials were issued with Zero Knowledge Proof signatures the holder will be able to choose which details on the credentials to share with the verifier.
{% endhint %}

If the credentials are valid and the verification is successful, this is what the holder will see a **Verification Successful** message, if the credential could not be verified a **Verification Failed** message will appear.

## Verification history

To see a log of all your verification requests, go to Verification and click on **History**.

<figure><img src="/files/7p4LXffUlmXJ47fJW0d5" alt=""><figcaption></figcaption></figure>

When the credentials are valid it will show up as “Verified” under Status. The verifier won’t get a notification if the credential is invalid because Dock’s tools won’t let the holder submit invalid credentials.

<div align="left"><figure><img src="/files/iPAcZBn0FNP2bwNTrw5l" alt="" width="375"><figcaption></figcaption></figure></div>

{% hint style="warning" %}
Verification request templates can only be created in Truvera Workspace, not the wallet. These templates can be important into the wallet from Truvera Workspace for wallet-to-wallet verification.
{% endhint %}

In order to reduce the data stored on the system we recommend deleting the verification template data after it is not needed anymore. Read more about [data retention policies](/truvera-workspace/team-management/data-retention-policies).

## Wallet-to-wallet verification <a href="#h_9833d67c15" id="h_9833d67c15"></a>

After creating the verification request in Truvera Workspace it can be imported in to the wallet for a wallet-to-wallet verification.

Go to **Settings** and choose **Credential Verifier**.

<div align="left"><figure><img src="https://downloads.intercomcdn.com/i/o/801963474/f0e42a69cd04be5cb000afa0/Screenshot_20230807_140939_DockApp.jpg" alt="" width="188"><figcaption></figcaption></figure></div>

Click Import via QR code and scan the verification template QR code generated in Truvera Workspace. [See how to create a verification template here.](#h_4638f9252a)

After the Verification template is imported you can share it with the holder to present and verify their credential.

![](https://downloads.intercomcdn.com/i/o/801966471/8b2b8552b1276fc19e7bc89d/Screenshot_20230807_141402_DockApp.jpg)

Holder will scan this QR code with their Truvera Wallet and follow the [verification steps for the holder](#h_551a4bc680).


# Create a schema

### Set up a credential schema <a href="#h_0bf8dff5dc" id="h_0bf8dff5dc"></a>

Select **Schemas** and click **Create schema**

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

Add a name for the schema and a description.

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

In Credential attributes, add the type of data you want to appear on the schema. You can do this in two ways:

a) By manually setting up the information you want to appear

b) Importing an existing credential template from another source

<figure><img src="https://downloads.intercomcdn.com/i/o/800461315/65abc4192bd133c968fbfc43/6431f2898c76935202fe74db_3-custom+verifiable+credential+attributes.jpeg" alt="" width="375"><figcaption></figcaption></figure>

### Manually add credential attributes <a href="#h_faa71c7067" id="h_faa71c7067"></a>

Click **Create manually**.

![](https://downloads.intercomcdn.com/i/o/800464123/6f1b15f7e4f0ca019984f74b/6431f2bf08ce44742be1746a_4-custom+verifiable+credential+create+manually.png)

You can choose what format the field will appear in and which fields are required or optional.

<figure><img src="https://downloads.intercomcdn.com/i/o/800465718/1df8901096f862edc15e7992/6431f40b5544d794d95d68d2_6-custom+verifiable+credential+drop+down.png" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
You don’t need to add an Issue Date and Expiry Date field because these fields will automatically appear on all templates.
{% endhint %}

Once you’ve added all the fields, click **Publish**. All credential schemas will be listed on this page when you select Schemas from the menu.

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

You can also see your new credential templates added to the pre-built templates. So whenever you issue a credential, you will be able to choose a template from this list.

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

Click the Actions menu and select **Preview** to see the attributes that are included in the credential schema or Duplicate to edit the schema.

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

The **Issue Date** and **Expiration Date** are default attributes that will appear on every template if you create the template manually.

![](/files/RGAN6B9na87kGRVgCq95)

### Add credential attributes by importing an existing credential schema <a href="#h_b163952b0c" id="h_b163952b0c"></a>

You can import an existing credential schema into Truvera.

{% hint style="success" %}
This feature is very useful when needing to move schemas from test mode into production.
{% endhint %}

Paste the schema URL or JSON in the Schema Import pop up and select Import Schema

![](/files/lzSQvw5AqqJLT8HtkTtp)

Double check to make sure that the correct data format is selected for each data field. Add or remove the fields as necessary and select Publish once ready.

### Edit a credential schema <a href="#h_4521818d05" id="h_4521818d05"></a>

Go to the schema you want to edit, click on the three dots, and select Duplicate.

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

Update the schema Name so you can tell the difference between this updated version and the original one. Once you’ve made all of your edits, go to the top of the page and select Publish.

### View a credential schema <a href="#h_7b90f5840a" id="h_7b90f5840a"></a>

To see the attributes included in a particular schema your can click on the three dots of the credential you want to view, and click **View schema**.

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

### Delete a credential schema <a href="#h_b89d37d495" id="h_b89d37d495"></a>

Go to Schemas, click on the three dots of the schema you want to delete, and click **Delete schema**.

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


# Create a design

## Create a new design <a href="#h_314866d147" id="h_314866d147"></a>

Select Designs and click Create Design

<figure><img src="https://downloads.intercomcdn.com/i/o/802003056/9cf967533170a1b87f811972/63e6a82e324b027e5054ecce_1-credential+certificate+template+create+design.jpg" alt=""><figcaption></figcaption></figure>

You can choose a pre-made template or you can import an existing PDF design. Click Import PDF Credential, and select the PDF file.

<figure><img src="https://downloads.intercomcdn.com/i/o/802005315/04ae53917dc3e669ccc0d632/64558e0ba17249dda9bf8ed3_4-Import+credential+PDF.jpeg" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Ensure your PDF credential template is:

* A max of 2 MB
* A4 size: 21.0 cm wide x 29.7cm high (portrait) and 29.7 cm wide and 21.0 cm high (landscape)
* If you’re exporting from Canva, be sure to flatten PDF when exporting the template in PDF format
  {% endhint %}

You can also work on a blank template and add the elements and attributes on a blank page in the designer.

<figure><img src="https://downloads.intercomcdn.com/i/o/802008644/688fbef383145393ac06c7cb/Screenshot+2023-08-07+at+15.09.10.png" alt=""><figcaption></figcaption></figure>

## Add elements <a href="#h_7134d4b8e1" id="h_7134d4b8e1"></a>

You can add images, QR Code, Text fields and HTML Blocks to customise your credential design.

Select **Elements** and choose the elements you need. Once they are placed on the design template drag\&drop them in the desired location.

<div align="left"><figure><img src="/files/f1UbB3y2JBFMtJF1xuRO" alt="" width="165"><figcaption></figcaption></figure></div>

## Add certificate attributes <a href="#h_29f46e8321" id="h_29f46e8321"></a>

You can choose which certificate attributes you want to appear on your template. The actual attribute details will be filled in on the issued credentials.

To add specific fields on your template, select Attributes in the menu then choose which details you would like to appear.

{% hint style="info" %}
Subject refers to the recipient or item that the credential is being issued to.
{% endhint %}

<figure><img src="https://downloads.intercomcdn.com/i/o/802018834/43b0570ceff840b6068c0841/Screenshot+2023-08-07+at+15.20.49.png" alt=""><figcaption></figcaption></figure>

If you want your organization’s logo (Issuer Logo) and description (Issuer Description) to appear on your credential, you have to fill out those details in your [Organization Profile (DIDs).](/truvera-workspace/create-an-organization-profile-did)

## Other settings <a href="#h_0097b6e872" id="h_0097b6e872"></a>

You can use your brand color for the design background. Chose it by changing the background colour in **Setup.**

You can also add a custom background image. To add a background image for your design go to Setup and click **Add Background Image.**

![](https://downloads.intercomcdn.com/i/o/802013789/e81df52148283faac0becc4c/63570d9f5432fa87e8a12f21_5-Add+background+image.png)


# Team management

The Truvera Workspace and API allow you to invite team members to collaborate on the credential issuance and management process.

The new Team Management feature enables you to:

* Invite a team member
* Remove a team member
* Change team roles

Here is an overview of what each team member will be able to do with the Team Management feature:

<figure><img src="https://dock-bc028fad1050.intercom-attachments-7.com/i/o/836720231/f2d0c51c849d7e2b9d8c7d47/gpr84TW2SHYeOhYczZAfaAp2quJ9T6v_xTA09wnFM-sd2lTHUk611iY-Y0hXvmXgqI5Q0cAFubfjJEjLPJgNoy-SLvj9EbQTRAFV12XmgOKFyeWSThDhtZz3c8rOqZJCr2WI_BOaIKrfctUpDVq9WQ" alt=""><figcaption></figcaption></figure>


# Inviting a team member

To invite a new member to your team click on your account picture on the top right corner and select Team Settings.

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

Click Invite team members.

<figure><img src="https://downloads.intercomcdn.com/i/o/817002994/bf3407a85b334997c690be86/Screenshot+2023-08-28+at+14.22.28.png" alt=""><figcaption></figcaption></figure>

Add the email addresses of team members and click Send invites.

![](https://downloads.intercomcdn.com/i/o/817003204/1293f9ad0d30975de4cafccf/Screenshot+2023-08-28+at+14.23.14.png)

The invites will be listed below the existing team members. You can resend the invitation if needed (once a day) or cancel invitation.

<figure><img src="https://downloads.intercomcdn.com/i/o/817006068/e5fd2d8d2dc410977220d338/Screenshot+2023-08-28+at+14.28.06.png" alt=""><figcaption></figcaption></figure>


# Removing a team member

To remove a team member you need click on Actions and select Remove from team.

<figure><img src="https://downloads.intercomcdn.com/i/o/817022051/3cbfae88705f6086212a4574/Screenshot+2023-08-28+at+14.49.45.png" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
Only a team owner and administrators can remove a team member. A member cannot remove themselves. Learn more about [roles](/truvera-workspace/team-management/changing-team-member-roles).
{% endhint %}


# Changing team member roles

To change the role of a team member click on Actions and choose Administrator or Member.

{% hint style="warning" %}
There can only be one team owner, this role will belong to the creator of the team.
{% endhint %}

<figure><img src="https://downloads.intercomcdn.com/i/o/817049655/4645fa8c71a04038eccf2f01/Screenshot+2023-08-28+at+15.26.35.png" alt=""><figcaption></figcaption></figure>

Roles have different access and rights within the system.

| Feature Access                    | Team owner | Administrator | Member |
| --------------------------------- | ---------- | ------------- | ------ |
| Issue, revoke, manage credentials | ✅          | ✅             | ✅      |
| Create Designs                    | ✅          | ✅             | ✅      |
| Create Issuer Profiles            | ✅          | ✅             | ✅      |
| Create Verification Templates     | ✅          | ✅             | ✅      |
| Remove team members               | ✅          | ✅             | ❌      |
| Invite team members               | ✅          | ✅             | ❌      |
| Manage subscription & billing     | ✅          | ❌             | ❌      |


# Data retention policies

Every team can customize their data retention policies based on specific requirements. Truvera promotes user privacy and data management best practices by minimizing stored data and empowering customers with flexible retention controls. You can now configure:

* **Verification Data Retention Policy**: Credential presentation data from completed verification requests will be automatically deleted after the selected time. Default is 72 hours, with a 1 hour minimum retention time.
* **Verification Requests Retention Policy**: Verification request data (except for verification ID) will be automatically deleted after the selected time. Default is 72 hours, with a 1 hour minimum retention time.
* **Credential Offers Retention Policy**: Unclaimed credential offers will be automatically deleted after the selected time. Default is 72 hours, with a 1 hour minimum retention time.

{% hint style="warning" %}
This setting does not apply to credential offers generated via the OID4VC Issuer API with `singleUse` set to `false`. These offers persist until manually deleted.
{% endhint %}

* **Credentials Retention Policy**: All except persisted credentials will be automatically deleted after the selected time. Default is infinite, with a 1 hour minimum retention time.

These granular settings give you complete control over your data lifecycle while maintaining compliance with privacy regulations.

<figure><img src="/files/0TmeM0SzWqfhV92DrGgR" alt=""><figcaption></figcaption></figure>

There is an option to store subject reference ID, that shows up on the credential view table and can be useful for filtering the credentials. The storing of it is optional as it may contain PII and is not suitable for all use cases.

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


# Sub-accounts

Sub-accounts allow Truvera's customers to segregate their data within the Truvera platform based on their own customers. Each sub-account can have its own keys, organization profiles, credential designs and verification templates conveniently organized to help with tracking and auditing of the activity performed by each.

In order to easier manage sub-account assets [Ecosystem Tools](/truvera-api/ecosystem-tools) can be used.

Sub-accounts can be created and managed in the Truvera Workspace. Sub-accounts menu is located in the Team settings.

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

You can create new sub-accounts, edit and delete them from this menu. For any other operation related to the sub-account (creating a DID, issuing credential etc.) you will need to take over that sub-account and do the actions in the account. You can take over the subaccount and use it by clicking on it a message will be displayed that the account is being changed and you will see a new account on the profile menu on the top of the screen.

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

To come back to the main account you need to click on the profile menu and select Back to main account.

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


# Revoking credentials

If you need to make a credential invalid you can revoke it.

{% hint style="warning" %}
To make a credential revocable, you need to select [Credential Revocation](/truvera-workspace/issue-verifiable-credentials#h_e26a4957df) when issuing credentials. If the revocation was not selected upon creation the credential can never be revoked and will always be verifiable.
{% endhint %}

Select Credentials, the credential(s) you want to revoke to make it invalid, and select Revoke. You can revoke one credential at a time.

<figure><img src="https://downloads.intercomcdn.com/i/o/797855675/0beb7df27ea02f5c38ec781b/63e6a17f880d265095ff0d9e_digital+credential+platform+(1).jpeg" alt=""><figcaption></figcaption></figure>


# Ecosystem Tools

Verifiable credentials have an advantage over physical documents, because they cannot be forged. However, there is still a fraud risk if a credential is issued by someone that has no authority to do so.

How can a verifier be sure that the credential came from an authorized issuer? And vice-versa, how can a credential holder know which verifiers are trustworthy and that it is okay to share their credentials with them? Ecosystem Tools is a solution to answer this problem.

## What is an ecosystem?

\
Ecosystem is a network of trusted digital identity issuers and verifiers. It uses a trust registry an on-chain list that contains information on who is authorized and trusted to issue or verify credentials in a particular ecosystem and which credential schemas they can issue and verify.

Ecosystems are governed by trust frameworks, a set of operating rules that participants of the ecosystem must follow.

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

## Why use Ecosystem Tools?

A trust ecosystem helps organizations to simplify everyday interactions and have confidence to allow other organizations or people to interact and share fraud-proof and digitally verifiable data.

Governing Authority could register as an Ecosystem Admin in Truvera Workspace where they can establish a Trusted Brand, communicate rules for participation in a Governance Framework, and administer the ecosystem.

By having an on-chain trust registry, credential verifiers do not need to manage a list of valid issuers and holders know which verifiers they can trust to share their credentials with. They only need to trust one Ecosystem administrator.

{% hint style="info" %}
Ecosystem Tools is an add-on feature. If you want it enabled for your account please contact <support@truvera.io>
{% endhint %}


# Ecosystem set up

### Create an ecosystem

You can create an Ecosystem through the left side menu by clicking **Ecosystem -> Create Ecosystem** button.

When creating an ecosystem an on-chain trust registry is created on the blockchain, a list of relationships between issuers and verifiers. It simplifies the process of identifying which issuers and verifiers are trustworthy within a particular ecosystem.

{% hint style="info" %}
Ecosystem Tools is an add-on feature. If you do not see it in your menu bar and want it enabled for your account please contact <support@truvera.io>
{% endhint %}

First steps in creating your ecosystem is defining your brand. Ecosystem branding is important, it will be present on the credentials issued by the participants and verification templates for the verifiers. Having a clearly defined brand makes it easier for ecosystem participants to trust the ecosystem and have a unified experience from credential issuance, to storage and verification.

<figure><img src="/files/cDpslsLkpYkwVdBOj6SL" alt="" width="375"><figcaption></figcaption></figure>

You will need to set the Ecosystem **Name**, **Description,** add an **Ecosystem URL**, a valid URL that links to a page outlining the advantages and key details of joining your ecosystem.

**Ecosystem Administrator Profile DID** will allow you to choose from an existing or add a new DID that will be the administrator of the ecosystem.

Next step will allow you to set your Governance Framework document, that is used to communicate the rules and guidelines of the ecosystem to every stakeholder, ensuring clarity and consistency, which helps align all stakeholders on the processes surrounding issuance and verification.

<figure><img src="/files/HJ9Rf0ptf1t0JdMyU9Sm" alt="" width="375"><figcaption></figcaption></figure>

### Invite a participant

After the ecosystem is set up you can start inviting participants. Ecosystem participants can be Issuers, Verifiers or both depending on their role in your ecosystem. You will be able to assign credential schemas based on the role of the participant.

Ecosystem participants can have and manage their own Truvera accounts, but we also enable our customers to create ecosystems where the participant accounts are managed and paid for by them. Using [Sub-accounts](/truvera-api/sub-accounts) allows creation of additional Truvera accounts and inviting them to participate in the ecosystem using the API.

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

After clicking **Invite participants** you will be able to select a credential schema and a role of the participant.

<figure><img src="/files/MyZbXEqE5nb1U9XPt88Y" alt="" width="375"><figcaption></figcaption></figure>

Ecosystem participants will need to have an account with Truvera to join the ecosystem. When they are logged in to their Truvera Workspace account and click on the link provided by the ecosystem administrator, they will be immediately prompted to **Join the ecosystem** and select an organization profile that will be used to participate in the ecosystem.

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

Ecosystem Administrator and participants will see the list of Issuers and Verifiers in the table.

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

Ecosystem administrator will be able to **Suspend**, **Remove** or **Edit** the existing Ecosystem participants. They can also change the role of the participant and assign schemas.

### Assign credential schemas

To assign a credential schema to participants you will need to first [create the schemas](/truvera-workspace/create-a-schema). To assign the schema you will click the **Add schema** button.

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

You will be able to select from your schemas from a dropdown or enter schema URL and assign it to ecosystem participants.

<figure><img src="/files/g8jFn9UKOxN1aqqtYbCQ" alt="" width="375"><figcaption></figcaption></figure>

{% hint style="info" %}
You can choose to add a verification price for your schema, which will set a fee for each verification of credential using the selected schema. [Learn more about verification prices](/truvera-workspace/monetizing-credentials)
{% endhint %}

Credential schemas can have Restricted or Public verifiability. If the schema is assigned to at least one participant that can verify the schema, the verification will restricted to only those participants. If there are no assigned verifiers the schema will be publicly verifiable.

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

Assigned schemas will be immediately available to participants and once credentials are issued using a schema assigned to an ecosystem, the ecosystem branding will be visible throughout the entire credential user journey.

Ecosystem branding will be visible in the wallet once a credential is issued by an ecosystem participant.

![](/files/YysqrvC7S6eJv1K1Ityw)

### Add verification templates

Ecosystem administrator will be able to add verification templates that will be available for all ecosystem participants.

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


# Ecosystem example

<figure><img src="/files/8UCYzd0iXuCmNOv8SdLs" alt=""><figcaption></figcaption></figure>

**Clarity Partners** ecosystem is a privacy conscious ecosystem of partners using Identity Clarity KYC products.

EquiNET credit bureau as the ecosystem administrator is responsible for specifying governance rules, providing branding and maintaining the [ecosystem website](https://bank-demo.dock.io/partners).

Administrator invites ecosystem participants, in this example:

* Forsur - biometric credentials provider
* Quotient - credit union
* EquiNET - credit bureau
* UrbanScape - apartment company offering upscale rentals

{% hint style="info" %}
Ecosystem administrator can be a participant in their own ecosystem.
{% endhint %}

Administrator is also responsible for assigning the credential schemas and verification templates that will be used by the participants.

Clarity partners ecosystem has 4 credential schemas:

* ForSur - Biometric Check, that can be used by ForSur, Quotient and UrbanScape.
* ForSur - Biometric Enrollment, that can be used by ForSur.
* Quotient - Bank Identity W/ Biometrics, that can be used by Quotient and UrbanScape.
* EquiNet - Credit Score, that can be used by EquiNet and UrbanScape.

Clarity partners ecosystem has 2 verfication templates, that can be used by all participants.

* Quotient Loan Verification - Bank Identity, Biometrics, and Credit Score
* UrbanScape Credit Score Verification- Credit Score


# Monetizing credentials

### What is credential monetization?

Truvera has a unique feature that allows setting a verification fee on credentials and introduces a new revenue stream that ecosystem administrator can leverage to motivate issuers to join their ecosystem. It converts credential issuance from expense to profit and is an important step in accelerating adoption of verifiable credentials by creating value for participating parties.

### How does it work?

The technology is based on KVAC (Keyed Verification Anonymous Credential) to lock the credential making sure, that it can only be verified that a payment has been made.

Ecosystem administrator sets a price for each schema and assigns it to participating issuers and verifiers.

When a verifier is trying to verify a credential, they will be notified that this verification requires a fee. During the verification process, the issuer is asked to provide an additional secret for the specific credential schema in order to unlock it. This is all done automatically within seconds during the verification process.

{% hint style="info" %}
Holder privacy is a key consideration in our design. The verifier doesn't share any holder-identifying data with the issuer when asking for verification. Only 2 random looking data items are shared with the issuer and issuer verifies a relationship between them e.g. verifier shares a pair of items (A, B) with the issuer and asks to check whether A equals B \* issuer-secret-key. Here A is the MAC from holder's credential but randomized so issuer can't identify it.
{% endhint %}

The Issuer sees that a credential based on a specific schema was shared with a specific Verifier, but learns nothing about the Holder. Preserving this requirement has forced us to innovate interesting solutions to use cases that previously required the Issuer to identify the Holder. With any technology, there are risks. The Issuer needs to use the same schema for enough credentials for Holders to benefit from herd privacy.

Truvera will track the verifications and provide detailed billing reports to the ecosystem administrators. A small percentage fee will be charged for each verification transaction based on the price set on the schema.


# Setting up monetizable credentials

This is a detailed guide on how to monetize your credentials using Truvera.

### Creating an ecosystem

Verification fees can be set by Ecosystem administrators to the participants of an ecosystem. Verifiers will only be able to access a credential if they are in the same ecosystem with the Issuer. See the step by step guide on [Ecosystem set up](/truvera-workspace/ecosystem-tools/ecosystem-set-up).

{% hint style="info" %}
Ecosystem administrators should only invite verifiers to an ecosystem with paid credentials if they have a billing relationship in place.
{% endhint %}

### Assigning schemas and adding verification prices

Verification prices are added to the schemas when assigning them to participants in the ecosystem.

First a schema needs to be [created](/truvera-workspace/create-a-schema) and then [assigned to an ecosystem](https://docs.dock.io/dock-certs/ecosystem-tools/ecosystem-set-up#assign-credential-schemas).

<figure><img src="/files/QlangMT235EI6DyDu1S4" alt="" width="375"><figcaption></figcaption></figure>

Verification fee will be displayed to all ecosystem participants. Verification fee is displayed in USD, but ecosystem administrators can transact with their ecosystem participants in their preferred currency.

{% hint style="warning" %}
Truvera will charge a percentage of the Verification fee as a platform commission. For each verification where that commission is too low, we will charge a minimum platform fee.
{% endhint %}

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

{% hint style="info" %}
The systems supports tracking fees in fractions of a cent to six decimal places.
{% endhint %}

### Issuing credentials

The process of issuing credentials will be the same. [See step by step instructions.](#issue-credentials)

The issuer will see a message showing that the credential can only be verified by participants of the specified ecosystem and requires a verification fee.

<figure><img src="/files/6enxKLW6YdcvtG4FcYbM" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
Zero-Knowledge Proof type of credential is mandatory for paid verification and will be selected by default.
{% endhint %}

For the holders monetizable credentials will look almost the same as regular credentials, they will be able to see an Ecosystem Bound badge in the credential settings with the explanation, that this credential was issued within a specific ecosystem and is sharable only with verifiers authorized by that ecosystem.

<div align="left"><figure><img src="/files/TTdXmEAtdaLkQzjatEsR" alt="" width="188"><figcaption></figcaption></figure></div>

### Creating a verification template and assigning it

When [creating a verification template ](/truvera-workspace/verify-credentials)a message will be shown that there is a fee for verifying each credential using the selected schema.

<figure><img src="/files/0o99yeC5thecp40VGwoX" alt=""><figcaption></figcaption></figure>

[Verification templates need to be added to an ecosystem](https://docs.dock.io/dock-certs/ecosystem-tools/ecosystem-set-up#add-verification-templates) and will be visible for all participants.

{% hint style="info" %}
Wallet-to-wallet verification is not supported by monetizable credentials.
{% endhint %}

### Choosing a DID for verification

When using a monetizable credential verification template verifier will be prompted to choose the verifiers DID. It has to be the same DID that is participating in the ecosystem.

<figure><img src="/files/1huIquLl1aVCNR11wRFw" alt="" width="375"><figcaption></figcaption></figure>

{% hint style="info" %}
When the holder has the same information in monetizable credentials from two different ecosystems, verification will default to the least expensive ecosystem.
{% endhint %}

### Getting the billing report

All payments are managed by the ecosystem administrator. Truvera provides a billing report that can be downloaded by the ecosystem administrator.

<figure><img src="/files/io4xmItFH4bchfWLRyZ7" alt="" width="375"><figcaption></figcaption></figure>

Billing report data can be selected for a specific date range and will include information about the date of verification, schema that was verified, verification ID, DIDs of Issuer and Verifier, whether the verification was successful and verification and platform fees.

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

Billing report includes all verifications where a credential was submitted for verification e.g if a verification request was made, but no credential was presented it will not be included, however if an invalid credential is presented and verification fails it will be included in the billing report.

{% hint style="info" %}
Ecosystem administrators take responsibility for charge-backs and disputes.
{% endhint %}

{% hint style="info" %}
Ecosystem administrators can remove ecosystem participants that do not meet ecosystem requirements.
{% endhint %}


# Creating API keys and webhook endpoints

## Creating API keys <a href="#h_4fdcc1a10e" id="h_4fdcc1a10e"></a>

To create an API key, under the Developer menu item, click API Keys. Then select Create API key.

<figure><img src="/files/3QM6t7d13YntVmxwR6k0" alt=""><figcaption></figcaption></figure>

Under Whitelisted IP’s, you have the option to add additional security by configuring IP's that are allowed to access your services

<div align="left"><figure><img src="/files/ttwiGrXefhP8fQkz6UDH" alt="" width="375"><figcaption></figcaption></figure></div>

{% hint style="warning" %}
Keep your API key safe, for security reasons it will not be shown again. Please do not share this key. If you forget your API key, you will need to delete the existing key and create a new one.
{% endhint %}

For more information about API [See API documentation](/truvera-api)

## Webhooks endpoints <a href="#h_fae99467a4" id="h_fae99467a4"></a>

You can add or modify webhook endpoints that will send events when issuing or when transactions occur. Under Developer, select Webhook and click Add Endpoint on the top right.

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

Fill in the Webhook details and click Create Webhook.

[![](https://downloads.intercomcdn.com/i/o/797831076/f27e685f76d0e00a209759cd/6356fc0a5432fa812b8eaea6_2-Webhook+details.png)](https://downloads.intercomcdn.com/i/o/797831076/f27e685f76d0e00a209759cd/6356fc0a5432fa812b8eaea6_2-Webhook+details.png)


# Transaction history

To see a historical list of your used API transactions and issued credentials, click on the Activity menu item. This page shows a historical list of credential issuance events and blockchain transactions, such as DIDs and revocation.

In the line chart you will see your live transaction history (test mode is not counted).

<figure><img src="https://downloads.intercomcdn.com/i/o/797839765/6053c2b5a3398184cb3f9dd8/Screenshot+2023-08-01+at+17.30.59.png" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
To protect user data, issued credentials never go on the blockchain.
{% endhint %}

You can view the transactions on the blockchain by clicking on the status icon on the right of the transaction that links to the [blockchain viewer.](https://dock.subscan.io/)

<figure><img src="https://downloads.intercomcdn.com/i/o/797839983/666d43435647e376adf1f061/Screenshot+2023-08-01+at+17.31.13.png" alt=""><figcaption></figcaption></figure>


# Custom branded distribution emails

To enable our customers to create a streamlined user experience we enable them to customize the credential distribution emails.

To have your logo and company name appear on the email, you will need to update the relevant Organization profile with the logo and Public Name. It will then be used to brand the credential distribution email.

![](/files/inDJ0otVwtQntcG7vanz)

Add the recipient emails either manually or via spreadsheet import.

<figure><img src="https://downloads.intercomcdn.com/i/o/838291954/6d4441c49272e0bd61119cea/Screenshot+2023-09-25+at+16.13.00.png" alt=""><figcaption></figcaption></figure>

Make sure to select the same Issuer Profile when creating the credential.

<figure><img src="https://downloads.intercomcdn.com/i/o/838303114/0eed16ad121b1c97ef8cdb64/Screenshot+2023-09-25+at+16.12.31.png" alt=""><figcaption></figcaption></figure>

You will see the Email Preview before issuing the credentials, will be able to add a custom message.

<figure><img src="https://downloads.intercomcdn.com/i/o/838292085/c8d02f00cbb8808ff438be82/Screenshot+2023-09-25+at+16.13.34.png" alt="" width="375"><figcaption></figcaption></figure>

When the credential email is received it will show Your Company name in the send in the format "Your Company name via Truvera", it will have Your Logo on the top and will remove the Powered by Truvera logo at the bottom of the email.

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

{% hint style="info" %}
Custom branded Emails are available for Business and Custom plans only.
{% endhint %}


# Truvera Workspace release notes


# 2025 Release notes


# Release notes Q1 2025

## v1.59.0 March 27

### Updates and new features

DCKA-2413 The auto generation of “subject reference ID” from the ID or Name to make it easy to for a human to identify credentials in Workspace is optional.

## v1.58.0 March 24

### Updates and new features

DCKA-3043 Implemented SD-JWT support in the API for issuance and verification. Credentials can be distributed via OpenID and via DIDComm.

DCKA-3048 Improved the credential variant selector SD-JWT variant in Truvera Workspace

DCKA-4776 Move "plan and billing" item from left menu to the profile settings menu.

## v1.57.0 March 13

### Updates and new features

DCKA-1169 Added sub-account management to the Workspace UI.

DCKA-2233 Added filtering for verification history in the API.

DCKA-2392 Implemented team retention policy for issuance data.

DCKA-2433 Implemented team retention policy for verification data.

DCKA-2987 Proof requests can be created with an expiration date.

DCKA-3091 Renamed the Key column on the API key table to avoid mixing the key alias with the actual API key.

### Bug fixes

DCKA-3110 Fixed a typo in the credential distribution email, where the first letter was a vowel.

## v1.56.0 February 24

### Updates and new features

DCKA-3112 Fixed verifying presentations with many different accumulators

DCKA-3113 Added assigning dockbbs keypairs at DID creation via the API.

DCKA-3114 Improved cheqd transaction processing

## v1.54.0\&v1.55.0 February 10

### Updates and new features

DCKA-2917 Added production API support for cheqd blockchain.

DCKA-2938 did:cheqd becomes the default DID method in Certs.

## v1.53.0 February 6

### Updates and new features

DCKA-2941 Credentials will have a new revocation registry assigned automatically.

DCKA-2386 Added the option to Delete all verification history in Truvera Workspace.

DCKA-2918 Disabled did:dock creation for testnet

## v1.52.0 January 29

### Updates and new features

Added support for multiple blockchains at the same time and cheqd blockchain in particular.

Migrated customer data from Dock blockchain to cheqd.

DCKA-2892 Added support multiple chains at the same time

DCKA-2715 Added new mDL verification templates in Truvera Workspace.

DCKA-3070 Disabled Dock node connection for testnet.

### Bug fixes

DCKA-3051 Enabled deleting verification templates that are connected to an Ecosystem in the Workspace.

DCKA-3056 Added the initials of the account user, when there is no profile picture to be visible in the Workspace.

## v1.51.0 January 9

### Updates and new features

DCKA-2915 Released API support for cheqd

### Bug fixes

DCKA-2989 Fixed an issue in the Truvera Workspace, when a polygon did was selected and then changed to a different did the subject id field would still have the "Request info" checkbox selected.

DCKA-3028 Added a better message for a team invitation that has been accepted twice.


# Release notes Q2 2025

## v1.63.0 June 14

### Updates and new features

DCKA-4847 Separated job processing into its own service

## v1.62.0 May 14

### Bug fixes

DCKA-4841 Fix verification history showing each verifier 3 times

DCKA-4842 Fix an issued with creating did:cheqd on testnet

## v1.61.0 April 14

### Updates and new features

DCKA-3819 Support for EDV labels entries based on the application that creates it

DCKA-4834 Convert API to ESM modules

DCKA-4836 Upgrade gcsRDSBackup and API to newer node version

DCKA-4927 Create wallet-edv-storage package

### Bug fixes

DCKA-4816 Fix subaccount billing

DCKA-4821 Fix credential table resizing bug

## v1.60.0 April 3

### Updates and new features

DCKA-4779 Upon issuance of the credential there will be no download of the issued credential, credential needs to be distributed via email or DID during issuance or if persisted can be downloaded from the credential view.

DCKA-4802 Update API OID4VCI flows to support latest spec requirements

### Bug fixes

DCKA-3089 Fixed an error where the verification template attribute field would change value if edited.


# Release notes Q3 2025

## v1.69.0 September 18

### Updates and new features

DCKA-4885 Handled breaking changes in the Digital Credentials API

## v1.68.0 September 10

### Updates and new features

DCKA-5018 Updated existing DIDs to add a DIDComm service endpoint

### Bug fixes

DCKA-5074 Fixed creds crypto utilsation error

## v1.67.0 September 4

### Updates and new features

DCKA-5014 Updated Postgres versions in RDS

DCKA-5017 Updated the information published on a webhook when a DIDcomm message is received

DCKA-5040 Added DIDComm message receiving - storing and retrieving of messages

### Bug fixes

DCKA-4983 Fixed the "Total Requests" for verification template

DCKA-4997 Fixed an error when "Back to main account" switched teams

DCKA-4998 Fixed an issue where schemas added to ecosystem by URL were not available for selection

DCKA-5003 Fixed the editing of credential data in the credential view

DCKA-5005 Added a restriction to not be able to delete a profile picture from an organization that is part of an ecosystem

## v1.66.0 August 12

### Updates and new features

DCKA-5020 Added DIDComm service endpoints to the API

### Bug fixes

DCKA-4907 Fixed a number being added on the attribute when creating a schema

DCKA-4938 Fixed the convener DID displayed in the Ecosystem edit view

## v1.65.0 July 27

### Bug fixes

DCKA-4897 Updated cheqd tests

## v1.64.0 July 12

### Updates and new features

DCKA-4865 Improved the "Switch sub-account" option

DCKA-4887 Added an option to resend expired team invites

### Bug fixes

DCKA-4848 Fixed the layout problem when creating a verification template"

DCKA-4864 Added logos to the subaccount list

DCKA-4874 Fixed the team name display after switching user


# Release notes Q4 2025

## v1.71 October 16

### Updates and new features

DCKA-5007 Configured ECS for auto-scaling

DCKA-5151 Implemented old production DID cleanup

DCKA-5158 EDV: Full unit testing of the EDV

## v1.70 October 14

### Updates and new features

DCKA-5133 API: Support controlling 3rd party cheqd DIDs

DCKA-5056 Added a possibility to import an existing DID via the API

DCKA-5131 Added SDK support 3rd party DID documents

DCKA-5077 Added new UI for the credential distribution

DCKA-4995 Updated the behavior of email and ID fields displayed during manual issuance

DCKA-5129 Added SDK support key-1 identifier for verification method references


# 2024 Release notes


# Release notes February 2024

## v1.24.0 February 22

### **Overview**

The Dock Certs 1.24.0 release introduces a suite of Ecosystem Tools with Trust Registry integration, enhancing the platform's capabilities in managing digital credentials within ecosystems. This update emphasizes flexibility, security, and scalability, ensuring that Dock Certs remains at the forefront of digital credential management solutions.

### **New Features**

#### **Trust Registry on Blockchain**

* **\[DCKA-2090] SDK/Chain Integration**: Store trust registry on the blockchain to enhance security and verifiability. Participants now need to consent before being added to an ecosystem, strengthening trust and compliance.

#### **Ecosystem Flexibility Enhancements**

* **\[DCKA-2341] Publicly Verifiable Schemas**: Ecosystem administrators can now specify schemas that are publicly verifiable, broadening the reach and applicability of issued credentials.
* **\[DCKA-2342] Issuance and Verification Schema Assignment**: Enables assigning different schemas for issuance and verification to ecosystem participants, catering to complex credential workflows.
* **\[DCKA-2346] Verification Template for Ecosystem Issuers**: Verifiers can create verification templates that accept credentials from all trusted ecosystem issuers for specified schemas, simplifying verifier workflows.

### **Enhancements**

#### **Scalability and Reliability**

* **\[DCKA-2283] Scalability Implementation Plan**: A detailed plan and breakdown to address scalability, ensuring Dock Certs can handle increased loads and maintain reliability at scale.

#### **User Experience and Usability**

* **\[DCKA-2360] CSV Import Charset Specification**: Users can now specify their charset when importing CSV files for bulk credential issuance, enhancing data compatibility and user control.

#### **Participant Management**

* **\[DCKA-2349] Self-removal from Ecosystems**: Participants can now remove themselves from an ecosystem, offering greater control and flexibility within the platform.

#### **Development and Compliance**

* **\[DCKA-2366] NPM Module License and Optionality Fixes**: Improved compliance and customization by adjusting NPM module usage and licenses.
* **\[DCKA-2368] Open Source License Check on PRs**: Implements checks for copy-left licenses in code contributions, ensuring compliance and protecting intellectual property.

### **Bug Fixes**

* **\[DCKA-2357] "Unmaintained" Badge Display Issue**: Fixed the issue where all ecosystems were showing an "Unmaintained" badge, ensuring accurate status representation.
* **\[DCKA-2359] Ecosystem About Section Button Fix**: Resolved an issue with the "More" button in the ecosystem about section, improving user interaction and information accessibility.
* **\[DCKA-2365] Credentials "Requested" Tab Error**: Addressed a bug causing errors when viewing the "Requested" tab on the Credentials screen, enhancing functionality.
* **\[DCKA-2373] "Learn More About" Display Fix**: Corrected the placement of the "Learn more about" link on the Credentials page, improving UI consistency.

## v1.23.0 February 9

### **Overview**

This release focuses on improving verification processes, ecosystem participation, and platform reliability, alongside critical bug fixes and user experience enhancements.

### **New Features**

#### **Enhanced Verification Security**

* **\[DCKA-2248] Verification Template DID Assignment**: Ensures the security of verification templates by requiring a signed message if a DID is present, preventing unauthorized DID assignments or QR code spoofing.

#### **Ecosystem Schema Integration**

* **\[DCKA-2307] Easy Proof Request Creation**: Developers can now easily create custom verification templates for proof requests using schemas assigned by the ecosystem administrator, streamlining the process of participating in an ecosystem.

#### **Ecosystem Participant Insights**

* **\[DCKA-2343] Participant List with Descriptions**: Ecosystem participants can view detailed descriptions of other participants, facilitating informed decisions about their participation in an ecosystem.

### **Bug Fixes**

* **\[DCKA-2328] Credential Validation Issue**: Addressed a critical issue where credentials became invalid after requested attributes were put in via the wallet.
* **\[DCKA-2160] Plan Upgrade Limits**: Fixed a bug where upgrading plans did not correctly update plan limits or reflect overage charges.
* **\[DCKA-2318 & DCKA-2321] Search Sensitivity and Signup Flow**: Improved user search functionality to be case-insensitive and ensured that Google account signups correctly trigger the signup flow.

### **Enhancements**

#### **Documentation and Support**

* **\[DCKA-2179] Common Issue Resolution Documentation**: Provided detailed documentation on common issue resolutions, enhancing the support process for users and administrators.

#### **User Experience Improvements**

* **\[DCKA-2265 & DCKA-2271] UX and Dashboard Consistency**: Implemented a series of small UX improvements and ensured visual consistency across all Certs dashboards, enhancing the user experience.

#### **Ecosystem Integration and Usability**

* **\[DCKA-2282 & DCKA-2296] Team Management and Ecosystem Invites**: Enhanced email notifications regarding ecosystem changes and improved the UX for accepting ecosystem invites, allowing users to change teams more seamlessly.

#### **Platform Reliability and Testing**

* **\[DCKA-2326 & DCKA-2331] Improved Critical Failure Handling and Automated Testing**: Introduced better handling for critical failures and implemented automated tests for Certs ecosystem tools, increasing platform reliability.

#### **Ecosystem Tools and Management**

* **\[DCKA-2344] Ecosystem Defaulting**: For users part of multiple ecosystems, Certs now defaults to the most recently used ecosystem, streamlining the user experience.

#### **Menu and Tagging Adjustments**

* **\[DCKA-2293] Menu Tag Update**: Moved the "new" tag from Schemas to Ecosystems in the Certs menu, better highlighting the introduction of new features.


# Release notes March 2024

## v1.26.1 March 22

### **Overview**

This release addresses specific needs identified by our ecosystem administrators and enhances the overall functionality and usability of Dock Certs.

### **New Features**

#### **Ecosystem Participant Onboarding**

* **\[DCKA-2377]** Administrators can now assign relevant schemas for issuance and verification directly when inviting a new participant to an ecosystem. This streamlines the setup process, enabling participants to contribute immediately after accepting their invitation.

#### **Subscription Management**

* **\[DCKA-2379]** Introduced a "Sync with Stripe" button on the account page to manually synchronize subscription data with Stripe. This feature allows for immediate correction and update of subscription details, ensuring accurate billing and service delivery.

### **Enhancements**

#### **License Compliance**

* **\[DCKA-2358]** Implemented an action in Dock JS repositories to detect GPL/AGPL packages and reject them, reinforcing our commitment to maintaining license compliance across all JavaScript projects.

#### **Verification History Management**

* **\[DCKA-2385]** API calls have been added to allow deletion of individual entries or all history for a specific verification template. This offers more flexibility in managing verification data in compliance with privacy policies and data retention guidelines.

#### **Ecosystem Tools Access for Subscribers**

* **\[DCKA-2445]** Updated the Certs database to ensure that all existing subscribers benefit from the ecosystem tools according to the licensing rules established in the previous release. This ensures all users have appropriate access to these powerful tools.

### **Bug Fixes**

#### **Trial Account Onboarding**

* **\[DCKA-2424]** Fixed an issue where expired trial accounts were incorrectly taken through the new onboarding process, which could not be completed due to the expired status. Now, onboarding will not initiate for expired trials, and any failed issuance during onboarding will redirect users to the dashboard, avoiding any disruption.

#### **UI and Data Display**

* **\[DCKA-2451]** Addressed a UI issue where participant names overlapped field boundaries in the ecosystem section. Improved logic and UX design ensure that participant information is displayed cleanly and legibly.

## v1.26.0 March 19

### Overview

This release brings significant improvements to credential verification within ecosystems, updates documentation links across the platform, and addresses key user feedback and bug fixes to streamline the Dock Certs experience.

### **New Features**

#### **Ecosystem Credential Verification**

* **\[DCKA-2270]** Verifiers now have the ability to see an ecosystem badge during credential verification, providing immediate visibility into whether a credential is part of an ecosystem they participate in. This ensures users can easily identify credentials issued by trusted ecosystem participants.

#### **Enhanced Documentation Access**

* **\[DCKA-2390]** All links within Dock Certs have been updated to point to the new Documentation Portal. This change ensures users have direct access to the most current and comprehensive guidance available, improving ease of use and support.

#### **Ecosystem Tools Documentation**

* **\[DCKA-2317]** Comprehensive end-user documentation for Ecosystem Tools has been introduced, covering everything from ecosystem administration to participation. This documentation is designed to help users maximize the benefits of Dock Certs’ ecosystem functionalities.

### **Enhancements**

#### **Billing Plan Clarification for Ecosystem Tools**

* **\[DCKA-2363]** The billing plans for ecosystem tools have been finalized, detailing which functionalities are available for different tiers. This clarification helps administrators and participants understand their access and capabilities within the ecosystem tools feature set.

#### **Verification History Sorting**

* **\[DCKA-2407]** Verification history now prioritizes the most recent verifications, with the “Created” column displaying timestamps for precise tracking.

### **Bug Fixes**

#### **UI and Functional Improvements**

* **\[DCKA-2396]** Resolved an issue where the name of a recipient was displayed multiple times for the same schema within an ecosystem.
* **\[DCKA-2406]** Fixed a complex and broken flow in deleting schemas, ensuring a smoother schema management experience.
* **\[DCKA-2411]** Addressed a bug in the ecosystems participants table refresh and save state indication.
* **\[DCKA-2419]** Corrected team switching errors within ecosystems, preventing "cannot find trust registry" messages.
* **\[DCKA-2426]** Fixed a display issue where deleting an organization profile showed it as "unnamed" until the page was refreshed.
* **\[DCKA-2429 & DCKA-2437]** Improved UI alignment in the "assign schemas to participants" table and fixed schema issuance errors with numbers/integers.

#### **Enhanced User Experience**

* **\[DCKA-2409]** Updated all Certs links to point to the correct sections within the new documentation portal, ensuring users are directed to relevant information efficiently.
* **\[DCKA-2420]** Improved the error message when using an invitation link for a deleted ecosystem, enhancing clarity and user guidance.
* **\[DCKA-2448]** Added a "Book a Demo" Calendly link to the ecosystem empty mainpage, facilitating easy access to personalized support and demonstrations.

## v1.25.0 March 07

### Overview

This release includes significant improvements on Dock Certs, focusing on making the Ecosystem Tools feature production-ready and introducing several enhancements and fixes. This feature along with all the below mentioned improvements is currently behind a feature flag and only available to internal users and beta testers.

### **New Features**

#### **Ecosystem Landing Page**

* **\[DCKA-2258]** To help users who are not subscribed to Ecosystem Tools we have added a landing page inside certs to better understand the benefits of this feature.

#### **Ecosystem Schema Management**

* **\[DCKA-2281]** **Admin Schema Assignment**: Ecosystem admins can now add schemas to their ecosystem with ease, either from the schema table or participant view. This includes the ability to select from existing schemas, mark those already in the ecosystem, and assign them to participants. A "create new schema" option is also now available for greater flexibility.

#### **Improved Ecosystem Participation**

* **\[DCKA-2376] Participant Role Automation**: The process of setting participant roles has been automated based on assigned schemas, removing the need for manual role selection and simplifying the ecosystem management experience
* **\[DCKA-2351] Ecosystem Administrator Visibility:** On the ecosystem view, the participant will now be able to see who is the administrator of the ecosystem.
* **\[DCKA-2299] Ecosystem Admin Participation:** Ability for ecosystem admins to add their organization profiles on relevant ecosystem roles and participate.

### **Enhancements**

#### **User Experience Improvements**

* **\[DCKA-2361] UX Cleanup**: Several user experience improvements have been implemented, including UI consistency enhancements, clearer empty state prompts, and more intuitive navigation elements.

#### **Default Schemas and Templates**

* **\[DCKA-2295] Badge Markings for Defaults**: Default schemas and verification templates are now marked with a badge to distinguish them from user-created items, enhancing clarity and usability .
* **\[DCKA-2245] Ecosystem verification Templates: Verification templates inside an ecosystem are available to all ecosystem verifiers.**

### **Bug Fixes**

* **\[DCKA-2353]** **Ecosystem Creation Labeling**: Updated terminology from "Convener" to "Ecosystem Administrator" across the platform for consistency and clarity.
* **\[DCKA-2362]** **Invitation Process Streamlining**: Fixed an issue where accepting invitations required logging in twice, now allowing users to proceed directly to the invitation acceptance page after login.
* **Ecosystem Schema and Participant Management Fixes**:
  * \[DCKA-2394] 400 error fix when trying to assign schema to a participant
  * \[DCKA-2397] Fix for error on duplicated schema assignment when original was deleted
  * \[DCKA-2399] Fix for job failure error when updating participant information.


# Release notes April 2024

## v1.30.0 April 24

### Overview:

The release 1.30.0 includes improvements related to error message handling within ecosystem along with fixes related to plan upgrade popup and proof requests. Additionally, as part of this release, we have continued on the performance improvement initiative for anonymous credentials issuance.

### **Enhancements**

#### **Clear Error for Verifiers of Locked Credentials**

* **\[DCKA-2493]**: Implemented a feature to provide clear error messages to verifiers attempting to access locked credentials from ecosystems they are not members of. When a verifier outside of the ecosystem attempts to verify a locked credential, they now receive a message stating: "This credential can only be verified by participants in the \[ecosystem name] ecosystem. You can learn about the ecosystem by visiting this website: \[ecosystem website]". This enhancement aims to improve transparency and guidance for verifiers encountering locked credentials.

### **Bug Fixes**

#### **Upgrade Pop-up Issue**

* **\[DCKA-2518]**: Resolved an issue where the upgrade pop-up sometimes appeared when inviting team members, without displaying the close button. Users encountered difficulty closing the pop-up, impacting user experience. With this fix, the upgrade pop-up behaves as expected, ensuring smoother interaction when inviting team members.

#### **Proof Requests Missing ID**

* **\[DCKA-2521]**: Fixed a bug where proof requests did not contain an ID required by the latest PEX library. This issue prevented seamless processing of proof requests, leading to errors and inconsistencies. By addressing this bug, proof requests now include the necessary ID, ensuring compatibility with the latest PEX library.

### **Tasks**

#### **Anonymous Credential Issuance Performance Investigation**

* **\[DCKA-2459]**: Conducted an investigation into the performance of anonymous credential issuance. Test results revealed that issuing an anonymous credential took approximately 3 seconds on average, highlighting potential performance improvements. To address this, debug tracing was enhanced to identify slow points, and further investigation into the efficiency of BBS 2023 compared to BBS+ was initiated. This investigation aims to optimize the performance of anonymous credential issuance for enhanced user experience.

#### **URL Connectivity for PolkadotJS**

* **\[DCKA-2522]**: Provided a list of URLs to connect with PolkadotJS, enabling fallback connectivity. Users can now connect to a private API node and fallback to another URL if the primary connection fails. This enhancement ensures robust connectivity and resilience when interacting with PolkadotJS.

## v1.29.0 April 18

### Overview:

This release includes fixes for revocation registries, certs UX for create organization profile flow and enhancements related to ecosystems tools along with content updates for certs plans as per our revised offerings.

### **Bug Fixes**

#### **Update DID Drawer Issue**

* **\[DCKA-2507]**: Resolved an issue where clicking "Create Organization Profile" after editing a DID opened the same drawer instead of a new pop-up to create a new DID. This bug caused confusion and inconsistency in the user interface. With this fix, users can now seamlessly create new DIDs without encountering unexpected behavior.

#### **Registries Filtering Issue**

* **\[DCKA-2514]**: Addressed a bug where Certs failed to find a registry to use due to an issue with filtering registries. This bug affected the functionality of Certs, preventing users from effectively managing registries. By fixing the registry filtering API route, Certs can now accurately identify and utilize registries as intended.

#### **Incorrect Revocation Status for Anoncreds**

* **\[DCKA-2515]**: Fixed a bug where issuing revocable anoncreds with a previously used DID incorrectly showed as revoked when it wasn't. This issue stemmed from using the wrong public/private keypair, leading to inaccurate revocation status. With this fix, Certs now accurately reflects the revocation status of anoncreds, ensuring data integrity and reliability.

#### **New Registry Creation at Each Issuance**

* **\[DCKA-2516]**: Resolved an issue where a new registry was created at each issuance if not using BBS+. This behavior resulted in unnecessary proliferation of registries, leading to inefficiency and clutter. By fixing this issue, Certs now creates registries appropriately, optimizing resource utilization and improving system performance.

### **Tasks**

#### **Prompt Admin to Create Schemas Before Inviting Participants**

* **\[DCKA-2462]**: Implemented a feature to prompt ecosystem administrators to create schemas before inviting participants. This enhancement ensures that administrators have the necessary schemas prepared for participants, streamlining the onboarding process and avoiding potential delays or errors.

#### **Update Subscription Plan Names and Features**

* **\[DCKA-2508]**: Updated the names and feature lists for subscription plans in Certs to reflect recent pricing changes. The Business plan has been renamed to the Build plan, with corresponding feature adjustments. Additionally, the Custom Plan has been renamed to Scale, with updated features to align with the new plan structure. These updates provide clarity and accuracy regarding subscription offerings in Certs.

#### **Sales Demo Registry Optimization**

* **\[DCKA-2517]**: Optimized the sales demo to prevent the creation of a new revocation registry for each issuance. This enhancement reduces unnecessary registry creation, improving system efficiency and resource management.

## v1.28.0 April 14

### Overview:

This release includes updates to the user interface, improvements to verification template handling, bug fixes related to credential issuance, and tasks aimed at defining architecture for future features.

### **New Features**

#### **Optional Fields in Verification Templates**

* **\[DCKA-2468]**: Verification templates in Certs now support optional fields. Administrators can designate attributes as optional, enhancing flexibility in proof presentation responses.

#### **Ecosystem Membership Display in Organization Profiles**

* **\[DCKA-2417]**: Organization profiles now display the ecosystems where the organization profile is used. Additionally, ecosystem badges are included in the organization profile details, providing easy access to ecosystem information.

### **Bug Fixes and Improvements**

#### **BBS+ Credential Issuance Error**

* **\[DCKA-2501]**: Resolved an error where issuing BBS+ credentials resulted in a "Schema properties did not contain top-level key" error, ensuring smooth credential issuance processes.

#### **Revocation Status Error with did:polygonid Creation**

* **\[DCKA-2509]**: Fixed an issue where creating a new organization profile with a did:polygonid DID resulted in a "can't fetch revocation status" error, ensuring successful profile creation without errors.

### **Tasks and Research**

#### **Architecture Definition for Verifier Pays Issuer**

* **\[DCKA-2263]**: Defined the architecture for Verifier Pays Issuer, laying the groundwork for future implementation and facilitating transactions within the ecosystem.

#### **Wallet Cache Management Solution**

* **\[DCKA-2474]**: Introduced a basic key/value map for wallet cache management, with plans to expand functionality to include limiting cached wallets, clearing old values, and improving the interface for setting/getting values.

## v1.27.0 Apr 04

### Overview

Dock Certs 1.27.0 introduces significant updates to our pricing plans, enhanced credential management features, and important bug fixes and optimizations. These changes aim to streamline user experience, improve flexibility, and align our offerings with market demands and best practices.

### **New Features**

#### **Pricing Plan Updates 2024**

* **\[DCKA-2374]**: This release brings comprehensive updates to our pricing plans for 2024, reflecting changes in feature availability, trial duration, and subscription terms. Notable adjustments include the inclusion of Anonymous credentials and Encrypted credential backup features in the Free Trial plan, removal of the Starter Plan, and flexibility in seat management for Business and Custom plans.

#### **Anonymous Credentials Expiration**

* **\[DCKA-2467]**: Certs now automatically adds expiration dates to verification templates for anonymous credentials, ensuring consistent enforcement of expiration policies. Users can choose to remove expiration dates for maximum privacy or comply with specific privacy requirements.

### **Enhancements**

#### **Credential Creation Defaults**

* **\[DCKA-2134]**: Default credential creation settings have been optimized to align with best practices, encouraging simplicity and privacy. Key changes include the use of anonymous credentials for enhanced privacy and avoidance of persistent credentials to simplify PII management.

#### **Organization View UX Improvement**

* **\[DCKA-2431]**: The organization profile management has been revamped to improve usability and accommodate additional fields. It is now presented as a drawer instead of a pop-up when editing, providing a more spacious and intuitive interface for managing organization details.

#### **Verifier DID Profile Exposure**

* **\[DCKA-2475]**: Verifier DID profile name and logo are now exposed to proof request messages, enhancing verification processes and providing more context to credential recipients.

### **Bug Fixes and Maintenance**

#### **UI and UX Fixes**

* **\[DCKA-2457]**: Fixed button styling inconsistencies on the settings page, ensuring a symmetrical design and improved visual consistency.
* **\[DCKA-2477]**: Corrected the style of the cancel button and warning icon when declining invitations, ensuring a cohesive and intuitive user experience.

#### **Database Certificate Updates**

* **\[DCKA-2332]**: Updated certificates for RDS instances to comply with AWS requirements, ensuring secure connections and preventing connectivity issues.

### **API and Backend Improvements**

#### **Blockchain Transaction Fee Tracking**

* **\[DCKA-2476]**: Implemented tracking of blockchain transaction fees in the database, facilitating easier monitoring and analysis of transaction costs.

#### **KVAC Credential Issuance**

* **\[DCKA-2491]**: Introduced KVAC (Key Verified Anonymous Credential) issuance and verification capabilities via the API, enabling secure and privacy-preserving credential management.

### **Documentation and Infrastructure**

* **\[DCKA-2416]: Onboarding Form Update**: The job title field is now required in the onboarding form, ensuring completeness and accuracy of user profiles.


# Release notes May 2024

## v.1.33.0 May 21

### **Overview:**

Certs v1.33.0 introduces a series of bug fixes and improvements aimed at enhancing the functionality and stability of the application.

### **Bug Fixes:**

* **DCKA-2288:** Fixed an issue where some fonts were missing on the PDF render server, ensuring accurate rendering of PDF documents.
* **DCKA-2589:** Resolved the "Secret key needs to be provided" error encountered when issuing a BBS+ revocable credential, ensuring smooth credential issuance.
* **DCKA-2590:** Addressed the 'Cannot add new DID key at this time of algorithm: dockbbs' error message received when attempting to create a BBS revocable credential, ensuring successful issuance without errors.
* **DCKA-2591:** Fixed the issue where proof templates were being returned multiple times in the API route, ensuring correct and consistent data retrieval.

### **Task:**

* **DCKA-2092:** Implemented bounds check in the proof presentation to validate the bounds since the cryptography library does not, ensuring data integrity and security.
* **DCKA-2542:** Ensured rejection of unsigned credentials in presentations for proof requests, enhancing security measures.
* **DCKA-2561:** Investigated and set up an autoscaling solution and AWS load balancer for the PDF render server, improving scalability and performance.

## v.1.32.0 May 08

### Overview

In this release of Dock Applications - Certs v1.32.0, we address several issues reported by users and introduced enhancements to improve the functionality and reliability of the platform. These updates aim to resolve PDF generation and opening issues, improve error handling for node connection failures, and ensure the default usage of BBS2023 for anonymous credentials, among other improvements.

### Bug Fixes

#### PDF Generation and Opening Issues

* **\[DCKA-2537] \[DCKA-2560]**: Fixed an issue where PDFs generated in Certs were not opening properly, as reported by users encountering errors when attempting to open PDF files. Additionally, a similar issue reported by Gravity, where PDF reports were not opening and resulted in a FUNCTION\_INVOCATION\_TIMEOUT error, has been addressed. These issues have been resolved to ensure that PDF files and reports can be generated and opened without any issues.

#### Accumulator Revocation Registries Key Pair Issue

* **\[DCKA-2513]**: Resolved an issue where accumulator revocation registries key pairs were incorrectly tied to a single DID. Now, each accumulator registry has a unique key per registry, ensuring proper functionality and security.

#### Unable to Open Downloaded VC Credentials File

* **\[DCKA-2526]**: Fixed an issue where downloaded VC credentials files could not be opened on staging using the testnet. Users encountered difficulties opening \*.pdf files after extraction. This issue has been resolved to allow seamless opening of downloaded VC credentials files.

### Tasks

#### Improved Error Handling for Node Connection Failures

* **\[DCKA-2523]**: Enhanced error handling for node connection failures to ensure that API alerts are more visible and actionable. Slack alerts now provide clearer indications of errors, and efforts have been made to trigger Zenduty alerts for enhanced monitoring and response to node connection failures.

#### Default Usage of BBS2023 for Anonymous Credentials

* **\[DCKA-2524]**: Updated the default usage of BBS2023 for anonymous credentials. With BBS formally proved in 2023, the platform now defaults to BBS2023 for anonymous credentials, ensuring alignment with industry standards and improved security.

#### Healthcheck PDF Rendering

* **\[DCKA-2544]**: Implemented improvements related to health checks of PDF rendering in the Dock API. This enhancement ensures more reliable rendering of PDF files, contributing to the overall stability and performance of the platform.

## v.1.31.0 May 01

### **Overview**

In this release of Dock Applications - Certs v1.31.0, we introduce several bug fixes and enhancements aimed at improving security, functionality, and usability of the Certs platform. These updates address various issues reported by users and enhance key features to provide a more seamless experience for our users.

### **Bug Fixes**

#### **Account Name Validation Enhancement**

* **\[DCKA-2499]**: Implemented validation for account names in Certs to prevent the inclusion of URLs. Previously, account name text fields lacked validation, allowing any characters to be used and potentially leading to malicious activities. With this fix, validation has been added to ensure that only appropriate characters are accepted, enhancing security and preventing potential vulnerabilities.

#### **Anoncreds Verification Issue with Required Fields**

* **\[DCKA-2502]**: Resolved an issue where anoncreds verification failed if a schema had required fields that were not revealed. The SDK now removes the required option during schema validation and only checks types/values, ensuring accurate and reliable verification of anoncreds credentials.

#### **Fix for publicKeyMultibase Invalid Header Bytes**

* **\[DCKA-2530]**: Addressed an issue related to publicKeyMultibase invalid header bytes for DIDComm messaging.

### **Tasks**

#### **Support for Ed25519-2020 Keys**

* **\[DCKA-2527]**: Added support for Ed25519-2020 keys for signing and verification in the Dock SDK/API. This enhancement expands the capabilities of the SDK/API, allowing users to utilize Ed25519-2020 keys for cryptographic operations.


# Release notes June 2024

## v.1.35.0 June 12

### Story

* **\[DCKA-1765]** - Migrated push notification service from Firebase Legacy HTTP Protocol to the more secure and scalable HTTP v1 API, in line with Google's recommendations. This ensures continued functionality post-June 20, 2024, when the legacy APIs are discontinued.
* **\[DCKA-2597]** - Implemented notifications for issuers when issuing "Ecosystem Bound" credentials, clarifying usage restrictions and pricing terms within ecosystems.

### Task

* **\[DCKA-2488]** - Implemented a paid verification reporting service. Ecosystem administrators can now download a CSV report of verifications for billing purposes.
* **\[DCKA-2490]** - Integrated KVAC during proof presentation verification, ensuring that verifiers pay for credential verification and differentiating between valid, revoked, and fraudulent credentials.
* **\[DCKA-2496]** - Displayed the list price per schema to ecosystem participants.
* **\[DCKA-2510]** - Enabled verifiers to build verification templates using KVAC/locked schemas, showing any associated costs.
* **\[DCKA-2588]** - Included the verifier DID in verification templates with paid credentials.

### Bug Fixes

* **\[DCKA-2532]** - Updated the label for "polygonid" to "polygonid amoy testnet" for clarity.
* **\[DCKA-2586]** - Groomed Sentry issues for better error tracking and management.
* **\[DCKA-2616]** - Ensured URL validation when inviting participants, preventing invalid URLs from being accepted.
* **\[DCKA-2618]** - Fixed the error message "Can not edit Registry" that appeared incorrectly when saving ecosystem name changes.
* **\[DCKA-2619]** - Validated links for assigning schemas to ecosystem participants, ensuring only valid links are accepted.
* **\[DCKA-2621]** - Investigated and resolved PDF render deploy failures.
* **\[DCKA-2623]** - Addressed "Job failed" errors when assigning paid schemas to ecosystems.
* **\[DCKA-2624]** - Fixed the issue where participants were removed from the first schema when assigned a new one.
* **\[DCKA-2626]** - Corrected the "Invalid Missing participant URL" error displayed during schema selection.
* **\[DCKA-2628]** - Prevented fractional cents from being displayed when adjusting verification fees, ensuring only round numbers are used.
* **\[DCKA-2629]** - Fixed schema delete errors when part of a trust registry.
* **\[DCKA-2632]** - Improved trimming of organization profile display names to avoid exceeding defined lengths.
* **\[DCKA-2635]** - Resolved download failures for billing reports after submitting verification.
* **\[DCKA-2637]** - Fixed issues with updating participant information where logo/info URL fields were unnecessarily required.
* **\[DCKA-2640]** - Addressed issues preventing schema assignment for certain combinations.
* **\[DCKA-2642]** - Ensured newly created verification templates are displayed at the top of the list.

## v.1.34.0 June 05

### **Overview:**

Certs v1.34.0 introduces several bug fixes aimed at improving user experience and system functionality related to ecosystem tools.

### **Bug Fixes:**

* **DCKA-2599:** Addressed issues with the ecosystem invitation API, including resolving errors related to missing participant details and ensuring consistency between the provided name and organization profile. Additionally, improvements were made to the handling of authentication tokens and documentation clarity.
* **DCKA-2601:** Fixed an issue where assigning a schema to a participant would cause the form to become unresponsive, ensuring smooth operation and usability.

**Task:**

* **DCKA-2529:** Created a staging relay service to facilitate load testing and ensure system reliability under various conditions.
* **DCKA-2596:** Enhanced the user interface by hiding back and next buttons and the stepper when only one credential is requested, reducing visual clutter and improving usability.


# Release notes July 2024

## v.1.36.0 July 11

### Story

* **\[DCKA-2059]** - Improved the visibility of custom attributes in verification templates. Custom attributes are now instantly visible under the "custom attribute" heading and sorted alphabetically upon selection.

### Tasks

* **\[DCKA-2253]** - Moved onboarding submission logic to the API, allowing Certs session tokens for authorization.
* **\[DCKA-2486]** - Updated UX for setting prices per schema in an ecosystem to align with current VPI design.
* **\[DCKA-2503]** - Applied the ElasticCache update to improve security and performance.
* **\[DCKA-2543]** - Integrated uniresolver status checks in healthcheck AWS.
* **\[DCKA-2583]** - Enhanced PEX validation error messages for better clarity.
* **\[DCKA-2593]** - Updated SSL/TLS certificates for dockusers RDS instance to prevent connectivity failures.
* **\[DCKA-2602]** - Created a wallet API skeleton for Dock Web.
* **\[DCKA-2604]** - Conducted end-to-end testing for the VPI feature in Certs and Wallet.
* **\[DCKA-2634]** - Improved performance for sales demo verification, reducing the average verification time.
* **\[DCKA-2645]** - Added batch-DIDs relay service get messages test.
* **\[DCKA-2652]** - Ensured verification fees are displayed with two decimal points.
* **\[DCKA-2653]** - Added pagination to the participant list table in the ecosystem view.
* **\[DCKA-2656]** - Showed only issuer DIDs belonging to the ecosystem during schema issuance.
* **\[DCKA-2658]** - Enabled default and optional DID selection during verification template creation.
* **\[DCKA-2659]** - Sorted verification templates by date created, displaying the newest first.
* **\[DCKA-2660]** - Changed the "edit" button to "copy" for shared verification templates not owned by the user.
* **\[DCKA-2663]** - Improved the credentials issuance flow feedback.
* **\[DCKA-2664]** - Allowed trial users to accept ecosystem invitations in test mode.
* **\[DCKA-2671]** - Restricted sign-up to valid company emails to improve marketing scoring.
* **\[DCKA-2673]** - Enforced a minimum verification fee for ecosystem-bound credentials.
* **\[DCKA-2674]** - Prevented public schemas from having a verification fee.
* **\[DCKA-2683]** - Renamed columns in the billing report for clarity.
* **\[DCKA-2684]** - Displayed the verifier DID in the verification history.
* **\[DCKA-2686]** - Ensured proper DID selection when generating a verification QR code.
* **\[DCKA-2689]** - Implemented automatic detection of Certs sign-up outages and triggered alerts/support.
* **\[DCKA-2692]** - Applied KVAC logic and reporting for the same issuer/verifier accounts.
* **\[DCKA-2693]** - Enforced a minimum platform fee for ecosystem-bound credential verification to ensure revenue.
* **\[DCKA-2694]** - Added basic ecosystem list and editing functionality to Dock CQ.
* **\[DCKA-2699]** - Switched to Vitest for end-to-end testing to improve test performance and reliability.

### Bug Fixes

* **\[DCKA-2698]** - Fixed an issue where team invitations were not working after sign-up. Invited users can now successfully join the team after completing the sign-up process.
* **\[DCKA-2584]** - Fixed credential status to include statusPurpose properties, ensuring compatibility and proper functioning.
* **\[DCKA-2638]** - Reduced the clickable area when assigning fees to avoid unintended selection.
* **\[DCKA-2644]** - Updated Certs links to developer documentation to point to the new docs portal.
* **\[DCKA-2646]** - Enabled verifiers to change the DID on verification templates, fixing issues with incorrect DID handling.
* **\[DCKA-2650]** - Ensured attributes appear correctly when creating verification templates.
* **\[DCKA-2655]** - Updated empty table text for verification templates in ecosystems, clarifying that participants cannot add templates.
* **\[DCKA-2657]** - Fixed an issue where credentials issued outside an ecosystem incorrectly showed as ecosystem-bound.
* **\[DCKA-2669]** - Addressed issues with the "Open in Wallet" link not working when no wallet is installed on Android devices.
* **\[DCKA-2672]** - Corrected the participant count for ecosystem schemas.
* **\[DCKA-2677]** - Fixed the date order of ecosystem-assigned verification templates.
* **\[DCKA-2678]** - Included KVAC verifications in the ecosystem report to ensure accurate billing.
* **\[DCKA-2680]** - Resolved schema removal issues in verification templates.
* **\[DCKA-2682]** - Enabled ecosystem admins to delete verification templates.
* **\[DCKA-2687]** - Addressed issues with saving verification templates without storing the DID.
* **\[DCKA-2688]** - Fixed onboarding issues for new users in Certs production.
* **\[DCKA-2701]** - Removed additional error notifications when deleting ecosystems.
* **\[DCKA-2703]** - Fixed the duplicate display of DID missing error messages.
* **\[DCKA-2705]** - Resolved errors when issuing VPI credentials with assigned prices.

## v1.37.0 July 24

### Story

* **\[DCKA-2603]** Indicate Last Block for Accumulator Update When Sharing Witness. Credential will indicate last block where accumulator was updated when sharing the witness.

### Bug fixes

* **\[DCKA-2651]** Members and administrators of a team that has a paid plan will be able to see that another team has a paid plan enabled and also how many credentials are left on that plan.
* **\[DCKA-2666]** Users can join more than 2 teams.
* **\[DCKA-2721] \[DCKA-2728]** Fixed errors that occurred when verifying a KVAC credential.
* **\[DCKA-2724** ]Fixed the verification template issues when adding schema specific attributes.
* **\[DCKA-2727]** Fixed the credential schema view, that sometimes did not load completely.

### Task

* **\[DCKA-2252]** Created API endpoints to create keys and manage them, allow using a certs session token to access these API routes.
* **\[DCKA-2630]** Added cypress tests for onboarding flow
* **\[DCKA-2675]** "My Plan: Free trial" shows the expiration date
* **\[DCKA-2696]** Stress tested add batch-did relay service
* **\[DCKA-2718]** Disabled the possibility for new users to sign up using non-work emails
* **\[DCKA-2738]** \[Dock API] Fixed race condition when creating credential immediately after creating a DID.

## v1.37.1 July 30

### Bug fixes

* **\[DCKA-2749]** Fixed a bug where users where being logged out after sending the invite links.
* **\[DCKA-2739]** Added a better error message if user tries to sign proof request with polygon DID.
* **\[DCKA-2745]** Fixed a bug where ecosystem showed wrong convener name and logo


# Release notes August 2024

## v1.40.0 August 29

### Bug fixes

* **\[DCKA-2807]** Fixed the issue where holders were unable to submit data for requested attributes during credential issuance.

### Tasks

* **\[DCKA-2732]** Added a button to delete a schema from an ecosystem table in the UI.
* **\[DCKA-2788]** Billing report of monetizable verifications include the id of verification template used.

## v1.39.0 August 20

### Bug fixes

* **\[DCKA-2735]** Fixed a logo issue in the ecosystem participants list, when a schema was assigned to the same DIDs in two different ecosystems.
* **\[DCKA-2796]** Fixed a bug that did not allow users to login with their @gmail accounts.
* **\[DCKA-2797]** Added consistent restrictions to DIDs profile and trust registry profile logos.

### Tasks

**\[DCKA-2771] \[DCKA-2773] \[DCKA-2787] \[DCKA-2794]** Added OID4VCI API routes to authorize and issue credentials; create a credential offer; create a verification template, submit verification proof and presentation.

**\[DCKA-2790]** Submit webhook on proof request received from the holder.

**\[DCKA-2791]** Support JWT-VC verification and fix schema validation.

**\[DCKA-2793]** Support for default JWT paths in the builder in Dock Certs.

## v.1.38.0 August 07

This release includes updated support for the OpenID4VC implementors draft (both issuance and presentation). To test this, we added a page to our bank demo <https://bank-demo.dock.io/openid> that uses OpenID rather than our default DIDComm credential exchange. We confirmed that we can issue into the Mattr Wallet and the Sphereon wallet, but those wallets don't seem to have support for OID4VP. We'll publish additional guidance after we complete more interoperability testing.

### Story

**\[DCKA-2495]** Added monetizable credential functionality to the bank demo

### Bug fixes

* **\[DCKA-2750]** Allowing to add a schema to an ecosystem without assigning any participants to it.
* **\[DCKA-2775]** Schema prices will load when editing a verification template.

### Tasks

* **\[DCKA-2761]** Ran tests on OpenID implementation to prepare for updates.
* **\[DCKA-2776]** API issuance of OpenID for VC implementation with existing wallet client .
* **\[DCKA-2352]** Participants are required to accept an invitation to join an ecosystem, when invited by modifying the on-chain trust registry directly.

##


# Release notes September 2024

## v1.43.0 September 30

### Bug fixes

DCKA-2907 Fixed an error that ocured when issuing credentials with new DIDs on testnet.

### New features

DCKA-2566 Updated OpenAPI documentation for Schemas.

DCKA-2712 Added verification status to the billing report.

DCKA-2819 Deprecated sr25519 and secp256k1 key formats from the Dock API.

DCKA-2823 Expanded the trial subscription by allow users to have 3 team members in their trial.

DCKA-2828 Allowed OpenID pre-authed flow to bypass authorize route when appropriate.

DCKA-2829 Added verification of more credential options for the OpenID issuer setup to ensure easier setup.

DCKA-2835 Deprecated the ability to createnew StatusList2017 revocation registries.

## v1.42.0 September 13

### New features

Added ability to verify test mobile drivers licenses.

DCKA-2756 Added support for requesting mDL verification QR and verify presentation in the API

DCKA-2757 Added the ability to create a verification request for an mDL in Certs

DCKA-2758 Added the ability to view mDL verification data in Certs

DCKA-2759 Added an indication of accepted credential types into verification templates in Certs

## v1.40.1 September 4

### Bug fixes

**\[DCKA-2812]** Fixed the did:polygonid creation in Dock Certs and API


# Release notes October 2024

## v1.44.0 October 17

### Updates and New Features

DCKA-2034 Removed the icon on Publish button when creating a credential template.

DCKA-2821 Deprecated the legacy revocation registry format CredentialStatusList2017.

DCKA-2831 Updated to a better credential contents storage solution.

DCKA-2834 Published OID4VCI and OID4VP developer guide.

DCKA-2888 Removed legacy presentations routes from the API.


# Release notes November 2024

## v1.47.0 November 21

### Updates and new features

DCKA-2748 Updated ecosystems "View schema" menu item to show the credential schema.

DCKA-2789 Implemented the updated credential and blockchain SDKs.

### Bug fixes

DCKA-2944 Fixed verification failing when verifying a ZKP date range attribute.

## v1.46.0 November 13

### Updates and new features

DCKA-94 Credential view table will show the Issuer profile name instead of the DID

DCKA-2452 In order to better track API keys in Certs, a description or alias field was added.

## v1.45.0 November 1

### Updates and new features

DCKA-2166 Users will be able to filter their credential view table by Credential ID, Issue date, Type (schema used) and subject reference.

DCKA-2453 Made the width of table columns in Certs adjustable for easier management.

DCKA-2913 Deprecated anchoring routes and old revocation registries support

### Bug fixes

DCKA-2928 Fixed the API Server error when using GET/dids/{did}/ecosystems endpoint


# Release notes December 2024

## v1.50.0 December 17

Rebrand from Dock to Truvera and support for did:cheqd.

### Updates and new features

DCKA-3000 Added support for arrays data type in credential schemas.

DCKA-2954 API Accumulator support for cheqd

DCKA-3026 Adding an alias to API key improves the usability

### Bug fixes

DCKA-3029 Fixed an error when some attributes were not visible on the webview and the wallet giving the error "input.descriptor\[0]"

## v1.49.0 December 12

### Updates and new features

DCKA-2992 Updated the API to fix "Unknown type for key in schema: date" error.

### Bug fixes

DCKA-2969 Fixed an issue with exporting DIDs that are on cheqd blockchain.

## v1.48.0 December 9

### Updates and new features

Cheqd blockchain support (alpha testers only)

DCKA-2914 Add cheqd as a DID method in Certs

DCKA-2955 API StatusListCredential support for cheqd

DCKA-2956 API TrustRegistry support for cheqd

### Bug fixes

DCKA-2986 Fixed an error that occured, when trying to verify only a date range attribute in a ZKP credential.


# Truvera API

A complete solution for creating, managing and presenting Verifiable Credentials.

The Truvera API allows you to issue, verify and revoke verifiable credentials, manage DIDs and interact with a blockchain. Truvera integrates industry-leading standards for verifiable credentials, allowing it to interoperate with other identity technologies. We provide a range of open-source software on [GitHub](https://github.com/docknetwork) that can be used alongside the API.

Primary features include:

* Easily issue, verify, manage, and revoke/unrevoke verifiable credentials.
* Create and manage decentralized identifiers (DIDs).
* Create and assign schemas to credentials for compliance.
* Work seamlessly across platforms with Truvera's standards-compliant, interoperable solutions.
* Create a network of trusted issuers and verifiers using Ecosystem Tools.
* Motivate issuers by enabling credential monetization.


# Getting started

## Architecture style

Truvera is built using a [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) architecture. Our API follows common patterns including standard HTTP header authentication and standard HTTP response codes. It accepts form-encoded request bodies and delivers JSON-encoded responses.

HTTPS is required for all API requests. Requests performed via plain HTTP will be rejected. API requests that do not include authentication will also fail. JSON requests should typically be encoded as UTF-8.

## Terminology

Understanding key terminology in Truvera will help you to use the API:

<table><thead><tr><th width="140">Terminology</th><th>Description</th></tr></thead><tbody><tr><td>DID</td><td>Decentralized Identifiers (DIDs) are identifiers that enable verifiable, decentralized digital identity. A DID refers to any subject (e.g., a person, organization, thing, data model, abstract entity, etc.) as determined by the controller of the DID. For more information, please refer to the <a href="https://www.w3.org/TR/did/">W3C standard</a> or <a href="https://docknetwork.github.io/sdk/tutorials/concepts_did.html">Credential SDK docs</a>.</td></tr><tr><td>Verifiable Credential</td><td>A verifiable credential is a specific way to express a set of claims made by an issuer so that it is tamper-resistant and can be delivered to a verifier via a wallet in control of the data subject. For more information, pleases refer to the <a href="https://www.w3.org/TR/vc-data-model/">W3C standard</a>.</td></tr><tr><td>Data Schema</td><td>The structure that describes the logical view of the data. It is useful to enforce a specific structure on a collection of data like a verifiable credential.</td></tr><tr><td>Schema</td><td>The list of attributes and structure of a credential that is used to create a verifiable credential of a specific type. It does not contain any cryptographic material and is shareable among issuers.</td></tr><tr><td>Registries</td><td>A reference to a unique credential in context of a process for handling revocation of that credential type.</td></tr><tr><td>Blob</td><td>Blob stands for Binary Large OBject. It is a collection of binary data stored as a single entity. The schemas are identified and retrieved by their unique blob id, which is a 32-byte long hex string.</td></tr><tr><td>DID Resolver</td><td>The tool that initiates the process of learning the DID document.</td></tr></tbody></table>

## Asynchronous responses

When possible, calling the API will immediately return the desired result in a synchronous response. When the result of an operation may be delayed, an asynchronous pattern is used to close the connection and avoid blocking system resources.

Calls that are asynchronous due to an interaction with another party ([such as requesting a proof presentation from a credential holder](/truvera-api/presentations/proof-requests)) will return a resource identifier that will be updated as the resource is processed through its workflow. Calls that are asynchronous due to a dependency on an external system (such as a blockchain) will trigger [a job to be queued](/truvera-api/jobs).

These operations will provide an immediate response to indicate whether a request was accepted for processing, but the result must be obtained asynchronously using one of the methods below. For ease of integration, we recommend getting your flow to work using polling and then switching to webhooks as you prepare for production usage.

### Asynchronous polling

A call may create a resource with a unique identifier, which can then be checked for updates. System resources can be unblocked by polling for the response in a background thread. Polling can also be done by a proxy behind a white-labeled API.

### Asynchronous webhook responses

[By registering a webhook](/truvera-api/webhooks), Truvera can asynchronously provide your integration with data when it is available—thereby reducing the load of repeated polling. The webhook response will confirm that an event occurred and provide you with key information about the event. If additional details are needed, the webhook response contains a resource identifier that you can use to call back the same API you would use for polling.

## Prerequisites

You must have an account and acquire your credentials (API keys) before accessing the Truvera API. You can register an account and generate a key in your [Truvera Workspace](https://truvera.io/keys) dashboard.

{% hint style="warning" %}
Keep in mind that your API keys should be kept private, so keep them safe! Do not post your private API keys on GitHub, in client-side code, or anywhere else that is publicly available.
{% endhint %}

We generally recommend configuring your solution in the [Truvera Workspace](/truvera-workspace), as it provides an easy to use interface for managing organization profiles, creating schemas, setting up verification templates, and administering ecosystems. You can even manually issue and verify through the web interface. When creating schemas and verification templates, you can download JSON that can then be used to complete the same action via the API.

We also recommend using the [Truvera Wallet](/credential-wallet/truvera-mobile-wallet) to hold and present your credentials while you are testing the API. Once you have your basic flow working, you can then customize the holder's wallet experience using the [Truvera Wallet SDK](/credential-wallet/wallet-sdk).

## Endpoints

Truvera provides two endpoints based on which mode was selected when creating your API key. By default, trial users only have access to Test data. Paid subscribers can create production API keys by switching the **test mode** toggle in Truvera Workspace in the top right next to your avatar icon. When in **test mode** you will see only testnet transactions, API keys, webhooks etc.

It should be noted that in **test mode** your used transaction count **will not increase or hit monthly limits** allowing for sandboxing on our test network.

* For production mode, use the endpoint: <https://api.truvera.io>
* For test mode, use the endpoint: <https://api-testnet.truvera.io>

{% hint style="warning" %}
Any transaction you perform in **test mode** cannot be used for **production**. This means that, for example, any DID created in **test mode** will not work for issuing or verification in **production**.
{% endhint %}

{% hint style="warning" %}
**Test mode** will be subject to data resets periodically, so the DIDs, etc. that you create there should not be expected to be permanent.
{% endhint %}

## Authentication

Truvera uses API keys to authenticate requests. You can obtain an API key by signing into [Truvera Workspace](https://truvera.io/). Once a key has been generated, it should be included in **all** request using dual-header authentication as below:

```
DOCK-API-TOKEN: <API_KEY>
Authorization: Bearer <API_KEY>
```

When you generate an API key, you may include a list of whitelisted IP's that can use with that key.

## Rate limits

We allow you to make up to 200 requests in a 2 minute window (avg 100 reqs/min or 1.6 reqs/second). If you exceed beyond that, you will receive a 429 Too Many Requests response and have to wait up to a minute for the next request depending on when you hit the limit. If you require higher rate limits, please [contact us](/support).

## Error handling

The Truvera API uses standard HTTP response codes to indicate if an API request was successful or unsuccessful.

The table below shows the most frequent HTTP error messages:

<table><thead><tr><th width="101">Code</th><th>Meaning</th></tr></thead><tbody><tr><td>400</td><td>Bad Request — Your request was rejected (e.g., missing mandatory field).</td></tr><tr><td>402</td><td>Payment required — Transaction limit reached or upgrade required to proceed</td></tr><tr><td>401</td><td>Unauthorized — Do not own resource or have an invalid API key in the header.</td></tr><tr><td>404</td><td>Not Found — The resource that you're trying to interact with could not be found on the server.</td></tr><tr><td>405</td><td>Method Not Allowed — The requested method does not exist in the API spec. Please check the {did} value and ensure that it's not empty/blank.</td></tr><tr><td>429</td><td>Too Many Requests — You sent too many requests. Please try to reduce the number of requests.</td></tr><tr><td>500</td><td>Server Errors — Something has gone wrong on the server. Contact us if this keeps happening.</td></tr></tbody></table>

## Development Tips

The Truvera Workspace is built using the REST API, so the network request viewer in your browser's developer tools will show the JSON used in requests and responses which you can then copy to your API calls. You can also examine errors in the browser developer console to get more insight into what is happening.


# Webhooks

Truvera allows you to register a webhook for [asynchronous integration with the API](/truvera-api/getting-started). When the below listed events occur within the API, the event will be published to the registered webhook URLs that are configured to receive the notification. You also need to select **at least one** of the webhook events from Truvera Workspace to trigger the data exchange.

The webhook response will confirm that an event occurred and provide key information about the event including the relevant resource identifier. Additional information can be obtained by querying the appropriate endpoint for that resource to receive additional details. This pattern helps minimize the data that would be seen by a 3rd party webhook provider.

## Step-by-step

1. Start by getting your flow working with polling. That will allow you to troubleshoot your usage of the Truvera API.
2. Then configure your webhook receiver as appropriate for your deployment environment.
3. Next, configure the webhook in Truvera by following these steps:

   1. Go to **Webhooks** in Truvera Workspace.
   2. Click **Add Endpoint**.
   3. Fill in the **Endpoint URL** and select **Endpoint Events** for the webhook events.
   4. Click **Create Webhook**.
   5. Once the webhook is created you will see a secret token. This token is sent in the webook POST request for you to validate that the webhook came from Truvera.

   You can subscribe to all events by clicking **Receive All** next to **Endpoint Events.**
4. When the webhook triggers, your code should first validate the secret token.
5. Then check the "event" attribute of the payload to determine the type of event that occurred.
6. For many events, all the information you need to complete your workflow is contained in the payload. If additional information is needed, you should call the appropriate API endpoint using the same process as is used when polling.

## Webhook events

You can configure the following events to trigger the HTTP request to send the data to your application.

### credential\_create

This event indicates a credential has been created. It will fire when a credential has been created.

<details>

<summary>SAMPLE JSON PAYLOAD</summary>

```json
{
  "token": "4A_Z0fYD19q1qKZ03qAfB0zTu8XYuLPpGk0oHfP8OrvGGDi5Jz8C86F6EVz8Wd2c",
  "event": "credential_create",
  "data": {
    "id": "http://example.com/39",
    "signingOps": 1,
    "byteSize": 727,
    "key": "did:dock:5DhSFTFJwD6bFdrPdTibhxQypDruZkBGeWs1p34FS87ko5Vy#5GsBC74MW9DxHkFUYDVGPnbtioEaFgPgkdytQU3cRTQcHJCz",
    "credential": {
      "@context": [
        "https://www.w3.org/2018/credentials/v1",
        "https://www.w3.org/2018/credentials/examples/v1"
      ],
      "id": "https://creds.dock.io/f087cbfabc90f8b996971ba47598e82b1a03523cb9460217ad58a819cd9c09eb",
      "type": [
        "VerifiableCredential"
      ],
      "credentialSubject": {
        "id": "did:dock:5DhSFTFJwD6bFdrPdTibhxQypDruZkBGeWs1p34FS87ko5Vy"
      },
      "issuanceDate": "2019-08-24T14:15:22Z",
      "expirationDate": "2019-08-24T14:15:22Z",
      "proof": {
        "type": "Sr25519Signature2020",
        "created": "2021-11-23T03:16:47Z",
        "verificationMethod": "did:dock:5DhSFTFJwD6bFdrPdTibhxQypDruZkBGeWs1p34FS87ko5Vy#keys-1",
        "proofPurpose": "assertionMethod",
        "proofValue": "z4jUYjc4CyQSfVCivjjTpngjg9TsSL5GkdNesqQFBxwtZwgruophe7xaAzFMSx2gZt4CmXhhhWz4aEyA9wtpqwhdn"
      },
      "issuer": {
        "id": "did:dock:5DhSFTFJwD6bFdrPdTibhxQypDruZkBGeWs1p34FS87ko5Vy",
        "name": "Issuer Name"
      }
    }
  }
}
```

</details>

### credential\_issued

This event indicates a credential has been issued. It will fire when a credential has been issued.

<details>

<summary>SAMPLE JSON PAYLOAD</summary>

```json
{
  "token": "4A_Z0fYD19q1qKZ03qAfB0zTu8XYuLPpGk0oHfP8OrvGGDi5Jz8C86F6EVz8Wd2c",
  "event": "credential_issued",
  "data": {
    "id": "http://example.com/39",
    "signingOps": 1,
    "byteSize": 691,
    "key": "did:dock:5DhSFTFJwD6bFdrPdTibhxQypDruZkBGeWs1p34FS87ko5Vy#5GsBC74MW9DxHkFUYDVGPnbtioEaFgPgkdytQU3cRTQcHJCz",
    "credential": {
      "@context": [
        "https://www.w3.org/2018/credentials/v1",
        "https://www.w3.org/2018/credentials/examples/v1"
      ],
      "id": "https://creds.dock.io/f087cbfabc90f8b996971ba47598e82b1a03523cb9460217ad58a819cd9c09eb",
      "type": [
        "VerifiableCredential"
      ],
      "credentialSubject": {
        "id": "did:dock:5DhSFTFJwD6bFdrPdTibhxQypDruZkBGeWs1p34FS87ko5Vy"
      },
      "issuanceDate": "2021-11-23T03:16:25.321Z",
      "proof": {
        "type": "Sr25519Signature2020",
        "created": "2021-11-23T03:16:25Z",
        "verificationMethod": "did:dock:5DhSFTFJwD6bFdrPdTibhxQypDruZkBGeWs1p34FS87ko5Vy#keys-1",
        "proofPurpose": "assertionMethod",
        "proofValue": "z41DNxuUzSvKz68L2YkXehR3nQ9PWoAfj6zk44gUzFXKK7pd2zEQByYAUGGg5TT2cZCxiYAmg49NGMX8tRLyf9W1G"
      },
      "issuer": {
        "id": "did:dock:5DhSFTFJwD6bFdrPdTibhxQypDruZkBGeWs1p34FS87ko5Vy",
        "name": "Issuer Name"
      }
    }
  }
}
```

</details>

### credential\_revoke

This event indicates a credential has been revoked. It will fire when a credential has been revoked.

<details>

<summary>SAMPLE JSON PAYLOAD</summary>

```json
{
  "token": "4A_Z0fYD19q1qKZ03qAfB0zTu8XYuLPpGk0oHfP8OrvGGDi5Jz8C86F6EVz8Wd2c",
  "event": "credential_revoke",
  "data": {
    "status": "finalized",
    "encodedTx": "0xa902040a0153b52f6bac3d812853d8aad9c94eb98b4a5dd632c5bf805dc4140965c753641e04aff1aa6770d43d684690c0ad679a8608d5b7576feb3fdc1d6712decf73ca44efd3ec3b0004483fc667eb8a63f8e040bb91cd23f6c650fb668d0152390a026620d05c5168ed00787db3a6322a4d81ab64848fdb4ec7f76404ad2360075b64e2de1c3d4bb0f2624d4684d073e528367a2dba2379254a50be816afa7eb731fa4f4807f1c6b4548f",
    "result": {
      "InBlock": "0x759314aa18d741335ac809ca2d877aed0a00375c3ba4a7dfc398d80dbc7bf2d5"
    }
  }
}
```

</details>

### credential\_unrevoke

This event indicates a credential has been unrevoked. It will fire when a credential has been unrevoked.

<details>

<summary>SAMPLE JSON PAYLOAD</summary>

```json
{
  "token": "4A_Z0fYD19q1qKZ03qAfB0zTu8XYuLPpGk0oHfP8OrvGGDi5Jz8C86F6EVz8Wd2c",
  "event": "credential_unrevoke",
  "data": {
    "status": "finalized",
    "encodedTx": "0xa902040a0253b52f6bac3d812853d8aad9c94eb98b4a5dd632c5bf805dc4140965c753641e04aff1aa6770d43d684690c0ad679a8608d5b7576feb3fdc1d6712decf73ca44ef45ed3b0004483fc667eb8a63f8e040bb91cd23f6c650fb668d0152390a026620d05c5168ed0052ced1926bc978029cf9ebe9107450961ca8f0aed21033b61087a901271e1451c67a1f8feb7851f8dda0913223fc3bb5a26b9550014dccce61b5392e9a5e3181",
    "result": {
      "InBlock": "0x4279f477c280d1721efaee8a3ee621f3d96068fe978811db73d4ab27fecc687a"
    }
  }
}
```

</details>

### did\_create

This event indicates a DID has been created. It will fire when a DID has been created.

<details>

<summary>SAMPLE JSON PAYLOAD</summary>

```json
{
  "token": "4A_Z0fYD19q1qKZ03qAfB0zTu8XYuLPpGk0oHfP8OrvGGDi5Jz8C86F6EVz8Wd2c",
  "event": "did_create",
  "data": {
    "status": "finalized",
    "encodedTx": "0x91010409004e0d07d7121cbfb78be48fea337f7afd6f90aa233e33c17ab8137c4873c7da924e0d07d7121cbfb78be48fea337f7afd6f90aa233e33c17ab8137c4873c7da920012e604ac480aa06981c9b5dae4fc0e0bd8961fd858584e0a53f8a66e9b5e1648",
    "result": {
      "InBlock": "0xe5f17466a3c4b2ac3f455d923367e6e2baf9970583c2ed56299280d3a269a471"
    }
  }
}
```

</details>

### did\_update\_key

This event indicates a `keyType` value within the DID has been updated. It will fire when the `keyType` value has been updated.

<details>

<summary>SAMPLE JSON PAYLOAD</summary>

```json
{
  "token": "4A_Z0fYD19q1qKZ03qAfB0zTu8XYuLPpGk0oHfP8OrvGGDi5Jz8C86F6EVz8Wd2c",
  "event": "did_update_key",
  "data": {
    "status": "finalized",
    "encodedTx": "0xa902040901c7f54544fc24f652c4bfd1eded6e26d4400cd2cc91f130f85076aee6f1f6efb2001eabe8649baa2de3ee613dd488a433f743ed36854843e2aef4317a924118487201483fc667eb8a63f8e040bb91cd23f6c650fb668d0152390a026620d05c5168ed15293c000030af292a54c9ac95c999dd746ae61b6f35e1b8e610a637ef7d8710c093826e6d7a01d665bbcc8e4825830711371dade0f78b604b39fa864e92911ed030e15181",
    "result": {
      "InBlock": "0x8c876bd6fe0dbbadc91ed04a5d9f811dca02850f95dda409e558034df24177bb"
    }
  }
}
```

</details>

### did\_update\_controller

This event indicates a `controller` value within the DID has been updated. It will fire when the `controller` value has been updated.

When you update both `controller` and `keyType`, you will receive `did_update_controller` event notification too on your webhook since updating `controller` value will update the `keyType` value.

<details>

<summary>SAMPLE JSON PAYLOAD</summary>

```json
{
  "token": "4A_Z0fYD19q1qKZ03qAfB0zTu8XYuLPpGk0oHfP8OrvGGDi5Jz8C86F6EVz8Wd2c",
  "event": "did_update_controller",
  "data": {
    "status": "finalized",
    "encodedTx": "0xad02040901c81cd739fdd090d889280f04ddec47cad8240290e974319eaf1a7d7f10213c500203d5dc1a348b80aa06673fc36b8d1c0405125ad61d90c43e157815cc0779a8696801483fc667eb8a63f8e040bb91cd23f6c650fb668d0152390a026620d05c5168ed822b3c000139a87a45eaf9ada41c964bada887ebffa7bf34d66aec88821fb7a6d2177d634e83ab7a45f685835add00cebcc96a8c572e2833ad01d6dcacb0f72fb9bf80fa0a",
    "result": {
      "InBlock": "0x47c6640633a8a22df1de8fdc8e80f36dc403e735975e6f14d1a30419a18a6abd"
    }
  }
}
```

</details>

### did\_delete

This event indicates a DID has been deleted. It will fire when a DID has been deleted.

<details>

<summary>SAMPLE JSON PAYLOAD</summary>

```json
{
  "token": "4A_Z0fYD19q1qKZ03qAfB0zTu8XYuLPpGk0oHfP8OrvGGDi5Jz8C86F6EVz8Wd2c",
  "event": "did_delete",
  "data": {
    "status": "finalized",
    "encodedTx": "0xa1010409024e0d07d7121cbfb78be48fea337f7afd6f90aa233e33c17ab8137c4873c7da92c0ea3b000008dcdfb22efd01604ca38facdb6c1086f2d76c2a36425f293e4c687e48f0ea295e02162e8af53f334544676bbf906f12f60d36a0b42dad89e169bc2816d68a85",
    "result": {
      "InBlock": "0x588b2170d114f68f47d697b92c4c2184db26deada7e114f205a6bb95a157a3bd"
    }
  }
}
```

</details>

### registry\_create

This event indicates a registry has been created. It will fire when a registry has been created.

<details>

<summary>SAMPLE JSON PAYLOAD</summary>

```json
{
  "token": "4A_Z0fYD19q1qKZ03qAfB0zTu8XYuLPpGk0oHfP8OrvGGDi5Jz8C86F6EVz8Wd2c",
  "event": "registry_create",
  "data": {
    "status": "finalized",
    "encodedTx": "0x1901040a0035cbd5b17285e74b86b198543f712c03c99b75d7e2ed82923fa1fde7f1129ef40004483fc667eb8a63f8e040bb91cd23f6c650fb668d0152390a026620d05c5168ed00",
    "result": {
      "InBlock": "0x2407aa20e16ae915698888ed84f41d1bc06d3733ed17c89041b897e91ecf8fac"
    }
  }
}
```

</details>

### registry\_delete

This event indicates a registry has been deleted. It will fire when a registry has been deleted.

<details>

<summary>SAMPLE JSON PAYLOAD</summary>

```json
{
  "token": "4A_Z0fYD19q1qKZ03qAfB0zTu8XYuLPpGk0oHfP8OrvGGDi5Jz8C86F6EVz8Wd2c",
  "event": "registry_delete",
  "data": {
    "status": "finalized",
    "encodedTx": "0x2502040a0335cbd5b17285e74b86b198543f712c03c99b75d7e2ed82923fa1fde7f1129ef443ec3b0004483fc667eb8a63f8e040bb91cd23f6c650fb668d0152390a026620d05c5168ed00405a766d239405e6e3c63104581168cbb831e32299f7af72e39b5e8774631674f41595542249599a454ce957374be99fc061ec40200d380a8df1776e4417fa82",
    "result": {
      "InBlock": "0x4c58ebd08823a2dd5d776eaed526bfeddacf988d79c8e85cd807e8765622de7a"
    }
  }
}
```

</details>

### schema\_create

This event indicates a schema has been created. It will fire when a schema has been created.

<details>

<summary>SAMPLE JSON PAYLOAD</summary>

```json
{
  "token": "4A_Z0fYD19q1qKZ03qAfB0zTu8XYuLPpGk0oHfP8OrvGGDi5Jz8C86F6EVz8Wd2c",
  "event": "schema_create",
  "data": {
    "status": "finalized",
    "encodedTx": "0xa106040b00e1420661c333988c024f0a4bd3ea4ed0e75773247a369419acdaa67447c22ca489047b2224736368656d61223a22687474703a2f2f6a736f6e2d736368656d612e6f72672f64726166742d30372f736368656d6123222c226164646974696f6e616c50726f70657274696573223a66616c73652c226465736372697074696f6e223a22446f636b20536368656d61204578616d706c65222c2270726f70657274696573223a7b22616c756d6e694f66223a7b2274797065223a22737472696e67227d2c22656d61696c41646472657373223a7b22666f726d6174223a22656d61696c222c2274797065223a22737472696e67227d2c226964223a7b2274797065223a22737472696e67227d7d2c227265717569726564223a5b22656d61696c41646472657373222c22616c756d6e694f66225d2c2274797065223a226f626a656374227d483fc667eb8a63f8e040bb91cd23f6c650fb668d0152390a026620d05c5168ed00c2d11f1a68160f1a7d926c7c89a937866d70fdd0b5d350a6b2be88ad099a8776c6518e1d798553f596baff8d3be36d0172860e7a9b1368019339c7da05bf3485",
    "result": {
      "InBlock": "0x8b7042e52223334929e1cb2507e9be5b35014573dbe693bbcda2952f6254934f"
    }
  }
}
```

</details>

### proof\_submitted

This event indicates that a proof has been submitted. Minimal data is included in the event but the details can be retrieved using the proof\_request API.

<details>

<summary>SAMPLE JSON PAYLOAD</summary>

```json
{
  "token": "15f2irRkZFz1tjOjGdA0cGh66abwd4ckC8pR2suxVIPt97yc_zDTQIiNkT20JqAm",
  "event": "proof_submitted",
  "data": {
    "id": "7fbbe582-66d6-4fbc-92f3-c13d9cf7975a",
    "verified": true
  }
}
```

</details>


# Webhooks API endpoints

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/webhooks" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/webhooks" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/webhooks/{id}" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/webhooks/{id}" method="patch" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/webhooks/{id}" method="delete" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Sample Postman collections

Download and use our [Postman Collections](https://github.com/docknetwork/knowledgebase-docs/tree/main/Postman_collections) to experiment with basic API flows:

* Download Postman [here](https://www.postman.com/downloads/).
* Download our [API collection here](https://github.com/docknetwork/knowledgebase-docs/tree/main/truvera-api/sample-postman-collections).
* Import Truvera Collection in Postman with our API collection that you have downloaded previously. For the detailed instructions to import the json file, please refer [here](https://learning.postman.com/docs/getting-started/importing-and-exporting-data/).
* Create a new environment in Postman. For the detailed instruction to create a new environment, please refer [here](https://learning.postman.com/docs/sending-requests/managing-environments/).
* In your new Postman environment, you need to create two new `ApiKey` and `BaseUrl` variables. Please refer [here](https://learning.postman.com/docs/sending-requests/variables/) for the instructions to set the new variables.
* Login to [Truvera Workspace](https://truvera.io/).
* In your Truvera Workspace dashboard, click **Create API key** on the keys page to generate the key, copy and save it (make sure the test mode toggle is on).
* In your Postman create a new environment and add a secret `Bearer` variable with your API key as values.
* Set `BaseUrl` initial and current values to <https://api-testnet.truvera.io>


# Issue-store-verify sample flow

This flow refers to Postman, but the general steps are the same however you use the API. The Issue Store Verify collection includes the scripts that automatically propagate results into the next request bodies when you follow the below steps.

Download the sample collection [here](https://github.com/docknetwork/knowledgebase-docs/blob/b03df61a74d26b6352779397ea6b0553bd62a76d/truvera-api/sample-postman-collections/Issue-Store-Verify%20flow).

To issue a credential and or a presentation on the holder's behalf, the following steps are required:

## 1. Create a DID

To create a new DID to issue with, go to **Create DID** and click **Send**. The `id` property denotes a job ID in the system that you can use to query for blockchain transaction status.

The Truvera API supports `did:cheqd` and `did:key` method creation.

<details>

<summary>Body</summary>

```json
{
"type": "cheqd"
}
```

</details>

<details>

<summary>200 Response</summary>

```json
{
    "did": "did:cheqd:5CvswSAkWbyn6iQdRtMiD8tUAQmpXBghPVs9JqK5cJTiAhJk",
    "controller": "did:cheqd:5CvswSAkWbyn6iQdRtMiD8tUAQmpXBghPVs9JqK5cJTiAhJk",
    "id": "23677",
    "data": {
        "did": "did:cheqd:5CvswSAkWbyn6iQdRtMiD8tUAQmpXBghPVs9JqK5cJTiAhJk",
        "controller": "did:cheqd:5CvswSAkWbyn6iQdRtMiD8tUAQmpXBghPVs9JqK5cJTiAhJk"
    }
}
```

</details>

{% hint style="info" %}
Creating a cheqd DID submits a transaction to the blockchain, this could take some time to process.
{% endhint %}

## 2. Update the DID

To add information about your Organization to the DID, e.g. name and logo, you will need to update the DID profile.

<details>

<summary>Body</summary>

```json
{
    "did":"did:cheqd:5CfsgqHioKCHNddVK9Y2Lu8fHQpvXh3nc9xVjLZNDqk1ZJ9z",
    "name": "Postman Test",
    "logo":""
}
```

</details>

<details>

<summary>200 Response</summary>

```json
{
    "did": "did:cheqd:5CfsgqHioKCHNddVK9Y2Lu8fHQpvXh3nc9xVjLZNDqk1ZJ9z",
    "name": "Postman Test",
    "logo": ""
}
```

</details>

{% hint style="info" %}
You only need to create a DID once and then you can issue many credentials with it. A subject/holder DID should not be the same as the issuer DID in a real world credential.
{% endhint %}

## 3. Create a schema

To issue a credential you will need to set a schema that will define which attributes need to be included in the credential.

<details>

<summary>Body</summary>

```json
{
      "$schema": "http://json-schema.org/schema",
      "name": "My Sample schema",
      "description": "description of my schema",
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "emailAddress": {
          "type": "string",
          "format": "email"
        },
        "textAttribute": {
          "type": "string"
        },
        "numberAttribute": {
          "type": "number"
        }
    },
      "required": [
        "emailAddress",
        "textAttribute",
        "numberAttribute"
      ],
      "additionalProperties": false
    }
```

</details>

<details>

<summary>200 Response</summary>

```json
{
    "id": "0",
    "data": {
        "schema": {
            "$schema": "http://json-schema.org/schema",
            "name": "My Sample schema",
            "description": "description of my schema",
            "type": "object",
            "properties": {
                "id": {
                    "type": "string"
                },
                "emailAddress": {
                    "type": "string",
                    "format": "email"
                },
                "textAttribute": {
                    "type": "string"
                },
                "numberAttribute": {
                    "type": "number"
                }
            },
            "required": [
                "emailAddress",
                "textAttribute",
                "numberAttribute"
            ],
            "additionalProperties": false,
            "$metadata": {
                "version": 1,
                "uris": {
                    "jsonSchema": "https://schema.truvera.io/MySampleSchema-V1-1737454702610.json",
                    "jsonLdContext": "https://schema.truvera.io/MySampleSchema-V1737454702610.json-ld"
                }
            },
            "$id": "https://schema.truvera.io/MySampleSchema-V1-1737454702610.json"
        },
        "id": "https://schema.truvera.io/MySampleSchema-V1-1737454702610.json",
        "uri": "https://schema.truvera.io/MySampleSchema-V1-1737454702610.json",
        "created": "2025-01-21T10:18:22.707Z",
        "isOwner": true,
        "ownerName": "",
        "ownerLogo": ""
    }
}
```

</details>

## 4. Issue a verifiable credential

To create a Verifiable Credential using the the new issuer DID, update Issuer with the DID you have created in the first step and add the required information to the attributes. It will return a Verifiable Credential that conforms to the W3C spec.

<details>

<summary>Body</summary>

````json
{
  "algorithm": "dockbbs",
  "recipientEmail":"agne@truvera.io",
  "distribute": true,
  "format": "jsonld",
  "credential": {
    "name": "My test credential",
    "description": "describing my test credential",
    "schema": "https://schema.truvera.io/MySampleSchema-V1-1736946620866.json",
    "type": [
      "SampleSchema"
    ],
    "subject": {
        "id":"1234",
        "emailAddress":"myemail@address.com",
        "textAttribute":"Some text",
        "numberAttribute":1
    },
    "issuer": "did:cheqd:testnet:64b9e235-7267-4ca3-a643-8123292466c6",
    "issuanceDate": "2025-01-21T11:03:35.610Z"
  }
}
```
````

</details>

<details>

<summary>200 Response</summary>

```json
{
    "@context": [
        "https://www.w3.org/2018/credentials/v1",
        "https://ld.dock.io/credentials/extensions-v1",
        "https://ld.dock.io/security/bbs23/v1",
        "https://schema.truvera.io/MySampleSchema-V1736946620866.json-ld"
    ],
    "id": "https://creds-testnet.truvera.io/649587d77d648a56c9be7a43668a6c4c44dfa7eee6fbfd9188cbf293616457a3",
    "type": [
        "VerifiableCredential",
        "SampleSchema"
    ],
    "credentialSubject": {
        "id": "1234",
        "emailAddress": "myemail@address.com",
        "textAttribute": "Some text",
        "numberAttribute": 1
    },
    "issuanceDate": "2025-01-21T11:03:35.610Z",
    "issuer": {
        "name": "My new DID",
        "logo": "https://placehold.co/400",
        "id": "did:cheqd:testnet:64b9e235-7267-4ca3-a643-8123292466c6"
    },
    "credentialSchema": {
        "id": "https://schema.truvera.io/MySampleSchema-V1-1736946620866.json",
        "type": "JsonSchemaValidator2018",
        "details": "{\"jsonSchema\":{\"$id\":\"https://schema.truvera.io/MySampleSchema-V1-1736946620866.json\",\"$schema\":\"http://json-schema.org/schema\",\"description\":\"description of my schema\",\"name\":\"My Sample schema\",\"properties\":{\"@context\":{\"type\":\"string\"},\"credentialSchema\":{\"properties\":{\"details\":{\"type\":\"string\"},\"id\":{\"type\":\"string\"},\"type\":{\"type\":\"string\"},\"version\":{\"type\":\"string\"}},\"type\":\"object\"},\"credentialSubject\":{\"additionalProperties\":false,\"properties\":{\"emailAddress\":{\"format\":\"email\",\"type\":\"string\"},\"id\":{\"type\":\"string\"},\"numberAttribute\":{\"type\":\"number\"},\"textAttribute\":{\"type\":\"string\"}},\"required\":[\"emailAddress\",\"textAttribute\",\"numberAttribute\"],\"type\":\"object\"},\"cryptoVersion\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"id\":{\"type\":\"string\"},\"issuanceDate\":{\"format\":\"date-time\",\"type\":\"string\"},\"issuer\":{\"properties\":{\"id\":{\"type\":\"string\"},\"logo\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"}},\"type\":\"object\"},\"name\":{\"type\":\"string\"},\"proof\":{\"properties\":{\"@context\":{\"items\":[{\"properties\":{\"proof\":{\"properties\":{\"@container\":{\"type\":\"string\"},\"@id\":{\"type\":\"string\"},\"@type\":{\"type\":\"string\"}},\"type\":\"object\"},\"sec\":{\"type\":\"string\"}},\"type\":\"object\"},{\"type\":\"string\"}],\"type\":\"array\"},\"created\":{\"format\":\"date-time\",\"type\":\"string\"},\"proofPurpose\":{\"type\":\"string\"},\"type\":{\"type\":\"string\"},\"verificationMethod\":{\"type\":\"string\"}},\"type\":\"object\"},\"type\":{\"type\":\"string\"}},\"type\":\"object\"},\"parsingOptions\":{\"defaultDecimalPlaces\":4,\"defaultMinimumDate\":-17592186044415,\"defaultMinimumInteger\":-4294967295,\"useDefaults\":true}}",
        "version": "0.4.0"
    },
    "name": "My test credential",
    "description": "describing my test credential",
    "cryptoVersion": "0.6.0",
    "proof": {
        "@context": [
            {
                "sec": "https://w3id.org/security#",
                "proof": {
                    "@id": "sec:proof",
                    "@type": "@id",
                    "@container": "@graph"
                }
            },
            "https://ld.dock.io/security/bbs23/v1"
        ],
        "type": "Bls12381BBSSignatureDock2023",
        "created": "2025-01-21T13:04:29Z",
        "verificationMethod": "did:cheqd:testnet:64b9e235-7267-4ca3-a643-8123292466c6#keys-2",
        "proofPurpose": "assertionMethod",
        "proofValue": "z2qWh3aNTysCYP8f41cj9jouGMHTKnag3vP4rfUJwXpQsnhjHgR6VfXYsj5TZAhNpG2jpkA4xTh1pDJjdsVgMdoXo8rdgAaNL5ovY36UqpsAC7V"
    }
}
```

</details>

## 5. Import the credential into the wallet

[Download Truvera wallet ](broken://pages/famFFWGPSQb2hQXJZLId)and click on the email link that was sent when issuing the credential. If not using the email distribution download the json of the credential an import it to the wallet using the json import option.

<div align="left"><figure><img src="/files/3wz3qu7UusJpX98sQT8F" alt="" width="188"><figcaption></figcaption></figure></div>

## 5. Create a proof template

To verify a credential you will need a verification template, that will indicate which attributes need to be fulfilled for successful verification. Verification templates can be reused.

<details>

<summary>Body</summary>

```json
{
  "name": "My Sample Proof Template",
  "request": {
    "name": "sample proof template",
    "purpose": "test my sample proof template",
    "input_descriptors": [
      {
        "id": "Credential 1",
            "name": "Verify Sample credential",
            "purpose": "verify sample credential",
            "constraints": {
            "fields": [
                {
                "path": [
                    "$.credentialSubject.emailAddress"
                ],
                "optional": false
            },
            {
                "path": [
                    "$.credentialSubject.numberAttribute"
                ],
                "filter": {
                    "type": "number",
                    "exclusiveMinimum": 0
                },
                "optional": false,
                "predicate": "required"
            },
            {
                "path": [
                    "$.credentialSchema.id"
                ],
                "filter": {
                    "const": "https://schema.truvera.io/MySampleSchema-V1-1736946620866.json"
                }
            },
            {
                "path": [
                    "$.credentialSubject.textAttribute"
                ]
            }
          ]
        }
      }
    ]
  }
}
```

</details>

<details>

<summary>200 Response</summary>

```json
{
    "id": "6cc6abd6-d47e-46c4-9ba1-3677a904237b",
    "did": "",
    "name": "My Sample Proof Template",
    "created": "2025-01-21T13:05:50.319Z",
    "updated": "2025-01-21T13:05:50.319Z",
    "request": {
        "name": "sample proof template",
        "purpose": "test my sample proof template",
        "input_descriptors": [
            {
                "id": "Credential 1",
                "name": "Verify Sample credential",
                "purpose": "verify sample credential",
                "constraints": {
                    "fields": [
                        {
                            "path": [
                                "$.credentialSubject.emailAddress"
                            ],
                            "optional": false
                        },
                        {
                            "path": [
                                "$.credentialSubject.numberAttribute"
                            ],
                            "filter": {
                                "type": "number",
                                "exclusiveMinimum": 0
                            },
                            "optional": false,
                            "predicate": "required"
                        },
                        {
                            "path": [
                                "$.credentialSchema.id"
                            ],
                            "filter": {
                                "const": "https://schema.truvera.io/MySampleSchema-V1-1736946620866.json"
                            }
                        },
                        {
                            "path": [
                                "$.credentialSubject.textAttribute"
                            ]
                        }
                    ]
                }
            }
        ]
    },
    "totalRequests": 0,
    "types": [
        "jsonld"
    ]
}
```

</details>

## 6. Create a proof request

Using the verification template created in the previous step in the endpoint **POST/proof-templates/{id}/** request a single use proof request will be created.

<details>

<summary>200 Response</summary>

```json
{
    "id": "86189366-c2a5-452e-b512-e052e26c84c1",
    "name": "My Sample Proof Template",
    "nonce": "6ef48e6c5f7a6f57eb92ab193f03fc8f",
    "did": "",
    "verified": false,
    "created": "2025-01-21T13:06:59.139Z",
    "updated": "2025-01-21T13:06:59.139Z",
    "signature": null,
    "presentation": {},
    "response_url": "https://api-testnet.truvera.io/proof-requests/86189366-c2a5-452e-b512-e052e26c84c1/send-presentation",
    "type": "proof-request",
    "qr": "https://creds-testnet.truvera.io/proof/86189366-c2a5-452e-b512-e052e26c84c1",
    "request": {
        "name": "sample proof template",
        "purpose": "test my sample proof template",
        "input_descriptors": [
            {
                "id": "Credential 1",
                "name": "Verify Sample credential",
                "purpose": "verify sample credential",
                "constraints": {
                    "fields": [
                        {
                            "path": [
                                "$.credentialSubject.emailAddress"
                            ],
                            "optional": false
                        },
                        {
                            "path": [
                                "$.credentialSubject.numberAttribute"
                            ],
                            "filter": {
                                "type": "number",
                                "exclusiveMinimum": 0
                            },
                            "optional": false,
                            "predicate": "required"
                        },
                        {
                            "path": [
                                "$.credentialSchema.id"
                            ],
                            "filter": {
                                "const": "https://schema.truvera.io/MySampleSchema-V1-1736946620866.json"
                            }
                        },
                        {
                            "path": [
                                "$.credentialSubject.textAttribute"
                            ]
                        }
                    ]
                }
            }
        ],
        "id": "86189366-c2a5-452e-b512-e052e26c84c1"
    },
    "types": [
        "jsonld"
    ]
}
```

</details>

{% hint style="info" %}
The proof request is one time use so that the information from the credential can be associated to a specific transaction event. However, the proof template can be used as many times as needed.

If there is a need to have a static QR code for multiple verification, a small service can be created to make proof requests from the verification template as and when needed.
{% endhint %}

## 7. Verify the presentation

Scan the QR code from the proof presentation using your wallet to verify the credential.


# Create ecosystems

Download a sample Postman collection [here](https://github.com/docknetwork/knowledgebase-docs/blob/b03df61a74d26b6352779397ea6b0553bd62a76d/truvera-api/sample-postman-collections/Ecosystem%20Tools%20\(Trust%20Registry\)).

Detailed instructions on how to create Ecosystems can be found [here](/truvera-api/ecosystem-tools/trust-registries).


# Issue monetizable credentials

Download a sample Postman collection [here](https://github.com/docknetwork/knowledgebase-docs/blob/b03df61a74d26b6352779397ea6b0553bd62a76d/truvera-api/sample-postman-collections/Issuing%20KVAC%20credentials).

Detailed instructions on how to issue monetizable credentials can be found [here](/truvera-api/kvac).


# Create sub-accounts

Download a sample Postman collection [here](https://github.com/docknetwork/knowledgebase-docs/blob/b03df61a74d26b6352779397ea6b0553bd62a76d/truvera-api/sample-postman-collections/Subaccounts).

Detailed instructions on how to create Sub-accounts can be found [here](/truvera-api/sub-accounts).


# Issue OpenID credentials

Download a sample Postman collection [here](https://github.com/docknetwork/knowledgebase-docs/blob/b03df61a74d26b6352779397ea6b0553bd62a76d/truvera-api/sample-postman-collections/OID4VC%20and%20OID4VP%20testing).

Detailed instructions on how to issue OpenID credentials can be found [here](/truvera-api/openid/openid-issuance-and-verification-integration-guide).


# Truvera Swagger UI

Truvera Swagger UI generates interactive API documentation to try out the API calls directly in any browser. Use our [Swagger UI](https://swagger-api.truvera.io/) to execute the API calls quickly:

* Login to [Truvera](https://truvera.io/).
* Make sure you are in **Test mode** to benefit from unlimited transactions.
* Create an API key by clicking **'Create API key'**. Copy and Save it.
* Use this key to **'Authorize'** into the Swagger UI.


# DIDs

DID stands for Decentralized IDentifiers. DIDs are meant to be globally unique identifiers that allow their owner to prove cryptographic control over them. A DID identifies any subject (e.g., a person, organization, thing, data model, abstract entity, etc.) that the controller of the DID decides that it identifies.

In Truvera, Decentralized Identifiers (DIDs) are created using the UUID v4 standard. This involves selecting a unique 128-bit identifier, typically represented as a 36-character hexadecimal string, along with an initial public key. Users have the flexibility to add and remove public keys associated with their DID document as needed. Additionally, the system supports various operations such as updating, deactivating, and listing all existing DIDs.

For a detailed example of the DIDs workflow. Please refer [here](https://github.com/docknetwork/dock-api-js/blob/main/workflows/didFlow.js).

## Create DID

A DID, a public key, and a controller are required to create a new DID. The controller is both the owner of the public key and a DID. The DID can be created using an auto-generated keypair, and the controller will be the same as the DID unless otherwise specified. The DID and public key have no cryptographic relation.

It is important to have a public key types that is supported by Truvera, the supported type of public key is `ed25519.`

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/dids" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Import DIDs

Import an already existing DID, possibly created in another platform, to take advantage of Truvera's advanced functions like ecosystems and monetized credentials.

## Import DIDs

> Import DIDs from JSON objects (\[DIDResolutionResponse]\(<https://www.w3.org/TR/did-resolution/>) or \[Universal Wallet]\(<https://w3c-ccg.github.io/universal-wallet-interop-spec/>) format). Supports both encrypted and plaintext wallet exports.

```json
{"openapi":"3.0.2","info":{"title":"Truvera API","version":"1"},"tags":[{"name":"dids","description":"Operations about DIDs"}],"servers":[{"url":"https://api-testnet.truvera.io","description":"Sandbox server (uses test data)"},{"url":"https://api.truvera.io","description":"Production server (uses live data)"}],"security":[{"bearerAuth":[]},{"accessToken":[]},{"nextAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"},"accessToken":{"type":"apiKey","in":"header","name":"DOCK-API-TOKEN"},"nextAuth":{"type":"apiKey","in":"header","name":"CERTS-TOKEN"}},"schemas":{"DID":{"description":"DID as fully qualified, typically. `did:cheqd:`","type":"string","minimum":32},"Error":{"description":"An API Error","type":"object","properties":{"status":{"type":"integer"},"type":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/dids/import":{"post":{"tags":["dids"],"summary":"Import DIDs","description":"Import DIDs from JSON objects ([DIDResolutionResponse](https://www.w3.org/TR/did-resolution/) or [Universal Wallet](https://w3c-ccg.github.io/universal-wallet-interop-spec/) format). Supports both encrypted and plaintext wallet exports.","requestBody":{"description":"Import data containing DIDs to import","required":true,"content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"description":"Import data - can be DIDResolutionResponse JSON-LD document, universal wallet export, or array of either","oneOf":[{"type":"string","description":"JSON string containing import data"},{"type":"object","description":"Single DID import object"},{"type":"array","description":"Array of DID import objects"}]},"password":{"type":"string","description":"Password for encrypted wallet imports","minLength":8}}}}}},"responses":{"200":{"description":"DIDs imported successfully","content":{"application/json":{"schema":{"type":"object","properties":{"imported":{"type":"integer","description":"Number of DIDs successfully imported"},"dids":{"type":"array","description":"Array of imported DID information","items":{"type":"object","properties":{"did":{"$ref":"#/components/schemas/DID"},"controller":{"$ref":"#/components/schemas/DID"},"keyCount":{"type":"integer","description":"Number of keys imported for this DID"},"profile":{"type":"object","description":"DID profile information if available","properties":{"name":{"type":"string"},"description":{"type":"string"}}}}}}}}}}},"400":{"description":"Invalid import data or missing required fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Payment required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"DID not found or cannot be resolved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## List DIDs

Return a list of all DIDs that your user account controls as fully resolved DID documents.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/dids" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Return ecosystems that DID participates in <a href="#list-dids-parameters" id="list-dids-parameters"></a>

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/dids/{did}/ecosystems" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Export DID

Exports the DID document and keys as an encrypted Universal Wallet JSON-LD document

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/dids/{did}/export" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Get DID

When a DID is provided in the path, the API will attempt to resolve that DID into a [DID document](https://www.w3.org/TR/did-core/#dfn-did-documents). This document contains the public keys and more information relating to that DID, check [the identity foundation did configuration](https://identity.foundation/.well-known/resources/did-configuration/) document to learn more.

The API supports resolving many DID methods, some examples are:

* did:cheqd:f48d2ace-4947-4cb7-8550-1cef3d63e651 - resolves through the cheqd blockchain
* did:key:z6MkjRagNiMu91DduvCvgEsqLZDVzrJzFrwahc4tXLt9DoHd- the public key is embedded in the DID

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/dids/{did}" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/dids/{did}/metadata" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Delete DID <a href="#list-dids-parameters" id="list-dids-parameters"></a>

Deletes a DID and its metadata from the blockchain and our platform. This will also delete the associated keypair from the key management system meaning that you cannot sign messages or credentials with it after this operation. The DID will no longer be able to be resolved. This operation is not reversible.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/dids/{did}" method="delete" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Profiles

Organization profiles are used to provide more context for an Issuer DID. Details about the issuer such as name and logo can be added using a organization profile. These details will be included in credentials that are issued by the DID.

## Create profile

The `did` and `name` fields are required to create a new Profile.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/profiles" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Get profile

When a DID is provided in the path, the API will retrieve the profile associated with that DID.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/profiles/{did}" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## List profiles

Return a list of all profiles that your user account controls.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/profiles" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Update profile

The update profile operation means that you can update the details of the profile. To do so, you need to provide a different value for **at least** one of `name`, `description` or `logo`.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/profiles/{did}" method="patch" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Delete profile

Deletes a profile from our platform. It does NOT delete the associated DID, nor revoke the credentials issued for the profile.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/profiles/{did}" method="delete" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Credentials

Credential issuance is the process of creating and signing a verifiable credential using the Truvera API. Verifiable Credentials are cryptographically secure and tamper-proof. They cannot be edited once issued, but [they can be revoked](#credential-issuance-revocation) and replaced with a new credential.

By default, the Truvera API issues a credential to a holder wallet without storing a copy—only credential metadata is stored. If the holder does not yet have a wallet, we recommend [provisioning a cloud wallet](/credential-wallet/wallet-sdk/cloud-wallet#step-4-create-a-new-wallet) for that holder and issuing the credential into it. If that is not appropriate for your use case, you can choose to persist the credential, in which case we will encrypt and store the credential for later retrieval using a password.

The following metadata is stored on each issuance:

* Credential ID property
* Credential size in bytes
* Issuer DID
* Issuance date

## Issue credential <a href="#issue-credentials" id="issue-credentials"></a>

Creates and issues a JSON-LD verifiable credential that conforms to the [W3C VCDM specification](https://www.w3.org/TR/vc-data-model/). The `type` values and subject properties must be represented by a schema URI in the `context` property. If you do not specify a `context` property, the API will automatically generate an embedded JSON-LD context based on the properties within your credential. You can read more about JSON-LD and contexts [here](https://json-ld.org/spec/latest/json-ld/#the-context).

{% hint style="info" %}
The `https://www.w3.org/2018/credentials/v1` context URI is always required and will be supplied by default at all times as mandated by the spec. If you pass a custom context, you must ensure that you define all the required JSON-LD terms. Please also note that the request format here is not the same as an issued verifiable credential. You can issue to multiple subjects per credential by passing an array of objects.
{% endhint %}

To sign a credential, an `issuer` must be supplied as either a fully qualified DID string or an object with at least an `id` property which is a fully qualified DID. (e.g: `did:dock:xyz`)

{% hint style="warning" %}
The `issuer` property **must** be a DID that you control with your Truvera account.
{% endhint %}

#### Creating an Example Payload <a href="#zero-knowledge-proofs" id="zero-knowledge-proofs"></a>

As mentioned in the [development tips](/truvera-api/getting-started#development-tips), you can create an example payload in Truvera Workspace by:

* Open the browser's dev tools
* Look at the network requests
* Manually issue a credential with the desired schema from the desired issuer profile
* In the section that shows HTTP headers, you can copy the Request URL ("Headers" in Google Chrome)
* In the section that shows the request preview, you can copy the text of the request (in Google Chrome, click on "Preview", then right-click on the top-level element "{,...}" and select "Copy object")

#### Zero Knowledge Proofs (ZKP) <a href="#zero-knowledge-proofs" id="zero-knowledge-proofs"></a>

Truvera credentials support [anonymous credentials](https://blog.dock.io/anonymous-credentials/) using Zero Knowledge Proofs and [Selective Disclosure](https://www.dock.io/post/selective-disclosure) by using the BBS2023 signing algorithm when issuing the credential. To enable this functionality, simply set the `algorithm` field in the request to `dockbbs`.

#### Credential distribution <a href="#credential-distribution" id="credential-distribution"></a>

As mentioned above, issued credentials are not stored and so should be issue directly into a holder wallet. Truvera's API has built in credential distribution on issuance, allowing you to send credentials directly to a holder's email and/or Truvera-compatible wallet. You can achieve this by supplying the `recipientEmail` field and `distribute: true` in your request. For DID distribution, simply set the `credentialSubject.id` property to the holder's DID.

In some use cases, you might choose to set the `persist` value to `true` and provide a `password` string which will store the credential contents encrypted on our platform.

#### Revocation <a href="#credential-issuance-revocation" id="credential-issuance-revocation"></a>

In order to support revocation the credential must be linked to a [revocation registry](/truvera-api/registries) at the time of issuance. To link the revocation registry to the credential set the `status` field in the [Credential](https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemacredential) body to the `registry.id` value.

{% hint style="info" %}
One time use credentials can be created, but automating the revocation based on tracking the verification of the credential ID and revoking the credential associated with it.
{% endhint %}

#### Expiration

An expiration date can be set when issuing a credential making the credential invalid after the assigned time. To check the expiration date for Zero Knowledge Proof credentials (using the dockbbs algorythm) the expiration date needs to be requested in the verification template otherwise due to the nature of zero knowledge proof it will not be disclosed automatically.

#### Attaching files

At the moment it is not possible to add a file to the credential itself. If a credential has to have a file associated with it, the file will need to be placed in public storage and the link to that location and a hash of the content should be added to the attributes of the credential.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/credentials" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## List credentials

When you issue a credential with us, persistent or not, we will store certain metadata about the credential to make it easier for you to reference. You can pull a list of credential metadata using this route. To return the content of a persisted credential, you should use the `GET /credentials/{id}` route.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/credentials" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Get credentials metadata and contents

When a credential has been persisted on our systems, you can fetch the credential data by supplying a credential ID and the password used at issuance to encrypt the credential.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/credentials/{id}" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Create request claims <a href="#request-claims" id="request-claims"></a>

Creates a request to gather certain claims and then issues the holder a credential after submission. The claims are user provided and type is based on the schema provided. This can be useful to catch a subject's DID without knowing it beforehand, name or other field. It should only be used when you do not already know this data or cannot find it by other means. There is a risk that a user may enter false data - so use it sparingly and not for fields that are important.

Typically, once the request has been created, you would show the holder the QR URL as an image or deep link for them to scan with a wallet and enter claims. After the holder submits the requested information the credential is automatically issued.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/credentials/request-claims" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Get request claims

Lists all created request claims that are open (the holders have not submitted the requested information).

{% openapi src="/files/KZcb8PtbmUBzZC5Hk5yz" path="/credentials/request-claims" method="get" %}
[openapi (1).yaml](https://815575130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWRMhdRsPkUzlSqCYzbgF%2Fuploads%2Fgit-blob-28711a41044e625f1c7f75546e4cb0168eb4a9b5%2Fopenapi%20\(1\).yaml?alt=media)
{% endopenapi %}

## Delete credential

A credential can have its metadata deleted, and if persisted the contents will also be deleted. Deleting a credential will remove any reference to it and its contents from our systems. This action cannot be undone. This action will not revoke or invalidate the credential in any way.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/credentials/{id}" method="delete" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Presentations

[Credential verification](/truvera-workspace/verify-credentials) consists of [defining a verification template / proof template](/truvera-api/presentations/proof-templates), using it to generate a [proof request](/truvera-api/presentations/proof-requests), delivering the proof request to a holder, receiving the proof response from the holder's wallet, and checking that response for consistency. The Truvera API automates many of these steps for you. The REST API does not contain functions to create a verifiable presentation, as that is done through the [Wallet SDK](/credential-wallet/wallet-sdk). The open source [Truvera Credential SDK](https://github.com/docknetwork/sdk) also contains the foundational capabilities needed to create proof presentations.

Our system supports the [DIF Presentation Exchange (PEX)](https://identity.foundation/presentation-exchange/) syntax for querying and filtering credentials.

## Examples

These are a few common examples of credential verification. More examples are in the documentation for [DIF Presentation Exchange](https://identity.foundation/presentation-exchange/#input-descriptor-extensions).

#### Require a numeric attribute to be within a range

A verifier might require that the holder have an income between $100,000 and $200,000 per year. This could be requested using the following `input_descriptor`

```
{
  path: ['$.credentialSubject.income.2022.total'],
  filter: {
    type: 'number',
    minimum: 100000,
    maximum: 200000
  },
}
```

#### Require a date attribute to be within a range

A verifier might require that the credential be issued after a certain date. In this example the verifier is requiring that the credential was issued between January 1, 2020 and December 31, 2020.

```
{
  path: ['$.issuanceDate'],
  filter: {
    "type": "string",
    "format": "date",
    "formatMinimum": "2020-01-01",
    "formatMaximum": "2020-12-31"
  },
}
```


# Proof templates

It is common to repeatedly request the same information from holders in subsequent proof requests. The Truvera API makes this easy by allowing you to create proof request templates to define the contents of the proof requests in a way that can be reused. The [Truvera Workspace](/truvera-workspace/verify-credentials) refers to proof request templates as "verification templates".

To verify a credential with Truvera, the verifier will need to create a proof template and generate a proof request to which the holder wallet will provide the verifiable presentation. Verifiable presentations can not be created via the REST API, as [the Truvera Wallet SDK](/credential-wallet/wallet-sdk) should be used.

## Create a proof template <a href="#create-proof-request" id="create-proof-request"></a>

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/proof-templates" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Get proof templates <a href="#create-proof-request" id="create-proof-request"></a>

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/proof-templates" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Get details of a specific proof template

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/proof-templates/{id}" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Update a proof template

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/proof-templates/{id}" method="patch" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Get proof requests from template

{% hint style="info" %}
Use the Verified parameter when needing to get only those verifications that were succsessful.
{% endhint %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/proof-templates/{id}/history" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Delete a proof template

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/proof-templates/{id}" method="delete" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Delete history for a proof template

This endpoint provides an irreversible deletion of all of proof template's verification history data.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/proof-templates/{id}/history" method="delete" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Delete a proof template

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/proof-templates/{id}" method="delete" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Proof requests

[Proof templates](/truvera-api/presentations/proof-templates) are used to create proof requests. When a proof request is created, you will receive a URL which needs to be delivered to a holder's wallet application either as a link (in the "response\_url" field) or displayed in a QR code for the wallet application to scan (conveniently pre-generated for you in the "qr" field). The holder's wallet will then generate a proof response and deliver it to the Truvera API which will check it for cryptographic correctness. [Like other asynchronous operations](/truvera-api/getting-started#integration-paradigms), you can receive the verification response along with the verified attributes either by polling or via a webhook.

To get a response by polling, check [the proof-request details](#get-the-details-of-an-existing-proof-request) for when the "verified" attribute equals "true". At that point, the "presentation" field will contain the verified attributes as a JSON list. If at any point the "verified" attribute equals "false", the response can be checked to determine the cause of the failure and appropriate next steps.

When creating a proof request, you can optionally provide a verifier DID in order for the holder to know that your verifier is on their trust-list, such as in an [ecosystem of trust](/truvera-workspace/ecosystem-tools).

## Create proof request <a href="#create-proof-request" id="create-proof-request"></a>

This route uses a template ID and takes the PEX request you defined there.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/proof-templates/{id}/request" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Create proof request <a href="#create-proof-request" id="create-proof-request"></a>

This route lets you create a standalone proof request without storing a verification template first.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/proof-requests" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Get all proof requests

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/proof-requests" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Get the details of an existing proof request

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/proof-requests/{id}" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Delete the proof request

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/proof-requests/{id}" method="delete" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Other proof endpoints

These endpoints are not used in the most common verification scenarios.

## Send a presentation to the proof request

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/proof-requests/{id}/send-presentation" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Get the proof request PEX definition

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/proof-requests/{id}/pex" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Registries

Revocation means deleting or updating a credential. Truvera's credential revocation is managed with a revocation registry.

There can be multiple registries on the chain, and each registry has a unique id. It is recommended that the revocation authority create a new registry for each credential type. Truvera Workspace allows you to create, delete, and revoke/unrevoke the credential. You can retrieve a specified registry as well as a list of all registries created by the user.

For a detailed example of the registry workflow. Please refer [here](https://github.com/docknetwork/dock-api-js/blob/main/workflows/registryFlow.js).

{% hint style="info" %}
If you want to revoke ZKP credentials, you must create a registry with type \`DockVBAccumulator2022\`. For revoking other credentials, you can use \`StatusList2021Entry\`.
{% endhint %}

## Create registry

To create a registry, you have to create a `policy` object for which a DID is needed. It is advised that the DID is registered on the chain first. Otherwise, someone can look at the registry and register the DID, thus gaining control of the registry.

Choosing the right revocation registry is essential. Here's a simplified overview of the available options:

* StatusList2021Entry
  * Only supports non-ZKP credentials.
  * Recommended for most users.
  * Collective Tracking: Manages all revocation entries together, making it less costly to revoke multiple credentials simultaneously.
  * W3C Compliant.
* DockVBAccumulator2022
  * Only supports ZKP credentials.
  * Utilizes an on-ledger accumulator for enhanced privacy.
  * Offers more privacy than the W3C Status List 2021.

CredentialStatusList2017 (Deprecated)

* Only supports non-ZKP credentials.
* Individual Tracking: Each entry is tracked separately, which means more ledger space is used for multiple entries.
* This registry is cost-effective for a single entry. However, managing several entries can be more expensive.
* Implements add-only policies.

### Parameters <a href="#create-registry-parameters" id="create-registry-parameters"></a>

<table data-full-width="false"><thead><tr><th width="119">Name</th><th width="82">In</th><th width="118">Type</th><th width="117">Required</th><th>Description</th></tr></thead><tbody><tr><td>addOnly</td><td>body</td><td>boolean</td><td>false</td><td>True/false options. The default value is "false".</td></tr><tr><td>policy</td><td>body</td><td>[<a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemadiddock">DIDDock</a>]</td><td>true</td><td>The DIDs which control this registry. You must own a DID listed here to use the registry. Only one policy supported as of now: <code>OneOf</code> DID in list.</td></tr><tr><td>type</td><td>body</td><td>string</td><td>false</td><td>Specifies which type of registry to create. Defaults to <code>StatusList2021Entry</code>.</td></tr></tbody></table>

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/registries" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## List registries

Return a list of all registries created by the user. The list is returned with the registry id and policy of the revocation registry.

{% hint style="info" %}
For now, only one policy is supported, and each registry is owned by a single DID.
{% endhint %}

### Parameters <a href="#list-dids-parameters" id="list-dids-parameters"></a>

<table data-full-width="false"><thead><tr><th width="116">Name</th><th width="94">In</th><th width="95">Type</th><th width="119">Required</th><th>Description</th></tr></thead><tbody><tr><td>offset</td><td>query</td><td>integer</td><td>false</td><td>How many items to offset by for pagination</td></tr><tr><td>limit</td><td>query</td><td>integer</td><td>false</td><td>How many items to return at one time (max 64)</td></tr></tbody></table>

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/registries" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Get registry

Get the details of an existing registry, such as policy, add-only status, when it was last updated, and controller(s). You need only supply the revocation registry id that was returned upon revocation registry creation.

### Parameters <a href="#get-registry-parameters" id="get-registry-parameters"></a>

<table data-full-width="false"><thead><tr><th width="100">Name</th><th width="88">In</th><th width="104">Type</th><th width="160">Required</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>path</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemahex32">Hex32</a></td><td>true</td><td>Revocation registry id.</td></tr></tbody></table>

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/registries/{id}" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Revoke or unrevoke a credential

Credential revocation is managed with on-chain revocation registries. To revoke a credential, its id (or hash of its id) must be added to the credential. It is advised to have one revocation registry per credential type. Revoking an already revoked credential has no effect.

Similar to the replay protection mechanism for DIDs, the last modified block number is kept for each registry, which is updated each time a credential is revoked or unrevoked. Unrevoking an unrevoked credential has no effect.

In this API, simply add Revoke/Unrevoke into the `action` parameter and input the desired credential ids.

### Parameters <a href="#revoke-unrevoke-credential-parameters" id="revoke-unrevoke-credential-parameters"></a>

<table data-full-width="false"><thead><tr><th width="147">Name</th><th width="89">In</th><th width="96">Type</th><th width="106">Required</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>path</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemahex32">Hex32</a></td><td>true</td><td>Revocation registry id.</td></tr><tr><td>action</td><td>body</td><td>string</td><td>false</td><td>The action taken, either revoke or unrevoke. The default value is "revoke"</td></tr><tr><td>credentialIds</td><td>body</td><td>array</td><td>true</td><td>The list of credential ids to act upon.</td></tr></tbody></table>

### Enumerated values

<table data-full-width="false"><thead><tr><th width="141">Parameter</th><th width="205">Value</th><th>Description</th></tr></thead><tbody><tr><td>action</td><td>revoke <strong>or</strong> unrevoke</td><td>Action to take on the registry.</td></tr></tbody></table>

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/registries/{id}" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Delete registry

A registry can be deleted, leading to all the corresponding revocation ids being deleted as well. This requires the signature from the owner, similar to the other updates.

### Parameters <a href="#delete-registry-parameters" id="delete-registry-parameters"></a>

<table data-full-width="false"><thead><tr><th width="105">Name</th><th width="85">In</th><th width="126">Type</th><th width="137">Required</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>path</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemahex32">Hex32</a></td><td>true</td><td>Revocation registry id.</td></tr></tbody></table>

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/registries/{id}" method="delete" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Revocation status

Credentials can be revoked or unrevoked, and as such they contain a revocation status so that verifiers/issuers can check if the credential is still valid. Once a revocation registry has been created and credentials issued with it, you can check the revocation status. Verifiers will do this automatically.

## Get revocation status

To check if an id is revoked or not, you can check its status with the registry id (`regId`) and revocation id (`revId`).

### Parameters <a href="#get-revocation-status-parameters" id="get-revocation-status-parameters"></a>

<table data-full-width="false"><thead><tr><th width="118">Name</th><th width="106">In</th><th width="117">Type</th><th width="130">Required</th><th>Description</th></tr></thead><tbody><tr><td>regId</td><td>path</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemahex32">Hex32</a></td><td>true</td><td>Revocation registry id.</td></tr><tr><td>revId</td><td>path</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemahex32">Hex32</a></td><td>true</td><td>Credential revocation id.</td></tr></tbody></table>

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/revocationStatus/{regId}/{revId}" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Get revocation status witness

The accumulator witness is utilized by the holder to generate a proof, which combines the witness with their revocation id associated with the credential id (`revId`) and the accumulator associated with the registry id (`regId`), allowing the verifier to validate the credential's status without directly accessing the revocation id on the blockchain.

### Parameters <a href="#get-revocation-status-parameters" id="get-revocation-status-parameters"></a>

<table><thead><tr><th width="113">Name</th><th width="93">In</th><th width="117">Type</th><th width="123">Required</th><th>Description</th></tr></thead><tbody><tr><td>regId</td><td>path</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemahex32">Hex32</a></td><td>true</td><td>Revocation registry id.</td></tr><tr><td>revId</td><td>path</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemahex32">Hex32</a></td><td>true</td><td>Credential revocation id.</td></tr></tbody></table>

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/revocationStatus/{regId}/{revId}/witness" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Credential schemas

Schemas are useful when enforcing a specific structure on a collection of data like a Verifiable Credential. Data Verification schemas, for example, are used to verify that the structure and contents of a Verifiable Credential conform to a published schema. On the other hand, Data Encoding schemas are used to map the contents of a Verifiable Credential to an alternative representation format, such as a binary format used in a zero-knowledge proof.

Truvera credential schemas are using json schema format and should follow this structure <https://json-schema.org/understanding-json-schema/reference>

## Create schema

Schemas are used to describe the structure of credentials, specifically the credential subject. It helps the issuer, holder, and verifier to unambiguously determine the claims contained within the credential. To create a schema, you need to define the object body using JSON schema.

### Parameters <a href="#create-schema-parameters" id="create-schema-parameters"></a>

<table data-full-width="false"><thead><tr><th width="109">Name</th><th width="82">In</th><th width="130">Type</th><th width="139">Required</th><th>Description</th></tr></thead><tbody><tr><td>body</td><td>body</td><td>object</td><td>true</td><td>JSON-schema.</td></tr></tbody></table>

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/schemas" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## List schemas

Return a list of all schemas created by the authenticated user.

### Parameters <a href="#list-schemas-parameters" id="list-schemas-parameters"></a>

<table data-full-width="false"><thead><tr><th width="121">Name</th><th width="102">In</th><th width="109">Type</th><th width="124">Required</th><th>Description</th></tr></thead><tbody><tr><td>offset</td><td>query</td><td>integer</td><td>false</td><td>How many items to offset by for pagination</td></tr><tr><td>limit</td><td>query</td><td>integer</td><td>false</td><td>How many items to return at one time (max 64)</td></tr></tbody></table>

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/schemas" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Get schema

Reading a Schema from the blockchain can easily be achieved by using the `get` method which will return the JSON schema to a specific schema ID. The `schemaId`needs to be URL encoded (e.g. `/schemas/https%3A%2F%2Fschema.dock.io%2FTestSchema-V1-1695817897561.json`)

### Parameters <a href="#get-schema-parameters" id="get-schema-parameters"></a>

<table data-full-width="false"><thead><tr><th width="132">Name</th><th width="100">In</th><th width="111">Type</th><th width="113">Required</th><th>Description</th></tr></thead><tbody><tr><td>schemaId</td><td>path</td><td>String</td><td>true</td><td>A URL encoded schema id.</td></tr></tbody></table>

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/schemas/{schemaId}" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Delete schema

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/schemas/{schemaId}" method="delete" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Jobs

In Truvera, API calls which depend on external systems may spawn jobs whose status can be queried until they complete. Examples include blockchain operations that we submit on your behalf and credential issuance via email. For instance, revoking a credential may require a blockchain transaction to finalize. This typically takes 5-10 seconds, depending on network load and other factors.

When an API call triggers a job, the response will contain a job ID that can be sent to this endpoint to track the job's status. [Like other asynchronous operations](/truvera-api/getting-started#asynchronous-responses), you can receive job information either by polling the API or registering a webhook.

## Get job status and data

To check the job status and data, you can use the `GET` method and simply put the job ID. It will return information related to the job being processed and its associated blockchain transaction. On completion or failure, the job data will be updated with a response from the blockchain.

### Parameters <a href="#get-job-status-and-data-parameters" id="get-job-status-and-data-parameters"></a>

<table data-full-width="false"><thead><tr><th width="125">Name</th><th width="109">In</th><th width="103">Type</th><th width="128">Required</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>path</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemajobid">JobId</a></td><td>true</td><td>Represents a Job id.</td></tr></tbody></table>

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/jobs/{id}" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Templates

Templates are used for presenting verifiable credentials to the user in a a pretty, readable and informative way. They can be used on the persisted credentials web view in Truvera workspace or for downloading credentials as PDF document. We have a [Designer function](/truvera-workspace/create-a-design) in the Truvera Workspace for creating Design templates.

We also have a library <https://github.com/docknetwork/prettyvc> that can be used to create templates and has samples of templates for users that want more customisation for their designs or use the same principal for their wallet credential display.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/templates" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/templates" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/templates/{id}" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/templates/{id}" method="patch" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/templates/{id}" method="delete" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Sub-accounts

Sub-accounts are a feature of the Truvera API that allows Truvera's enterprise customers to segregate their data within the Truvera platform based on their own customers. Each sub-account can have its own keys, organization profiles, credential designs and verification templates conveniently organized to help with tracking and auditing of the activity performed by each.

When using a sub-account the parent account will set up separate API keys for each sub-account and then use the sub-account specific API key for the transactions associated with that sub-account.

In order to easier manage sub-account assets [Ecosystem Tools](/truvera-api/ecosystem-tools) can be used.

### Sample sub-account Postman collection

Download the collection [here](https://github.com/docknetwork/knowledgebase-docs/blob/main/Postman_collections/Subaccounts/README.md).

This Postman collection shows a simple example of sub-account set up in 5 steps:

1. Creating a sub-account
2. Creating an API key for a sub-account
3. Creating a DID for the sub-account
4. Inviting sub-account as a participant in an already existing ecosystem
5. Accepting the invite

## Create sub-account

Sub-accounts are limited to 5 for trial users. The amount of sub-accounts for customers with subscription varies depending on the subscription plan.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/subaccounts" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## List sub-accounts

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/subaccounts" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Get sub-account by ID

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/subaccounts/{id}" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Update the specified sub-account

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/subaccounts/{id}" method="patch" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Deletes the specified sub-account

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/subaccounts/{id}" method="delete" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Get sub-account usage

Get details about the activity that this sub-account has performed in the system.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/subaccounts/{id}/usage" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Create sub-account API key

Creates an API key for a sub-account. In order for activity to be associated with the given sub-account an API key needs to be created for that sub-account and then that key must be used for all transactions related to that sub-account.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/subaccounts/{id}/keys" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## List sub-account API keys

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/subaccounts/{id}/keys" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Delete a sub-account API key

Delete the specified API key for the given sub-account.

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/subaccounts/{id}/keys/{keyId}" method="delete" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Teams

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/teams/accept-member-invite" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/teams/{id}/invite" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/teams/{id}" method="patch" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/teams/{id}/invitations" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/teams/{id}/invitations/{invitation\_id}/resend" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/teams/{id}/invitations/{invitation\_id}/cancel" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/teams/{id}/members" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/teams/{id}/members/{user\_id}" method="delete" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/teams/{id}/members/{user\_id}" method="patch" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Holder messaging via DIDComm

Holder messaging enables secure, encrypted communication between organizations and digital wallet holders using the DIDComm protocol. This feature allows verifiers to send authenticated requests directly to credential holders' wallets, enabling real-time verification workflows without requiring traditional authentication methods.

### Example use case

Consider a customer service scenario where enhanced identity verification is needed. A customer calls their bank to request a credit limit increase or password change. Rather than relying solely on traditional phone-based verification, the call center can leverage the customer's existing digital credentials for stronger authentication.

The process works as follows: the customer receives a credential during onboarding. The call center agent can initiate a credential verification request. The customer receives a secure message in their digital wallet via push notification, reviews the request, and responds using biometric authentication to unlock their wallet and confirm the data sharing.

### Technical implementation

#### Prerequisites

* Issuer has captured the holder's DID
* Issuer is using a valid message schema

{% hint style="info" %}
Current Truvera wallet implementation supports only YES/NO holder messaging schema. Customers using the wallet SDK can implement custom schemas based on their needs.
{% endhint %}

#### **Encrypted message dispatch**

Uses the Truvera API to send an encrypted DIDComm message to the holders DID.

On steps how to create the sender DID see the [Create DID](/truvera-api/dids) or step by step instructions in the [Truvera Workspace.](/truvera-workspace/create-an-organization-profile-did)\\

{% hint style="warning" %}
Static key (did:key method) cannot be used for the senders DID. Please use other available methods (e.g. did:cheqd).\
Recipient DID from the holder wallet will be a did:key.
{% endhint %}

The message script:

```javascript
const axios = require("axios").default;
const API_KEY = ;//Your Truvera API key// 
const API_URL = "https://api-testnet.truvera.io";//for production https://api.truvera.io
const WALLET_DID = ;//Holders wallet DID//

const apiClient = axios.create({
  baseURL: API_URL,
  headers: {
    "Content-Type": "application/json",
    "User-Agent": "insomnia/9.3.2",
    Authorization: `Bearer ${API_KEY}`,
  },
});

async function sendYesNoMessage() {
  const payload = {
    type: "text",
    payload: {
      senderName: , //Name of the message sender DID//
      senderDid: , //Message sender DID//
      senderLogo: , //Logo of the message sender DID//
      title: "Are you currently speaking with our customer support team?",
      question:
        "This confirms you initiated the call and helps prevent fraud. Your personal information will not be shared.",
      yesText: "Yes",
      noText: "No",
      expirationDate: new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString(),
      messageId: 'Internal-message-1234'//add a message ID to track the message
    },
    type: "https://schema.truvera.io/yes-no-payload-V1.json",
    senderDid: ,//the message sender DID//
    algorithm: "ECDH-1PU+A256KW",
    recipientDids: [WALLET_DID],
  };

  const { data: encryptedMessage } = await apiClient.post(
    "/messaging/encrypt",
    payload
  );
  console.log("Message encrypted successfully:", encryptedMessage);

  const sendPayload = {
    to: WALLET_DID,
    message: encryptedMessage.jwe,
  };

  const { data: sentMessage } = await apiClient.post(
    "/messaging/send",
    sendPayload
  );
  console.log("Message sent successfully:", sentMessage);
}


sendYesNoMessage();
```

#### Response payload from the wallet

```
{
    "messageId": "f07b97220782dd2c66df0180f09ad4cdd8d8671b2a86218129e4c721c03dfa5e",
    "to": "did:cheqd:testnet:senderDID",
    "messageType": "https://schema.truvera.io/yes-no-response-V1.json",
    "sender": null,
    "receivedAt": "2025-09-04T12:25:29.331Z",
    "content": {
        "id": "3d287880-898a-11f0-8698-4d8b1173feb3",
        "type": "https://schema.truvera.io/yes-no-response-V1.json",
        "created_time": 1756988727,
        "from": "did:key:holderDID",
        "body": {
            "messageId": "internal-message-1234",
            "response": "no"
        },
        "to": [
            "did:cheqd:testnet:senderDID"
        ]
    }
}
```

#### **Response notification and retrieval**

Configure a webhook via the [API](/truvera-api/webhooks) or the Truvera [Workspace](/truvera-workspace/creating-api-keys-and-webhook-endpoints#h_fae99467a4) to listen to didcomm\_message\_received event.

You can also get all the received messages using the API.

## List DIDComm messages

> Retrieve a list of DIDComm messages for the authenticated user. \
> Messages are returned in reverse chronological order (newest first).<br>

```json
{"openapi":"3.0.2","info":{"title":"Truvera API","version":"1"},"tags":[{"name":"messaging","description":"Operations about DIDComm messaging"}],"servers":[{"url":"https://api-testnet.truvera.io","description":"Sandbox server (uses test data)"},{"url":"https://api.truvera.io","description":"Production server (uses live data)"}],"security":[{"bearerAuth":[]},{"accessToken":[]},{"nextAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"},"accessToken":{"type":"apiKey","in":"header","name":"DOCK-API-TOKEN"},"nextAuth":{"type":"apiKey","in":"header","name":"CERTS-TOKEN"}},"schemas":{"DID":{"description":"DID as fully qualified, typically. `did:cheqd:`","type":"string","minimum":32},"DIDCommMessage":{"description":"A DIDComm message with metadata","type":"object","properties":{"messageId":{"type":"string","description":"Unique identifier for the message"},"to":{"type":"string","description":"The DID that received this message"},"messageType":{"type":"string","description":"The type of the message (from the message content)"},"sender":{"type":"string","nullable":true,"description":"The DID of the message sender (if available)"},"receivedAt":{"type":"string","format":"date-time","description":"When the message was received"},"content":{"type":"object","description":"The message content (decrypted if encrypted, plaintext if not). Not included in message lists.","additionalProperties":true}},"required":["messageId","to","receivedAt"]},"Error":{"description":"An API Error","type":"object","properties":{"status":{"type":"integer"},"type":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/messaging/messages":{"get":{"summary":"List DIDComm messages","tags":["messaging"],"description":"Retrieve a list of DIDComm messages for the authenticated user. \nMessages are returned in reverse chronological order (newest first).\n","parameters":[{"name":"offset","in":"query","description":"How many items to offset by for pagination","required":false,"schema":{"type":"integer","format":"int32","default":0,"minimum":0}},{"name":"limit","in":"query","description":"How many items to return at one time (max 64)","required":false,"schema":{"type":"integer","format":"int32","default":64,"minimum":1,"maximum":64}},{"name":"to","in":"query","description":"Filter messages by specific DID","required":false,"schema":{"$ref":"#/components/schemas/DID"}},{"name":"messageType","in":"query","description":"Filter messages by type (e.g., 'https://didcomm.org/basicmessage/2.0/basic-message')","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"A paged array of DIDComm messages","content":{"application/json":{"schema":{"type":"object","properties":{"messages":{"type":"array","items":{"$ref":"#/components/schemas/DIDCommMessage"}},"total":{"type":"integer","description":"Total number of messages available"},"offset":{"type":"integer","description":"Current offset for pagination"},"limit":{"type":"integer","description":"Current limit for pagination"}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

To get the message content make an API call to retrieve the full response.

## Get a specific DIDComm message

> Retrieve a specific DIDComm message by its ID. \
> Only messages owned by the authenticated user can be retrieved.<br>

```json
{"openapi":"3.0.2","info":{"title":"Truvera API","version":"1"},"tags":[{"name":"messaging","description":"Operations about DIDComm messaging"}],"servers":[{"url":"https://api-testnet.truvera.io","description":"Sandbox server (uses test data)"},{"url":"https://api.truvera.io","description":"Production server (uses live data)"}],"security":[{"bearerAuth":[]},{"accessToken":[]},{"nextAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"},"accessToken":{"type":"apiKey","in":"header","name":"DOCK-API-TOKEN"},"nextAuth":{"type":"apiKey","in":"header","name":"CERTS-TOKEN"}},"schemas":{"DIDCommMessage":{"description":"A DIDComm message with metadata","type":"object","properties":{"messageId":{"type":"string","description":"Unique identifier for the message"},"to":{"type":"string","description":"The DID that received this message"},"messageType":{"type":"string","description":"The type of the message (from the message content)"},"sender":{"type":"string","nullable":true,"description":"The DID of the message sender (if available)"},"receivedAt":{"type":"string","format":"date-time","description":"When the message was received"},"content":{"type":"object","description":"The message content (decrypted if encrypted, plaintext if not). Not included in message lists.","additionalProperties":true}},"required":["messageId","to","receivedAt"]},"Error":{"description":"An API Error","type":"object","properties":{"status":{"type":"integer"},"type":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/messaging/messages/{messageId}":{"get":{"summary":"Get a specific DIDComm message","tags":["messaging"],"description":"Retrieve a specific DIDComm message by its ID. \nOnly messages owned by the authenticated user can be retrieved.\n","parameters":[{"name":"messageId","in":"path","required":true,"description":"The unique identifier of the message","schema":{"type":"string","pattern":"^[a-f0-9]{64}$"}}],"responses":{"200":{"description":"The requested DIDComm message","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DIDCommMessage"}}}},"400":{"description":"Invalid message ID format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Message not found or not owned by user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```


# Messaging API calls

## Encrypt Message

In most cases you'll want to ensure the privacy of the message by encrypting it before sending.

### Parameters <a href="#post__messaging_encrypt-parameters" id="post__messaging_encrypt-parameters"></a>

<table data-full-width="false"><thead><tr><th width="162">Name</th><th width="85">In</th><th width="103">Type</th><th width="115">Required</th><th>Description</th></tr></thead><tbody><tr><td>body</td><td>body</td><td>object</td><td>true</td><td>The recipients, sender and message</td></tr><tr><td>» type</td><td>body</td><td>string</td><td>false</td><td>none</td></tr><tr><td>» payload</td><td>body</td><td>object</td><td>true</td><td>none</td></tr><tr><td>» senderDid</td><td>body</td><td>string</td><td>true</td><td>none</td></tr><tr><td>» algorithm</td><td>body</td><td>string</td><td>false</td><td>none</td></tr><tr><td>» recipientDids</td><td>body</td><td>[oneOf]</td><td>true</td><td>none</td></tr></tbody></table>

### **Enumerated Values**

<table data-full-width="false"><thead><tr><th>Parameter</th><th>Value</th></tr></thead><tbody><tr><td>» algorithm</td><td>ECDH-1PU+A256KW</td></tr><tr><td>» algorithm</td><td>ECDH-ES+A256KW</td></tr></tbody></table>

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/messaging/encrypt" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Decrypt Message

### Parameters <a href="#post__messaging_decrypt-parameters" id="post__messaging_decrypt-parameters"></a>

<table data-full-width="false"><thead><tr><th>Name</th><th>In</th><th>Type</th><th>Required</th><th>Description</th></tr></thead><tbody><tr><td>body</td><td>body</td><td>object</td><td>true</td><td>The JWM</td></tr><tr><td>» jwe</td><td>body</td><td>object</td><td>true</td><td>none</td></tr></tbody></table>

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/messaging/decrypt" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Signing Messages

Signing a message helps to prove to the recipient that the message is valid and unaltered. The message will be signed as a Base64 encoded JWT.

### Parameters <a href="#post__messaging_sign-parameters" id="post__messaging_sign-parameters"></a>

<table data-full-width="false"><thead><tr><th width="169">Name</th><th width="79">In</th><th width="89">Type</th><th width="108">Required</th><th>Description</th></tr></thead><tbody><tr><td>body</td><td>body</td><td>object</td><td>true</td><td>The message payload</td></tr><tr><td>» payload</td><td>body</td><td>object</td><td>true</td><td>none</td></tr><tr><td>» senderDid</td><td>body</td><td>string</td><td>true</td><td>none</td></tr><tr><td>» type</td><td>body</td><td>string</td><td>false</td><td>none</td></tr></tbody></table>

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/messaging/sign" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Verifying a Message

Verify that the message is valid.

### Parameters <a href="#post__messaging_verify-parameters" id="post__messaging_verify-parameters"></a>

<table data-full-width="false"><thead><tr><th width="112">Name</th><th width="88">In</th><th width="110">Type</th><th width="135">Required</th><th>Description</th></tr></thead><tbody><tr><td>body</td><td>body</td><td>object</td><td>true</td><td>The message payload</td></tr><tr><td>» jws</td><td>body</td><td>string</td><td>true</td><td>none</td></tr></tbody></table>

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/messaging/verify" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

## Send Message

Sends a DIDComm message using our relay service and DID service endpoints, it also returns a URL for QR code scanning. Supports encrypted, plaintext and signed DIDComm messages. You can generate an encrypted DIDComm message by calling the `/messaging/encrypt` route.

The `typ` attribute must be a DIDComm type (i.e. starts with "application/didcomm").

### Parameters <a href="#post__messaging_send-parameters" id="post__messaging_send-parameters"></a>

<table data-full-width="false"><thead><tr><th width="134">Name</th><th width="83">In</th><th width="107">Type</th><th width="116">Required</th><th>Description</th></tr></thead><tbody><tr><td>body</td><td>body</td><td>object</td><td>true</td><td>The message payload</td></tr><tr><td>» to</td><td>body</td><td>string</td><td>true</td><td>none</td></tr><tr><td>» message</td><td>body</td><td>Message</td><td>true</td><td>none</td></tr></tbody></table>

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/messaging/send" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# OpenID

OpenID issuance is the best way to go, when you need to send the credential to the holder using a deeplink or QR code.

OpenID issuer endpoint should not be confused with the credential Issuer as it is in the Truvera platform. With OpenID creating an OpenID issuer is the first step of credential issuance and will need to be done for each individual credential.

{% hint style="warning" %}
**Note:** Credential offers created with `"singleUse": false` are not subject to automatic deletion by the retention policy. Because these offers are designed for repeated use, they persist indefinitely until manually deleted. If you want offers to be cleaned up automatically, set `"singleUse": true`.
{% endhint %}

{% openapi src="/files/JRr1pCTFHx76mpRDdFlL" path="/openid/issuers" method="post" %}
[updated\_openapi.yaml](https://815575130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWRMhdRsPkUzlSqCYzbgF%2Fuploads%2Fgit-blob-275cf229de21c78eb08b2b9375323ab201e4ea6e%2Fupdated_openapi.yaml?alt=media)
{% endopenapi %}

### Credential offers

Generate credential offers to initiate the issuance process. Credential offers can be shared with the holder to claim the credential. This endpoint creates a credential offer linked to the OpenID issuer.

{% openapi src="/files/JRr1pCTFHx76mpRDdFlL" path="/openid/credential-offers" method="post" %}
[updated\_openapi.yaml](https://815575130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWRMhdRsPkUzlSqCYzbgF%2Fuploads%2Fgit-blob-275cf229de21c78eb08b2b9375323ab201e4ea6e%2Fupdated_openapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/JRr1pCTFHx76mpRDdFlL" path="/openid/issuers" method="get" %}
[updated\_openapi.yaml](https://815575130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWRMhdRsPkUzlSqCYzbgF%2Fuploads%2Fgit-blob-275cf229de21c78eb08b2b9375323ab201e4ea6e%2Fupdated_openapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/JRr1pCTFHx76mpRDdFlL" path="/openid/issuers/{id}" method="get" %}
[updated\_openapi.yaml](https://815575130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWRMhdRsPkUzlSqCYzbgF%2Fuploads%2Fgit-blob-275cf229de21c78eb08b2b9375323ab201e4ea6e%2Fupdated_openapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/JRr1pCTFHx76mpRDdFlL" path="/openid/issuers/{id}" method="delete" %}
[updated\_openapi.yaml](https://815575130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWRMhdRsPkUzlSqCYzbgF%2Fuploads%2Fgit-blob-275cf229de21c78eb08b2b9375323ab201e4ea6e%2Fupdated_openapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/JRr1pCTFHx76mpRDdFlL" path="/openid/vp/{id}/request" method="get" %}
[updated\_openapi.yaml](https://815575130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWRMhdRsPkUzlSqCYzbgF%2Fuploads%2Fgit-blob-275cf229de21c78eb08b2b9375323ab201e4ea6e%2Fupdated_openapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/JRr1pCTFHx76mpRDdFlL" path="/openid/vp/{id}/request-url" method="post" %}
[updated\_openapi.yaml](https://815575130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWRMhdRsPkUzlSqCYzbgF%2Fuploads%2Fgit-blob-275cf229de21c78eb08b2b9375323ab201e4ea6e%2Fupdated_openapi.yaml?alt=media)
{% endopenapi %}


# OpenID issuance and verification integration guide

This guide provides detailed instructions for implementing OpenID for Verifiable Credential Issuance (OID4VCI) and OpenID for Verifiable Presentation (OID4VP) using a series of API endpoints. It outlines the steps required to set up an issuer, create credential offers, manage the issuance flow, create presentations and verify the issued credentials.

## Prerequisites

Before starting, ensure you have:

* **Issuer DID** (`did:dock:issuer`): The did for the credential issuer.
* **Verifier DID** (`did:dock:verifier`): The did for the credential verifier.
* **Holder DID** (`did:key:holder`): The DID for the credential holder (optional)

Download and use our [Postman Collections](https://github.com/docknetwork/knowledgebase-docs/blob/main/Postman_collections/OID4VC%20and%20OID4VP%20testing/README.md) to experiment with OpenID standards based credentials.

## Set up an OID4VCI issuer

Create an OID4VCI issuer with the necessary configurations, including claim mappings, credential options, and authentication provider settings.

<mark style="color:green;">`POST`</mark> /openid/issuers

This endpoint creates an OID4VCI issuer. "authProvider" and "claimMap" are supplied as part of the [Authorization Code Flow](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html#name-authorization-code-flow). It can be omitted for the [Pre-Authorized Code Flow](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html#name-pre-authorized-code-flow).

{% hint style="info" %}
**Note:** Credential offers created with `"singleUse": false` are not subject to automatic deletion by the retention policy. Because these offers are designed for repeated use, they persist indefinitely until manually deleted. If you want offers to be cleaned up automatically, set `"singleUse": true`.
{% endhint %}

**Request/Response**

{% tabs %}
{% tab title="Body" %}

```json
 {
    "claimMap": {
      "name": "name"
    },
    "credentialOptions": {
      "credential": {
        "type": ["UniversityDegreeCredential"],
        "context": ["https://www.w3.org/2018/credentials/examples/v1"],
        "subject": {
          "alumniOf": "Truvera University",
          "degree": "Credential Science"
          // name will be added by claims flow
        },
        "expirationDate": "2099-08-24T14:15:22Z",
        "issuer": "did:dock:issuer"
      }
    },
    "authProvider": {
      "url": "https://creds.dock.io/claims",
      "scope": ["openid"],
      "clientId": "eyAic2NoZW1hIjogImh0dHBzOi8vZG9ja25ldHdvcmsuZ2l0aHViLmlvL3ZjLXNjaGVtYXMvYmFzaWMtY3JlZGVudGlhbC5qc29uIiwgImNsYWltcyI6IFsibmFtZSJdIH0=",
      "clientSecret": "gpO2IVK+OALL8W+DcFlIfFhJtNA="
    },
    "singleUse": false
  }
```

{% endtab %}

{% tab title="Response" %}

```json
{
  "id": "{issuerId}",
  "created": "2024-09-20T08:53:50.524Z",
  "updated": "2024-09-20T08:53:50.524Z",
  "credentialOptions": { ... },
  "authProvider": { ... },
  "claimMap": { ... },
  "qrUrl": "openid://discovery?issuer=https://api.example.com/openid/issuers/issuer-id"
}
```

{% endtab %}
{% endtabs %}

### Check the OpenID issuer configuration

<mark style="color:green;">`GET`</mark> /openid/issuers/{issuerId}/.well-known/openid-configuration

This endpoint retrieves the OpenID configuration for the specified issuer.

**Request/Response**

{% tabs %}
{% tab title="Response" %}

```json
{
  "issuer": "https://api-testnet.dock.io/openid/issuers/{issuerId}",
  "credential_formats_supported": ["ldp_vc", "jwt"],
  "credential_claims_supported": ["name"],
  "response_types_supported": ["code"],
  "grant_types_supported": ["authorization_code"]
}
```

{% endtab %}
{% endtabs %}

## Create credential offers

Generate credential offers to initiate the issuance process. Credential offers can be shared with the holder to claim the credential.

<mark style="color:green;">`POST`</mark> /openid/credential-offers

This endpoint creates a credential offer linked to the OpenID issuer.

**Request/Response**

{% tabs %}
{% tab title="Body" %}

```json
  {
    "id": "{issuerId}"
  }
```

{% endtab %}

{% tab title="Response" %}

```json
{
  "url": "openid-credential-offer://?credential_offer=...",
  "offer": {
    "credential_issuer": "https://api-testnet.dock.io/openid/issuers/{issuerId}",
    "credentials": ["ldp_vc:UniversityDegreeCredential"],
    "grants": {
      "authorization_code": { "issuer_state": "state123" }
    }
  }
}
```

{% endtab %}
{% endtabs %}

## Retrieve and store credentials

Using the [Truvera Wallet ](/credential-wallet)or any OID4VCI Wallet, scan the QR code received and follow the process to receive the credential.

## Verify credentials

### Create a new proof request

This step involves creating a proof request that specifies the requirements for the verifiable presentation. The proof request defines what credentials and claims are expected from the holder.

<mark style="color:green;">`POST`</mark> /proof-requests

This endpoint creates a new proof request that the verifier can use to request credentials from the holder.

**Request/Response**

{% tabs %}
{% tab title="Body" %}

```json
{
      "did": "did:dock:5HCXuyBhXRiZxSmyLG2j6NhoeqL4dYHV9EGwLE2FKJVUmXL4",
	  "name": "OID4VP Proof request 2",
	  "request": {
		"name": "OID4VP test proof request",
		"purpose": "To present a test credential using OID4VPI",
		"input_descriptors": [
		  {
			"id": "Truvera Credential",
			"name": "OID4VP test proof request",
			"purpose": "To present a test credential using OID4VP",
			"constraints": {
			  "fields": [
				{
				  "path": [
					"$.credentialSubject.name"
				  ]
				},
				{
				  "path": [
					"$.type",
					"$.vc.type"
				  ],
				  "filter": {
					"type": "array",
					"contains": {
					  "const": "UniversityDegreeCredential"
					}
				  }
				}
			  ]
			}
		  }
		]
	  }
  }
```

{% endtab %}

{% tab title="Response" %}

```json
{
    "id": "{proofRequestId}",
    "name": "OID4VP Proof request",
    "nonce": "...",
    "did": "did:dock:verifier",
    "verified": false,
    "created": "...",
    "updated": "...",
    "signature": "...",
    "presentation": {},
    "response_url": "...",
    "type": "proof-request",
    "qr": "...",
    "request": {...},
    "types": ["jsonld"]
}
```

{% endtab %}
{% endtabs %}

### Get the request url for the OID4VP

This step generates a request URL that can be shared with the holder. The holder can use this URL to present the requested credentials through their wallet.

<mark style="color:green;">`POST`</mark> /openid/vp/{proofRequestId}/request-url

This endpoint generates a request URL based on the proof request ID. The withRequestURI parameter determines whether the URL includes the request\_uri.

**Request/Response**

{% tabs %}
{% tab title="Body" %}

```json
  {
      "withRequestURI": true
  }
```

{% endtab %}

{% tab title="Response" %}

```json
{
    "url": "openid://?client_id=...&request_uri=..."
}
```

{% endtab %}
{% endtabs %}

### Verify presentation

Using the [Truvera Wallet ](/credential-wallet)or any OID4VP Wallet, scan the QR code received and follow the process to verify the credential.

### Check proof request status

This step involves checking the status of a specific proof request to see if it has been fulfilled, and to retrieve any relevant information associated with the request.

<mark style="color:green;">`GET`</mark> /proof-requests/{proofRequestId}

This endpoint retrieves the status and details of the specified proof request, including whether the requested credentials have been presented and verified

**Request/Response**

{% tabs %}
{% tab title="Response" %}

```json
{
    "id": "{proofRequestId}",
    "name": "OID4VP Proof request",
    "nonce": "...",
    "did": "did:dock:verifier",
    "verified": true,
    "created": "...",
    "updated": "...",
    "signature": "...",
    "presentation": {
	    "holder": "did:dock:holder"
	    ...
    },
    "response_url": "...",
    "type": "proof-request",
    "qr": "...",
    "request": {...},
    "types": ["jsonld"]
}
```

{% endtab %}
{% endtabs %}


# Ecosystem Tools

Verifiable credentials have an advantage over physical documents, because they cannot be forged. However, there is still a fraud risk if a credential is issued by someone that has no authority to do so.

How can a verifier be sure that the credential came from an authorized issuer? And vice-versa, how can a credential holder know which verifiers are trustworthy and that it is okay to share their credentials with them? Ecosystem Tools is a solution to answer this problem.

## What is an ecosystem?

\
Ecosystem is a network of trusted digital identity issuers and verifiers. It uses a **trust registry,** an on-chain list, that contains information on who is authorized and trusted to issue or verify credentials in a particular ecosystem and which credential schemas they can issue and verify.

Ecosystems are governed by trust frameworks, a set of operating rules that participants of the ecosystem must follow.

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

## Why use Ecosystem Tools?

A trust ecosystem helps organizations to simplify everyday interactions and have confidence to allow other organizations or people to interact and share fraud-proof and digitally verifiable data.

Governing Authority could register as an Ecosystem Admin in Truvera Workspace where they can establish a Trusted Brand, communicate rules for participation in a Governance Framework, and administer the ecosystem.

By having an on-chain trust registry, credential verifiers do not need to manage a list of valid issuers and holders know which verifiers they can trust to share their credentials with. They only need to trust one Ecosystem administrator.


# Trust Registry integration guide

This guide provides step-by-step instructions for integrating a trust registry into any application using a series of API endpoints. This guide assumes a basic understanding of essential elements such as DIDs, JWTs, and specific configurations.

Download a sample Postman collection [here](https://github.com/docknetwork/knowledgebase-docs/blob/main/Postman_collections/Ecosystem%20Tools%20\(Trust%20Registry\)/README.md).

## Prerequisites

Before starting, ensure you have:

* A DID for the convener (`did:dock:convener`) with associated profile
* A DID for the participant (`did:dock:pariticpant`) with associated profile

## Step-by-step guide

### 1. Create a trust registry

Create a trust registry using the convener's DID and relevant metadata.

**POST /trust-registries** This endpoint creates a new trust registry with the provided metadata and convener DID.

**Body:**

```json
{
  "name": "Dock Trust Registry",
  "description": "Qui labore ad consequat exercitation excepteur nulla deserunt qui sunt deserunt laboris quis dolore voluptate!",
  "logoUrl": "https://logo.com/registry",
  "ecosystemUrl": "https://myecosystem.com",
  "governanceFramework": "Consectetur non anim incididunt duis ullamco est in irure labore quis.",
  "governanceFrameworkVersion": "1.0.0",
  "convener": "did:dock:convener"
}
```

**Response:**

```json
{
  "id": "0x30eb6adc982f60e11d77044e7dec02c89e24af32f05be6a17ea204d155a36fcb",
  "slug": "my-trust-registry-1",
  "nonce": "0xc54b08e7f82d4689",
  "convener": "did:dock:convener",
  "convenerName": "My Convener",
  "convenerLogoUrl": "https://dock.io/convener.png",
  "created": "2024-08-16T12:39:32.060Z",
  "name": "Dock Trust Registry",
  "description": "Qui labore ad consequat exercitation excepteur nulla deserunt qui sunt deserunt laboris quis dolore voluptate!",
  "logoUrl": "https://logo.com/registry",
  "ecosystemUrl": "https://myecosystem.com",
  "governanceFramework": "Consectetur non anim incididunt duis ullamco est in irure labore quis.",
  "governanceFrameworkVersion": "1.0.0"
}
```

### 2. Add participants to the trust registry

Invite participants (e.g., issuers, verifiers) to the trust registry and assign schemas.

**Note:** Roles are automatically assigned based on the schemas allocated to a participant:

* If a participant can only issue credentials using the assigned schemas, they are designated as an `issuer`.
* If a participant can only verify credentials using the assigned schemas, they are designated as a `verifier`.
* If a participant can both issue and verify, they are designated as a `verifier+issuer`. A participant without any assigned schemas will have a `verifier` role but will only be able to verify public schemas within the ecosystem.

**POST /trust-registries/{trust\_registry\_id}/participants** This endpoint invites a participant to the trust registry with specified schemas they are allowed to issue or verify. Will be called by the trust registry convener.

**Body:**

```json
{}
```

**Note:** An empty body will result in a `verifier` role for the participant, allowing them only to verify `public` schemas. Issuer and verifier schemas can be assigned in the invitation by adding the schema IDs to the request body.

```json
{
  "issuerSchemas": ["https://schema.com/invitation/issuer"],
  "verifierSchemas": ["https://schema.com/invitation/verifier"]
}
```

**Response:**

```json
{
  "link": "http://127.0.0.1:3000/ecosystems?token=inviteToken"
}
```

**Accept the invitation:**

**POST /trust-registries/invitations/accept** This endpoint accepts an invitation to join a trust registry using a provided token. Will be called by a trust registry participant to join the registry.

**Body:**

```json
{
  "did": "did:dock:participant",
  "infoUrl": "https://participant.com",
  "token": "inviteToken"
}
```

**Response:**

```json
{
  "id": "64c257f0-2920-408b-adef-8fd3f40c1b3c",
  "userId": 1,
  "name": "My Participant",
  "description": "Proident proident enim cupidatat ad culpa anim ullamco qui aliquip.",
  "did": "did:dock:participant",
  "logoUrl": "https://dock.io/participant.png",
  "infoUrl": "https://participant.com",
  "status": "active",
  "role": "verifier",
  "created": "2024-08-16T12:42:56.682Z",
  "suspendedAt": ""
}
```

**Note:**

* The DID's profile name, description, and logo will be applied to the participant. The name and logo are required for DIDs that will be used as participants.
* Invitations can be snoozed using `POST /trust-registries/invitations/snooze`
* Invitations can be declined using `POST /trust-registries/invitations/decline`

**Error Handling:**

* Attempting to reuse an invite token will result in an error.
* Inviting a participant that already exists in the registry may also cause an error.

### 3. Retrieve trust registry details

Retrieve details of the trust registry, including participants and schemas.

**GET /trust-registries/{trust\_registry\_id}** This endpoint retrieves detailed information about a specific trust registry. Useful for both the convener and participants to get an overview of the registry.

**Response:**

```json
{
  "id": "0x30eb6adc982f60e11d77044e7dec02c89e24af32f05be6a17ea204d155a36fcb",
  "slug": "my-trust-registry-1",
  "nonce": "0xc54b08e7f82d4689",
  "convener": "did:dock:convener",
  "convenerName": "My Convener",
  "convenerLogoUrl": "https://dock.io/convener.png",
  "created": "2024-08-16T12:39:32.060Z",
  "name": "Dock Trust Registry",
  "description": "Qui labore ad consequat exercitation excepteur nulla deserunt qui sunt deserunt laboris quis dolore voluptate!",
  "logoUrl": "https://logo.com/registry",
  "ecosystemUrl": "https://myecosystem.com",
  "governanceFramework": "Consectetur non anim incididunt duis ullamco est in irure labore quis.",
  "governanceFrameworkVersion": "1.0.0",
  "created": "2024-08-16T12:50:30.944Z",
  "isOwner": true, //whether the current user is the owner of the ecosystem
  "isUnmaintained": false, // whether the trust registry administrator has no active subscription
  "issuerCount": 0, // the number of issuers in the trust registry
  "verifierCount": 1 // the number of verifier in the trust registry
}
```

**Note:**

* `slug` can be used instead of `trust_registry_id`
* The public info about a trust registry is available at `GET /trust-registries/{trust_registry_id}/public`

### 4. Update trust registry metadata

Update the metadata of an existing trust registry.

**PATCH /trust-registries/{trust\_registry\_id}** This endpoint updates the metadata of an existing trust registry. Will be called by the convener to update details like the name, description, or governance framework.

**Body:**

```json
{
  "name": "Updated Name",
  "description": "Updated description",
  "logoUrl": "https://logo.com/updated",
  "ecosystemUrl": "https://updatedecosystem.com",
  "governanceFramework": "This is a markdown document describing my framework version two!",
  "governanceFrameworkVersion": "2.0.0"
}
```

**Response:**

```json
{
  "id": "0x62459be8cef6cd405cc6838ed3f678bcf0784393fce25f42307f37001255d07c",
  "slug": "updated-name-359",
  "nonce": "0x9f49c2d9e481d5c7",
  "convener": "did:dock:convener",
  "convenerName": "My Convener",
  "convenerLogoUrl": "https://dock.io/convener.png",
  "created": "2024-08-16T13:02:49.456Z",
  "isOwner": true,
  "isUnmaintained": false,
  "name": "Updated Name",
  "description": "Updated the description",
  "logoUrl": "https://logo.com/ecosystemnew",
  "ecosystemUrl": "https://myecosystemnew.com",
  "governanceFramework": "This is a markdown document describing my framework version two!",
  "governanceFrameworkVersion": "2.0.0",
  "issuerCount": 0,
  "verifierCount": 1
}
```

### 5. Manage trust registry participants

#### a. Update participant information

Update a participant's information within the registry.

**PATCH /trust-registries/{trust\_registry\_id}/participants/{participant\_id}/info** This endpoint updates a participant’s information within the trust registry. It can be used only by the participant to update his own informations.

**Body:**

```json
{
  "infoUrl": "https://newinfo.com"
}
```

**Response:**

```json
{
  "id": "f6ea7dd8-2a99-4c1a-9985-a41f12b4a7da",
  "userId": 1,
  "name": "My Participant",
  "description": "Proident proident enim cupidatat ad culpa anim ullamco qui aliquip.",
  "did": "did:dock:participant",
  "logoUrl": "https://newlogo.com",
  "infoUrl": "https://newinfo.com",
  "status": "active",
  "role": "verifier",
  "issuerSchemas": [],
  "verifierSchemas": [],
  "created": "2024-08-16T13:22:38.213Z",
  "suspendedAt": ""
}
```

**Note:** The name and logo can be updated by modifying the associated DID profile's information.

#### b. Suspend or unsuspend participants

Suspend or unsuspend a participant's status within the registry.

**PATCH /trust-registries/{trust\_registry\_id}/participants/{participant\_id}** This endpoint updates a participant’s information within the trust registry, such as their assigned schemas or their status (e.g., suspended or active).

**Body:**

```json
{
  "status": "suspended" // or "active"
}
```

**Response:**

```json
{
  "id": "f6ea7dd8-2a99-4c1a-9985-a41f12b4a7da",
  "userId": 1,
  "name": "My Participant",
  "description": "Proident proident enim cupidatat ad culpa anim ullamco qui aliquip.",
  "did": "did:dock:participant",
  "logoUrl": "https://dock.io/participant.png",
  "infoUrl": "https://participant.com",
  "status": "suspended",
  "role": "verifier",
  "issuerSchemas": [],
  "verifierSchemas": [],
  "created": "2024-08-16T13:22:38.213Z",
  "suspendedAt": "2024-08-16T14:22:38.213Z"
}
```

#### c. Get all participants

Get a list of all participants in the trust registry

**GET /trust-registries/{trust\_registry\_id}/participants** This endpoint retrieves detailed information about the participants from the trust registry

**Response:**

```json
{
  "total": 1,
  "list": [
    {
      "id": "f6ea7dd8-2a99-4c1a-9985-a41f12b4a7da",
	  "userId": 1,
	  "name": "My Participant",
	  "description": "Proident proident enim cupidatat ad culpa anim ullamco qui aliquip.",
	  "did": "did:dock:participant",
	  "logoUrl": "https://dock.io/participant.png",
	  "infoUrl": "https://participant.com",
	  "status": "active",
	  "role": "verifier",
	  "issuerSchemas": [],
	  "verifierSchemas": [],
	  "created": "2024-08-16T13:22:38.213Z",
	  "suspendedAt": ""
    }
  ]
}
}
```

### 6. Manage schemas

#### a. Assign schemas to participants

Assign specific schemas to participants based on their roles.

**PATCH /trust-registries/{trust\_registry\_id}/participants/{participant\_id}** This endpoint updates a participant’s information within the trust registry, such as their assigned schemas or their status (e.g., suspended or active). Will be called by the convener to manage participant roles and schemas.

**Body:**

```json
{
  "issuerSchemas": ["https://schema.com/issuer"],
  "verifierSchemas": ["https://schema.com/verifier"]
}
```

**Response:**

```json
{
  "id": "f6ea7dd8-2a99-4c1a-9985-a41f12b4a7da",
  "userId": 1,
  "name": "My Participant",
  "description": "Proident proident enim cupidatat ad culpa anim ullamco qui aliquip.",
  "did": "did:dock:participant",
  "logoUrl": "https://dock.io/participant.png",
  "infoUrl": "https://participant.com",
  "status": "active",
  "role": "verifier",
  "issuerSchemas": ["https://schema.com/issuer"],
  "verifierSchemas": ["https://schema.com/verifier"],
  "created": "2024-08-16T13:22:38.213Z",
  "suspendedAt": ""
}
```

#### b. Get trust registry schemas

Retrieve schemas associated with the trust registry.

**GET /trust-registries/{trust\_registry\_id}/schemas** This endpoint retrieves the list of schemas associated with a specific trust registry, including participant counts and public visibility. Useful for both the convener and participants.

**Response:**

```json
{
  "id": "https://schema.com/verifier",
  "name": "https://schema.com/verifier",
  "public": false, // if a schema has no verifier assigned it is a public schema and can be verifier by anyone in the ecosystem
  "prices": [], // assigned prices for this schema
  "topParticipants": [
    {
      "id": "0e5ed250-382a-496c-a59e-d7b0f9f2f3d3",
      "name": "My Participant",
      "description": "Proident proident enim cupidatat ad culpa anim ullamco qui aliquip.",
      "did": "did:key:participant",
      "logoUrl": "https://dock.io/participant.png",
      "suspendedAt": ""
    }
  ], // top 5 participants using this schema
  "participantCount": 1 // the total number of participants using this schema
}
```

### 7. Manage proof templates

#### a. Assign proof templates to the trust registry

Assign proof templates to the trust registry to enable credential verification. This will allow the verifiers in the trust registry to use the proof-template

**POST /trust-registries/{trust\_registry\_id}/proof-templates** This endpoint assigns a proof template to the trust registry, enabling it for use in credential verification. Will be called by the convener.

**Body:**

```json
{
  "id": "proof_template_id"
}
```

**Response:**

```json
{}
```

#### b. Retrieve proof templates

Retrieve proof templates associated with the trust registry.

**GET /trust-registries/{trust\_registry\_id}/proof-templates** This endpoint retrieves the list of proof templates associated with the trust registry. Useful for both the convener and participants.

**Response:**

```json
{
  "total": 1,
  "list": [
    {
      "id": "proof_template_id",
      "created": "2024-08-16T13:36:54.776Z",
      "name": "Proof request"
    }
  ]
}
```

### 8. Delete trust registry entities

#### a. Delete a trust registry participant

Remove a participant from the trust registry.

**DELETE /trust-registries/{trust\_registry\_id}/participants/{participant\_id}** This endpoint removes a participant from the trust registry. Will be called by the convener to manage the registry’s participants.

**Response:**

```json
{}
```

#### b. Delete a trust registry proof template

Remove a proof template from the trust registry.

**DELETE /trust-registries/{trust\_registry\_id}/proof-templates/{template\_id}** This endpoint removes a proof template from the trust registry. Will be called by the convener to manage the registry’s proof templates.

**Response:**

```json
{}
```

#### c. Delete a trust registry

Delete the entire trust registry.

**DELETE /trust-registries/{trust\_registry\_id}** This endpoint deletes the entire trust registry. Will be called by the convener when the trust registry is no longer needed.

**Response:**

```json
{}
```


# Creating a trust registry

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/query" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}" method="parameters" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Inviting participants

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/invitations/accept" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/invitations/decline" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/invitations/snooze" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/participants" method="parameters" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/participants" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/participants" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/participants/{participantId}" method="parameters" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/participants/{participantId}" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/participants/{participantId}" method="delete" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/participants/{participantId}" method="patch" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/participants/{participantId}/info" method="parameters" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/participants/{participantId}/info" method="patch" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Verifiers and public info

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/verifiers" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/public" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Trust registry schemas

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/schemas" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/schemas/{schemaId}/price" method="parameters" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/schemas/{schemaId}/price" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/schema-prices" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/schema-dids" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/schemas/{schemaId}" method="delete" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Trust registry proof templates

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/proof-templates" method="parameters" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/proof-templates" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/proof-templates" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/proof-templates/{templateId}" method="parameters" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/proof-templates/{templateId}" method="delete" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Reports

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/reports" method="parameters" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}/reports" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Updating and deleting a trust registry

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}" method="delete" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/trust-registries/{registryId}" method="patch" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Issuing paid credentials (KVAC algorithm integration)

This guide provides step-by-step instructions for implementing the KVAC algorithm to issue and verify paid credentials using a series of API endpoints. Follow these instructions to integrate KVAC into your system effectively.

Download a sample Postman collection [here](https://github.com/docknetwork/knowledgebase-docs/blob/main/Postman_collections/Issuing%20KVAC%20credentials/README.md).

## Prerequisites

Before starting, ensure you have:

* DIDs for issuer (`did:dock:issuer`) and verifier (`did:dock:verifier`)
* A trust registry (`trust_registry_id`)
* A schema (`http://example.org/schema/kvac`)

## Step-by-step guide

### 1. Invite participants to trust registry (issuer and verifier)

Invite issuers and verifiers to the trust registry and assign them the schema that will be used in the `KVAC` credential.

**POST /trust-registries/{trust\_registry\_id}/participants** This endpoint invites a participant to the trust registry with specified schemas they are allowed to issue or verify. Will be called by the trust registry convenor.

**Body:**

```json
{
  "issuerSchemas": ["http://example.org/schema/kvac"]
}
```

**POST /trust-registries/invitations/accept** This endpoint accepts an invitation to join a trust registry using a provided token. Will be called by a trust registry future member.

**Body:**

```json
{
  "did": "did:dock:issuer",
  "infoUrl": "https://info.org/issuer",
  "token": "inviteTokenIssuer"
}
```

**POST /trust-registries/{trust\_registry\_id}/participants** This endpoint invites a participant to the trust registry with specified schemas they are allowed to issue or verify. Will be called by the trust registry convenor.

**Body:**

```json
{
  "verifierSchemas": ["http://example.org/schema/kvac"]
}
```

**POST /trust-registries/invitations/accept** This endpoint accepts an invitation to join a trust registry using a provided token. Will be called by a trust registry future member.

**Body:**

```json
{
  "did": "did:dock:verifier",
  "infoUrl": "https://info.org/verifier",
  "token": "inviteTokenVerifier"
}
```

### 2. Assign prices to schemas

Assign a price to the schema in the trust registry. Prices are specified in "digits" to support fractional cents, where 1 cent is represented as 1,000,000 digits. This ensures precision in transactions and avoids issues related to floating-point arithmetic.

**POST /trust-registries/{trust\_registry\_id}/schemas/{schema\_id}/price** This endpoint assigns a price to a schema within the trust registry, enabling it to be used for paid credentials.

**Body:**

```json
{
  "currency": "USD",
  "digits": 1000000  // Represents 1 cent
}
```

### 3. List schemas with prices

Retrieve and verify the list of schemas with their assigned prices.

**GET /trust-registries/{trust\_registry\_id}/schemas** This endpoint retrieves all schemas within a trust registry, including the prices assigned to each schema.

**Response:**

```json
[
  {
    "schema": "http://example.org/schema/kvac",
    "prices": [
      {
        "digits": 1000000,
        "currency": "USD",
        "trustRegistryId": "trust_registry_id",
        "trustRegistryMetadata": {
          ...
        }
      }
    ]
  }
]
```

### 4. Issue credentials

Issue credentials using the schemas. The credential must be a KVAC credential to enable paid credentials. The use of the `bbdt16` algorithm is required to enable KVAC and paid credentials.

**POST /credentials** This endpoint issues a KVAC credential based on the specified schema and issuer details.

**Body:**

```json
{
  "algorithm": "bbdt16",
  "credential": {
    "schema": "http://example.org/schema/kvac",
    "issuer": "did:dock:issuer",
    "name": "KVAC Credential",
    "issuanceDate": "2019-12-03T12:19:52Z",
    "expirationDate": "2029-12-03T12:19:52Z",
    "subject": {
      "id": "did:dock:subject",
      "name": "Subject Name",
      "favouriteDrink": "Coffee"
    }
  }
}
```

### 5. Create proof template

Create a proof template using the schema with a price associated and request for verification.

**POST /proof-templates** This endpoint creates a proof template specifying the requirements for verifying a credential.

**Body:**

```json
{
  "name": "KVAC Proof Template",
  "nonce": "1234567890",
  "request": {
    "name": "KVAC Request",
    "purpose": "KVAC Purpose",
    "input_descriptors": [
      {
        "id": "Credential 1",
        "name": "KVAC Request",
        "purpose": "KVAC Purpose",
        "constraints": {
          "fields": [
            { "path": ["$.credentialSchema.id"], "filter": { "const": "http://example.org/schema/kvac" } }
          ]
        }
      }
    ]
  }
}
```

### 6. Add the proof template to the trust registry

Add the proof template to the trust registry to enable it being used by other participants.

**POST /trust-registries/{trust\_registry\_id}/proof-templates** This endpoint adds a proof template to the trust registry, enabling it to be used for verification.

**Body:**

```json
{
  "id": "proof_template_id",
}
```

### 7. Create proof request

Create a proof request based on the proof template to verify the credential.

**POST /proof-templates/{template\_id}/request** This endpoint creates a proof request based on the specified proof template, which can then be used to verify a credential.

**Body:**

```json
{
  "did": "did:dock:verifier"
}
```

**Note:** Verifier DID is required when using paid schemas.

**Errors:**

* If using a did that is part of the trust registry but is not assigned as a verifier for that schema the verification process on step 6 will fail with the following error message: `Presentation could not be verified: Error: Verifier DID does not have permission to verify this credential`
* If using a did that is not part of the trust registry the verification process on step 6 will fail with the following message: `Presentation could not be verified: Error: This credential can only be verified by participants in the ${trust_registry_name} ecosystem. You can learn about the ecosystem by visiting this website: ${trust_registry_url}`

### 8. Verify presentation

Using the [Truvera Wallet](broken://pages/famFFWGPSQb2hQXJZLId), scan the QR code received and follow the process to submit the verification.

### 9. Retrieve trust registry reports

Fetch and verify trust registry reports to ensure proper billing and tracking.

**GET /trust-registries/{trust\_registry\_id}/reports** This endpoint retrieves reports from the trust registry, detailing verifications, fees, and other relevant information for auditing purposes.

**Response:**

```json
[
  {
    "trustRegistryId": "trust_registry_id",
    "verificationId": "572350a8-673a-490a-bed3-c001aa3f58a0",
    "verifierDID": "did:dock:verifier",
    "issuerDID": "did:dock:issuer",
    "schemaId": "http://example.org/schema/kvac",
    "currency": "USD",
    "verifierFee": "123456",
    "vendorFee": "6172",
    "created": "2024-08-08T08:53:50.524Z"
  }
]
```

### 10. Assigning additional schemas to participants

Add new schemas to the Ecosystem by assigning them to each participant.

**PATCH/trust-registries/{registryId}/participants/{participantId}** This endpoint allows updating the Trust Registry participant.

```json
{
  "name": "string",
  "logoUrl": "string",
  "infoUrl": "string",
  "status": "string",
  "suspendedAt": "string",
  "issuerSchemas": [
    "http://example.org/schema/kvac2",
    "http://example.org/schema/kvac3"
  ],
  "verifierSchemas": [
    "http://example.org/schema/kvac2",
    "http://example.org/schema/kvac3"
  ]
}
```


# Data

{% openapi src="/files/JRr1pCTFHx76mpRDdFlL" path="/data/notifications" method="get" %}
[updated\_openapi.yaml](https://815575130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWRMhdRsPkUzlSqCYzbgF%2Fuploads%2Fgit-blob-275cf229de21c78eb08b2b9375323ab201e4ea6e%2Fupdated_openapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/JRr1pCTFHx76mpRDdFlL" path="/data/profile" method="get" %}
[updated\_openapi.yaml](https://815575130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWRMhdRsPkUzlSqCYzbgF%2Fuploads%2Fgit-blob-275cf229de21c78eb08b2b9375323ab201e4ea6e%2Fupdated_openapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/JRr1pCTFHx76mpRDdFlL" path="/data/profile" method="patch" %}
[updated\_openapi.yaml](https://815575130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWRMhdRsPkUzlSqCYzbgF%2Fuploads%2Fgit-blob-275cf229de21c78eb08b2b9375323ab201e4ea6e%2Fupdated_openapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/JRr1pCTFHx76mpRDdFlL" path="/data/notifications/mark-read" method="post" %}
[updated\_openapi.yaml](https://815575130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWRMhdRsPkUzlSqCYzbgF%2Fuploads%2Fgit-blob-275cf229de21c78eb08b2b9375323ab201e4ea6e%2Fupdated_openapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/JRr1pCTFHx76mpRDdFlL" path="/data/onboarding" method="post" %}
[updated\_openapi.yaml](https://815575130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWRMhdRsPkUzlSqCYzbgF%2Fuploads%2Fgit-blob-275cf229de21c78eb08b2b9375323ab201e4ea6e%2Fupdated_openapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/JRr1pCTFHx76mpRDdFlL" path="/data/limits" method="get" %}
[updated\_openapi.yaml](https://815575130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWRMhdRsPkUzlSqCYzbgF%2Fuploads%2Fgit-blob-275cf229de21c78eb08b2b9375323ab201e4ea6e%2Fupdated_openapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/JRr1pCTFHx76mpRDdFlL" path="/data/history" method="get" %}
[updated\_openapi.yaml](https://815575130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWRMhdRsPkUzlSqCYzbgF%2Fuploads%2Fgit-blob-275cf229de21c78eb08b2b9375323ab201e4ea6e%2Fupdated_openapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/JRr1pCTFHx76mpRDdFlL" path="/data/transactions" method="get" %}
[updated\_openapi.yaml](https://815575130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWRMhdRsPkUzlSqCYzbgF%2Fuploads%2Fgit-blob-275cf229de21c78eb08b2b9375323ab201e4ea6e%2Fupdated_openapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/JRr1pCTFHx76mpRDdFlL" path="/data/stats" method="get" %}
[updated\_openapi.yaml](https://815575130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWRMhdRsPkUzlSqCYzbgF%2Fuploads%2Fgit-blob-275cf229de21c78eb08b2b9375323ab201e4ea6e%2Fupdated_openapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/JRr1pCTFHx76mpRDdFlL" path="/data/delete" method="post" %}
[updated\_openapi.yaml](https://815575130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWRMhdRsPkUzlSqCYzbgF%2Fuploads%2Fgit-blob-275cf229de21c78eb08b2b9375323ab201e4ea6e%2Fupdated_openapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/JRr1pCTFHx76mpRDdFlL" path="/data/accountdelete" method="post" %}
[updated\_openapi.yaml](https://815575130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWRMhdRsPkUzlSqCYzbgF%2Fuploads%2Fgit-blob-275cf229de21c78eb08b2b9375323ab201e4ea6e%2Fupdated_openapi.yaml?alt=media)
{% endopenapi %}


# Verify

## VCDM verification

VCDM verification is usually done in context of a presentation request as [documented with the presentations endpoint](/truvera-api/presentations). You probably do not want to call the verify endpoint directly.

This route allows manual verification of issued/received credentials and presentations. Verification will check that the JSON-LD document's cryptographic proof is correct and that it has not been revoked. It will return a verification status with a boolean verified result.

A verifier upon receiving a verifiable presentation verifies the validity of each credential in the presentation. This includes checking the correctness of the data model of the credential, the authenticity by verifying the issuer's signature and revocation status if the credential is revocable. It then checks whether the presentation contains the signature from the holder on the presentation, including the given challenge.

### Parameters <a href="#verify-a-credential-or-presentation-parameters" id="verify-a-credential-or-presentation-parameters"></a>

<table data-full-width="false"><thead><tr><th width="106">Name</th><th width="82">In</th><th width="205">Type</th><th width="89">Required</th><th>Description</th></tr></thead><tbody><tr><td>body</td><td>body</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemaverifiablecredential">VerifiableCredential</a> or <a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemaverifiablepresentation">VerifiablePresentation</a></td><td>true</td><td>Provide as the body a verifiable credential or verifiable presentation JSON-LD document.</td></tr></tbody></table>

## Verify a credential or presentation

> Verifies a VCDM credential or presentation as JSON or JWT string. More info about \[Verify Credentials/Presentations]\(<https://docs.truvera.io/developer-documentation/truvera-api/presentations>)

```json
{"openapi":"3.0.2","info":{"title":"Truvera API","version":"1"},"tags":[],"servers":[{"url":"https://api-testnet.truvera.io","description":"Sandbox server (uses test data)"},{"url":"https://api.truvera.io","description":"Production server (uses live data)"}],"security":[{"bearerAuth":[]},{"accessToken":[]},{"nextAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"},"accessToken":{"type":"apiKey","in":"header","name":"DOCK-API-TOKEN"},"nextAuth":{"type":"apiKey","in":"header","name":"CERTS-TOKEN"}},"schemas":{"VerificationResponse":{"description":"Whether a credential/presentation/anchor is verified or not","type":"object","properties":{"verified":{"type":"boolean"},"results":{"type":"array","items":{"type":"object"}}}},"Error":{"description":"An API Error","type":"object","properties":{"status":{"type":"integer"},"type":{"type":"string"},"message":{"type":"string"}}}}},"paths":{"/verify":{"post":{"tags":["verify"],"summary":"Verify a credential or presentation","description":"Verifies a VCDM credential or presentation as JSON or JWT string. More info about [Verify Credentials/Presentations](https://docs.truvera.io/developer-documentation/truvera-api/presentations)","requestBody":{"description":"JSON verifiable presentation","required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"The verification result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationResponse"}}}},"400":{"description":"Invalid/insufficient credential params.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Transaction limit reached or upgrade required to proceed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```


# Keys

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/keys" method="get" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/keys" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/keys/{publicKey}" method="delete" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/keys/{publicKey}" method="patch" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}

{% openapi src="<https://swagger-api.truvera.io/openapi.yaml>" path="/keys/temporary-key" method="post" %}
<https://swagger-api.truvera.io/openapi.yaml>
{% endopenapi %}


# Schemas

Data Schemas are useful when enforcing a specific structure on a collection of data like a Verifiable Credential. Other than that, Data Verification schema and Data Encoding Schemas are used to verify and map the structure and contents of a Verifiable Credential.

These are the schemas used in all API operations mentioned before, such as Error, Credential, Jobs, Anchor, Registry, and so on.

For a detailed example of the schema workflow. Please refer [here](https://github.com/docknetwork/dock-api-js/blob/main/workflows/schemaFlow.js).

## Error <a href="#tocs_error" id="tocs_error"></a>

This is a schema for an API Error.

#### Properties

<table data-full-width="false"><thead><tr><th width="138">Name</th><th width="131">Type</th><th width="176">Required</th><th>Description</th></tr></thead><tbody><tr><td>status</td><td>integer</td><td>false</td><td>Status of the error.</td></tr><tr><td>type</td><td>string</td><td>false</td><td>Type of the error.</td></tr><tr><td>message</td><td>string</td><td>false</td><td>Message of the error.</td></tr></tbody></table>

<details>

<summary>Object Schemas</summary>

```json
{
  "status": 0,
  "type": "string",
  "message": "string"
}

```

</details>

## Hex32 <a href="#tocs_hex32" id="tocs_hex32"></a>

32 byte hex string. Ignoring higher base (base64) for simplicity.

### Properties

<table data-full-width="false"><thead><tr><th width="100">Name</th><th width="99">Type</th><th width="114">Required</th><th>Description</th></tr></thead><tbody><tr><td>Hex32</td><td>string</td><td>false</td><td>32 byte hex string. Ignoring higher base (base64) for simplicity.</td></tr></tbody></table>

```json
"string"
```

## JobStartedResult <a href="#tocs_jobstartedresult" id="tocs_jobstartedresult"></a>

Object containing unique id of the background task and associated data. This id can be used to query the job status.

### Properties

<table data-full-width="false"><thead><tr><th width="110">Name</th><th width="130">Type</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemajobid">JobId</a></td><td>Unique id of the background task. This id can be used to query the job status.</td></tr><tr><td>data</td><td>object</td><td>Data of the object.</td></tr></tbody></table>

```json
{
  "id": "string",
  "data": {
    "did": "did:dock:xyz",
    "hexDid": "0x00",
  }
}
```

## JobId <a href="#tocs_jobid" id="tocs_jobid"></a>

Unique id of the background task. This id can be used to query the job status

```json
"string"
```

## JobStatus <a href="#tocs_jobstatus" id="tocs_jobstatus"></a>

This is a schema used in Job operation to get a status of the job.

#### Enumerated values

<table data-full-width="false"><thead><tr><th width="158">Property</th><th width="323">Value</th><th>Description</th></tr></thead><tbody><tr><td>JobStatus</td><td>todo <strong>or</strong> finalized <strong>or</strong> in_progress <strong>or</strong> error.</td><td>Job Status variants.</td></tr></tbody></table>

```json
"in_progress"
```

## JobDesc <a href="#tocs_jobdesc" id="tocs_jobdesc"></a>

This is a schema used in Job operation to get description of the job including the result if it is available.

### Properties

<table data-full-width="false"><thead><tr><th width="121">Name</th><th width="142">Type</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemajobid">JobId</a></td><td>Unique id of the background task. This id can be used to query the job status.</td></tr><tr><td>status</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemajobstatus">JobStatus</a></td><td>Status of the job.</td></tr><tr><td>result</td><td>object</td><td>false</td></tr></tbody></table>

```json
{
  "id": "string",
  "result": {},
  "status": "todo",

}
```

## DIDDock <a href="#tocs_diddock" id="tocs_diddock"></a>

DID as fully qualified, e.g., `did:dock:`.

### Properties

<table data-full-width="false"><thead><tr><th width="93">Name</th><th width="99">Type</th><th width="119">Required</th><th>Description</th></tr></thead><tbody><tr><td>DID</td><td>string</td><td>false</td><td>DID as fully qualified, e.g., <code>did:dock:</code>. You cannot specify your own DID, the DID value will be randomly generated.</td></tr></tbody></table>

```json
"did:dock:xyz"
```

## KeyType <a href="#tocs_keytype" id="tocs_keytype"></a>

This is a schema type of public key for DID.

### Enumerated Values

<table><thead><tr><th width="142">Property</th><th width="318">Value</th><th>Description</th></tr></thead><tbody><tr><td>KeyType</td><td>sr25519 <strong>or</strong> ed25519 <strong>or</strong> secp256k1</td><td>keyType DID variants.</td></tr></tbody></table>

```json
"sr25519"
```

## SigType <a href="#tocs_sigtype" id="tocs_sigtype"></a>

This is a schema used in Presentation operation that represents a type of signature.

### Enumerated Values

<table><thead><tr><th width="135">Property</th><th width="364">Value</th><th>Description</th></tr></thead><tbody><tr><td>SigType</td><td>Sr25519Signature2020 <strong>or</strong> Ed25519Signature2018 <strong>or</strong> EcdsaSecp256k1Signature2019</td><td>SigType signature variants.</td></tr></tbody></table>

```json
"Sr25519Signature2020"
```

## ProofPurpose <a href="#tocs_proofpurpose" id="tocs_proofpurpose"></a>

This is a schema that represents a purpose of credential.

### Enumerated values

<table><thead><tr><th width="170">Property</th><th width="309">Value</th><th>Description</th></tr></thead><tbody><tr><td>ProofPurpose</td><td>assertionMethod <strong>or</strong> authentication</td><td>Purpose of credential.</td></tr></tbody></table>

```json
"assertionMethod"
```

## Context <a href="#tocs_context" id="tocs_context"></a>

This is a schema that represents a JSON-LD context used in DID and Presentation.

```json
[
  "string"
]
```

## DIDDoc <a href="#tocs_diddoc" id="tocs_diddoc"></a>

This is a schema that represents a DID document. The current set of properties is incomplete

### Properties

<table><thead><tr><th width="161">Name</th><th width="120">Type</th><th width="117">Required</th><th>Description</th></tr></thead><tbody><tr><td>@context</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemacontext">Context</a></td><td>false</td><td>JSON-LD context.</td></tr><tr><td>id</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemadiddock">DIDDock</a></td><td>false</td><td>DID as fully qualified, e.g., <code>did:dock:</code>.</td></tr><tr><td>authentication</td><td>array</td><td>false</td><td>DID authentication.</td></tr></tbody></table>

<details>

<summary>OBJECT SCHEMAS</summary>

```json
{
  "@context": [
    "string"
  ],
  "id": "did:dock:xyz",
  "authentication": [
    {}
  ]
}
```

</details>

## Credential <a href="#tocs_credential" id="tocs_credential"></a>

This is a schema that represents a credential format expected by API caller when issuing a credential.

### Properties

<table data-full-width="false"><thead><tr><th width="121">Name</th><th width="153">Type</th><th width="102">Required</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>string(uri)</td><td>false</td><td>Credential ID. The default value is a creds.dock.io uri with random ID.</td></tr><tr><td>context</td><td>[string or object]</td><td>false</td><td>Credential context array of string URIs and/or embedded JSON-LD context objects. If no context parameter is supplied, we will auto generate contexts for you. If you do supply this parameter, you must ensure that all JSON-LD terms are defined. This is for advanced users.</td></tr><tr><td>type</td><td>[string]</td><td>false</td><td>Credential type. The default value is ['VerifiableCredential']</td></tr><tr><td>subject</td><td>object or [object]</td><td>true</td><td>Credential subject or subjects array.</td></tr><tr><td>schema</td><td>string</td><td>false</td><td>Schema ID returned by create schema route or a valid URI</td></tr><tr><td>issuer</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemadiddock">DIDDock</a></td><td>false</td><td>Credential issuer. DID as fully qualified, e.g., <code>did:dock:</code>. If not supplied the credential will not be signed.</td></tr><tr><td>issuanceDate</td><td>string(date-time[RFC3339])</td><td>false</td><td>The date and time in GMT that the credential was issued specified in RFC 3339 format. The issuanceDate will be automatically set if not provided.</td></tr><tr><td>expirationDate</td><td>string(date-time[RFC3339])</td><td>false</td><td>The date and time in GMT that the credential expired is specified in RFC 3339 format. The default value of the expirationDate will be empty if the user does not provide it.</td></tr><tr><td>status</td><td>object or string</td><td>false</td><td>Revocation registry id or user supplied status object containg a Dock revocation registry identifier.</td></tr></tbody></table>

<details>

<summary>OBJECT SCHEMAS</summary>

```json
{
  "context": [
    "string"
  ],
  "type": [
    "string"
  ],
  "subject": {},
  "issuer": "did:dock:xyz",
  "issuanceDate": "2019-08-24T14:15:22Z",
  "expirationDate": "2019-08-24T14:15:22Z",
  "status": "90b7dc6e8642bf1425c5a5ef2c3ff62bb689770843fdc0e2d79b97beb6c73311"
}
```

</details>

## VerifiablePresentation <a href="#tocs_verifiablepresentation" id="tocs_verifiablepresentation"></a>

This is a schema that represents a Verifiable (signed) Presentation returned by API. The current set of properties is almost complete

### Properties

<table data-full-width="false"><thead><tr><th width="144">Name</th><th width="163">Type</th><th width="121">Required</th><th>Description</th></tr></thead><tbody><tr><td>@context</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemacontext">Context</a></td><td>true</td><td>JSON-LD context.</td></tr><tr><td>id</td><td>string(uri)</td><td>true</td><td>Verifiable (signed) presentation id.</td></tr><tr><td>type</td><td>string</td><td>true</td><td>Verifiable (signed) presentation type.</td></tr><tr><td>verifiableCredential</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemaverifiablecredential">VerifiableCredential</a></td><td>true</td><td>Verifiable (signed) Credential returned by API. The current set of properties is almost complete.</td></tr><tr><td>proof</td><td>object</td><td>true</td><td>Proof of credential.</td></tr></tbody></table>

### Child properties of proof <a href="#proofchildpropertiespresentation" id="proofchildpropertiespresentation"></a>

<table data-full-width="false"><thead><tr><th width="162">Name</th><th width="155">Type</th><th width="112">Required</th><th>Description</th></tr></thead><tbody><tr><td>type</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemasigtype">SigType</a></td><td>true</td><td>Type of signature.</td></tr><tr><td>proofPurpose</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemaproofpurpose">ProofPurpose</a></td><td>true</td><td>Purpose of credential.</td></tr><tr><td>verificationMethod</td><td>string</td><td>true</td><td>Verification method.</td></tr><tr><td>created</td><td>string(date-time[RFC3339])</td><td>true</td><td>The date and time in GMT that the credential was created specified in RFC 3339 format.</td></tr><tr><td>proofValue</td><td>string</td><td>true</td><td>none</td></tr></tbody></table>

<details>

<summary>OBJECT SCHEMAS</summary>

```json
{
  "@context": [
    "string"
  ],
  "id": "http://example.com",
  "type": [
    "string"
  ],
  "verifiableCredential": {
    "@context": [
      "string"
    ],
    "id": "https://creds.dock.io/f087cbfabc90f8b996971ba47598e82b1a03523cb9460217ad58a819cd9c09eb",
    "type": [
      "string"
    ],
    "credentialSubject": {},
    "issuer": "did:dock:xyz",
    "issuanceDate": "2019-08-24T14:15:22Z",
    "expirationDate": "2019-08-24T14:15:22Z",
    "credentialStatus": {},
    "proof": {
      "type": "Sr25519Signature2020",
      "proofPurpose": "assertionMethod",
      "verificationMethod": "string",
      "created": "2019-08-24T14:15:22Z",
      "proofValue": "string"
    }
  },
  "proof": {
    "type": "Sr25519Signature2020",
    "proofPurpose": "assertionMethod",
    "verificationMethod": "string",
    "created": "2019-08-24T14:15:22Z",
    "proofValue": "string"
  }
}
```

</details>

## VerifiableCredential

This is a schema that represents a verifiable (signed) Credential returned by API. The current set of properties is almost complete.

### Properties

<table data-full-width="false"><thead><tr><th width="155">Name</th><th width="127">Type</th><th width="107">Required</th><th>Description</th></tr></thead><tbody><tr><td>@context</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemacontext">Context</a></td><td>false</td><td>JSON-LD context.</td></tr><tr><td>id</td><td>string(uri)</td><td>false</td><td>Credential id.</td></tr><tr><td>type</td><td>[string]</td><td>false</td><td>Credential type.</td></tr><tr><td>credentialSubject</td><td>any</td><td>false</td><td>Credential subject.</td></tr><tr><td>issuer</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemadiddock">DIDDock</a></td><td>false</td><td>Credential issuer or DID as fully qualified, e.g., <code>did:dock:</code>.</td></tr><tr><td>issuanceDate</td><td>string(date-time[RFC3339])</td><td>false</td><td>The date and time in GMT that the credential was issued specified in RFC 3339 format. The issuanceDate will be automatically set if not provided.</td></tr><tr><td>expirationDate</td><td>string(date-time[RFC3339])</td><td>false</td><td>The date and time in GMT that the credential expired is specified in RFC 3339 format. The default value of the expirationDate will be empty if the user does not provide it.</td></tr><tr><td>credentialStatus</td><td>any</td><td>false</td><td>Revocation registry id or user supplied status object.</td></tr><tr><td>proof</td><td>object</td><td>false</td><td>Proof of credential.</td></tr></tbody></table>

### Child properties of proof <a href="#proofchildpropertiescredentials" id="proofchildpropertiescredentials"></a>

<table data-full-width="false"><thead><tr><th width="164">Name</th><th width="151">Type</th><th width="129">Required</th><th>Description</th></tr></thead><tbody><tr><td>type</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemasigtype">SigType</a></td><td>false</td><td>Type of signature.</td></tr><tr><td>proofPurpose</td><td><a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemaproofpurpose">ProofPurpose</a></td><td>false</td><td>Purpose of credential.</td></tr><tr><td>verificationMethod</td><td>string</td><td>false</td><td>Verification method.</td></tr><tr><td>created</td><td>string(date-time[RFC3339])</td><td>false</td><td>The date and time in GMT that the credential was created specified in RFC 3339 format.</td></tr><tr><td>proofValue</td><td>string</td><td>false</td><td>Value of credential.</td></tr></tbody></table>

<details>

<summary>OBJECT SCHEMAS</summary>

```json
{
  "@context": [
    "string"
  ],
  "id": "https://creds.dock.io/f087cbfabc90f8b996971ba47598e82b1a03523cb9460217ad58a819cd9c09eb",
  "type": [
    "string"
  ],
  "credentialSubject": {},
  "issuer": "did:dock:xyz",
  "issuanceDate": "2019-08-24T14:15:22Z",
  "expirationDate": "2019-08-24T14:15:22Z",
  "credentialStatus": {},
  "proof": {
    "type": "Sr25519Signature2020",
    "proofPurpose": "assertionMethod",
    "verificationMethod": "string",
    "created": "2019-08-24T14:15:22Z",
    "proofValue": "string"
  }
}
```

</details>

## Registry <a href="#tocs_registry" id="tocs_registry"></a>

This is a schema that represents a Revocation registry used in Revocation or Unrevocation.

### Properties

<table data-full-width="false"><thead><tr><th width="128">Name</th><th width="115">Type</th><th width="112">Required</th><th>Description</th></tr></thead><tbody><tr><td>addOnly</td><td>boolean</td><td>false</td><td>If the <code>addOnly</code> value is true, they cannot unrevoke and delete the registry. The default value for this is <code>false</code>.</td></tr><tr><td>policy</td><td>[<a href="https://github.com/docknetwork/knowledgebase-docs/blob/main/developer-documentation/dock-api/index.html.md#schemadiddock">DIDDock</a>]</td><td>false</td><td>Only one policy supported as of now called <code>OneOf</code>.</td></tr></tbody></table>

```json
{
  "addOnly": true,
  "policy": [
    "did:dock:xyz"
  ]
}
```

## VerificationResponse <a href="#tocs_verificationresponse" id="tocs_verificationresponse"></a>

This is a schema that is used to define whether a credential/presentation is verified or not

```json
{
  "verified": true,
  "results": [...]
}
```

## Response <a href="#tocs_response" id="tocs_response"></a>

This is a schema that represents a default response for a request made.

```json
{
  "code": 0
}
```

## Message <a href="#tocs_message" id="tocs_message"></a>

This is a schema that represents a message send request. If the message is signed or encrypted use the `ciphertext` field. The `typ` field must be a valid DIDComm message type.

```json
{
  "to": ["did:example:bob"],
  "ciphertext": "eyJhsad...AQ",
  "typ":"application/didcomm..."
}
```


# System architecture

## Architectural overview

### Components

* Truvera API
  * AWS
    * us-west-1 (Northern California)
* Truvera Workspace
  * Vercel
    * us-west-1 (Northern California)
* Relay Service and EDV
  * Vercel
    * us-west-1 (Northern California)
  * MongoDB
    * us-west-1 (Northern California)
* Blockchain (Dock owned validators)
  * AWS
    * us-west-1 (Northern California)
    * us-east-1 (North Virginia)
    * us-east-2 (Ohio)
    * eu-central-2 (Zurich)
    * eu-west-2 (London)

### Truvera network diagram

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

### Data storage details

Truvera strives to minimize the data it stores and works to follow SSI best practices of keeping private data with the individual it belongs to. Below we outline what data is used each component of our system.

Truvera API:

* Issuer metadata (name, logo, etc.)
* VC metadata (id, issue date, etc.)
* Subject reference field\*
* Verification history\*
* Persisted VC’s\* (optional)
* Raw credential data is only stored in memory during issuance and is dropped immediately after

*\* may contain PII*

Relay Service:

* Temporary storage of encrypted VC’s
* Can only be decrypted by recipient DID
* Message deleted once retrieved by recipient

### Blockchain

The blockchain used (if any) depends on the DID method selected when configuring an organization profile. A public blockchain provides Truvera users with assurance that their identity data is not locked-in to the platform. As long as the blockchain can be read, previously issued credentials in standard credential formats remain verifiable.

We recommend the [cheqd blockchain](https://cheqd.io/) built in the Cosmos ecosystem because it is mature, decentralized, public, and permissionless. The Truvera API abstracts the complexity of blockchain transactions and the associated token fees.

We are cautious that user PII, including hashed data, is never written to a public blockchain. User credential information is never written to the chain. Wallet DIDs are in DID:key format and are not stored on-chain.

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


# Proposed architecture with Truvera

## Basic architecture

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

## APIs - Truvera’s VC service

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

## Supported APIs

|                     | Truvera VC Service       | 3rd Party VC Service     |
| ------------------- | ------------------------ | ------------------------ |
| Truvera wallet SDKs | <p>OID4VC<br>DIDcomm</p> | <p>OID4VC<br>DIDcomm</p> |
| 3rd Party Wallet    | <p>OID4VC<br>DIDcomm</p> | Unsupported              |

## Integration with customer systems

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

## Credential request flow

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


# Revocation

Credential revocation is managed with on-chain revocation registries. To revoke a credential, its id (or hash of its id) must be added to the credential. It is advised to have one revocation registry per credential type. Each registry has a unique id and an associated policy. The policy determines who can update the revocation registry.

{% hint style="info" %}
A revocation registry is shared between all the schemas of the same organisation profile.
{% endhint %}

{% hint style="warning" %}
The same revocation registry should be reused for thousands of credentials. It speeds up issuance and increases privacy.
{% endhint %}

## W3C Status List 2021

The default trust registry in Truvera Workspace for non-anonymous credentials is the VC Status List. It is the best choice for most users of non-anonymous credentials, but requires disclosure of a revocation id to identify which credential is being revoked. This can be avoided by using Truvera's anonymous credentials, where you prove that the revocation id is not in "the list" (accumulator) without disclosing the id itself.

This registry is good for interoperability, because it follows the [W3C standard](https://www.w3.org/community/reports/credentials/CG-FINAL-vc-status-list-2021-20230102/).

It tracks all revocation entries in a single data type.

The blockchain transaction to revoke multiple credentials at once is less expensive than the Truvera Revocation Registry.

The Status List supports both a revocation and suspension flag. An id that is added to the registry with a suspended flag can be removed, which undoes the revocation. Adding an id to the registry with the revoked flag is permanent. When triggering a credential revocation, the Truvera API uses the suspended flag by default.

## Truvera Revocation Registry

This is the original approach to revocation for non-anonymous credentials that is implemented with a private status list. It is the preferred approach only in specific scenarios.

Truvera revocation registry blockchain transactions have a different cost profile than a Status List. It consumes more space on the ledger for multiple entries, so it is more expensive when revoking in batches but less expensive for a single entry (when revoking a single credential at one time).

The Truvera revocation registry requires disclosure of a revocation id that wouldn't otherwise be disclosed with Truvera's anonymous credentials.

The registry has an "add-only" flag specifying whether an id once added to the registry can be removed (leading to undoing the revocation) or not.

For now, only one policy is supported which is that each registry is owned by a single DID. Also, neither the policy nor the "add-only" flag can be updated post the creation of the registry for now.

## Anonymous Credential Revocation

We use [VB and KB universal types](https://github.com/docknetwork/crypto/tree/main/vb_accumulator) of accumulators for anonymous credential revocation. They have different properties, but both are bilinear map pairing based accumulators.

Truvera Anonymous Credential Revocation has specific advantages over a Status List:

* *Superior Cryptographic Verification:* Accumulators provide strong cryptographic guarantees of membership, unlike status lists which rely on simple lookups that lack the same mathematical security properties.
* *Enhanced Privacy Through Zero-Knowledge:* Unlike status lists (such as W3C VC Status List) which require disclosure of revocation IDs, accumulators enable proving non-revocation without disclosing which particular credential ID is being verified, allowing for anonymous credential revocation.
* *Consistently Efficient Storage:* While status lists grow linearly with each new element added, accumulators maintain constant-size representations regardless of how many credentials are included, ensuring storage requirements remain minimal even at massive scale.
* *Comprehensive Privacy Protection:* Accumulators offer fundamentally stronger privacy preservation than status lists, making them substantially better suited for applications where confidentiality of both membership and the specific credentials being verified is critical, particularly for anonymous credential systems.
* *Witness-Based Verification:* Accumulators utilize a witness-based approach that allows holders to prove non-revocation without revealing their credential identifier, unlike status lists which require direct disclosure of the identifier being checked.

#### Key terms

* Credential identifier
* Witness - additional information provided to the credential holder. The witness is issued to the Holder during the initial issuance process and needs to be re-issued or updated after each revocation process.
* Accumulator - one-way function that sums a large set of items into a single accumulator value. The membership of an included item can be proved using the accumulator, the item itself, and a witness. [Read more](https://github.com/docknetwork/crypto-wasm-ts/?tab=readme-ov-file#accumulator)
* Update transactions - contain the additions, removals and witness update polynomial for the update.

#### Anonymous revocation process

* Issuer uses the credential identifier of an issued credential to generate an accumulator that gets stored on the blockchain.
* Issuer provides the holder with the credential and the witness.
* During revocation, issuer puts an update transaction on the blockchain that updates the accumulator and that the holder can use to update their witness. The most recent accumulator is present in the blockchain state and updates are stored in “calldata” which can be fetched with blockchain events.
* Holder uses the witness, accumulator, and the updates to generate an updated witness which is then used to create the proof of non-revocation by showing that their credential identifier is included in the accumulator.

#### Additional resources

* [The Rust codebase of the accumulators](https://github.com/docknetwork/crypto/tree/main/vb_accumulator). Contains additional documentation, including links to the 2 papers used for our implementation.
* [Anoncreds Tutorial](https://docknetwork.github.io/sdk/tutorials/tutorial_anoncreds.html)


# System scalability

This document explains how we audit the systems scalability.

## Architecture

Truvera's SaaS systems are engineered for scalability using tools from Amazon AWS and MongoDB Atlas.

## Service level agreements

Our contractual SLAs are listed in our [MSA](https://www.dock.io/master-services-agreement).

## API performance benchmarks

We regularly test our platform to ensure we can meet our performance benchmarks. Verifiable credential implementations are unique for every project. It is configured with a different number of DIDs, ecosystems, different types and numbers of VCs. Those different combinations may affect the application performances differently and are tested separately.

### Creating DID

* **Throughput:** Maximum of 90 requests/second, average of 75 requests/second
* **Response Times**:
  * Average: 200 ms
  * 95% Percentile: 300 ms
  * Maximum: 3000 ms

### Issue non anonymous credential

* **Throughput:** Maximum of 78 requests/second, average of 50 requests/second
* **Response Times**:
  * Average: 343 ms
  * 95% Percentile: 1 s
  * Maximum: 6 s

### Issue anonymous credential

* **Throughput:** Maximum of 74 requests/second, average of 49 requests/second
* **Response Times**:
  * Average: 452 ms
  * 95% Percentile: 2 seconds
  * Maximum: 6 seconds

### Verify non-anonymous credential

* **Throughput:** Maximum of 80 requests/second, average of 54 requests/second
* **Response Times**:
  * Average: 340 ms
  * 95% Percentile: 414 ms
  * Maximum: 1 s

### Verify anonymous credential

* **Throughput:** Maximum of 75 requests/second, average of 49 requests/second
* **Response Times**:
  * Average: 386 ms
  * 95% Percentile: 485 ms
  * Maximum: 2 s

{% hint style="info" %}
**95% Percentile Response Time**: Indicates that 95% of the requests were served within this time.
{% endhint %}


# Security policies

Dock Labs strives to follow best practices for information management and system security.

Specific practices include:

* Strategic Alignment: Aligning security objectives with the overall business strategy to support organizational goals.
* Leadership Oversight: Managed by a dedicated security manager and subject to regular policy reviews.
* People Security: Includes confidentiality agreements and mandatory security training. All new hires receive security training as part of on boarding and all team member continue to receive annual security training. This training encompasses key areas such as avoiding phishing attacks and other security best practices, ensuring continuous skill enhancement in security roles.
* Physical and Remote Work Protocols: Focuses on secure remote work practices, including device security and data protection.
* Access Control: Enforces the least privilege principle and conducts regular access audits. Our access management policies detail risks associated with system and data access, specifying procedures for granting, monitoring, and revoking access.
* Robust Password and Data Policies: Ensures strong password use and responsible data management.
* Change Management: Follows documented procedures for system changes and development.
* Disaster Recovery: Implements effective backup strategies for business continuity.
* Incident Response and Preparedness: Developing and maintaining robust incident response plans.
* Vendor Management: Utilizes proactive monitoring and collaborates with security-conscious vendors.
* Continuous Policy Enforcement and Updates: Enforces strict adherence to security policies, with annual reviews for relevancy.
* Risk Management: Identifying, assessing, and mitigating risks to maintain the integrity, confidentiality, and availability of information.
* Compliance and Legal Requirements: Ensuring adherence to relevant laws, regulations, and industry standards.
* Documentation Storage: All risk-related documentation, including NDAs, confidentiality agreements, and access management policies, are securely stored in designated, secure repositories, accessible only to authorized personnel. We maintain an audit trail for any changes to these documents.
* Documented Evidence: Our strategy and security objectives are formally documented in our strategic planning documents and Information Security Policy. These documents detail the specific goals, responsibilities, and procedures that govern our approach to security and overall business strategy. They are reviewed and approved by the management team and are subject to regular updates to reflect evolving business needs and security landscapes.
* Continuous Improvement: Regularly reviewing and updating security policies and procedures to address emerging threats and changes in the business environment.

We additionally follow specific architectural and coding practices such as:

* Minimize the storage of Personally Identifiable Information (PII)
* Encrypt data in transit and at rest
* Production logs do not contain user data
* System anomalies are automatically reported to employees so they can be triaged in a timely manner
* All changes must be reviewed by a team member before deployment


# How data is processed and stored

Truvera is designed to balance the requirements of user convenience with privacy and security. This document explains how we make those trade-offs in each part of the platform. This document does not replace the [Dock Labs Master Services Agreement](https://www.dock.io/master-services-agreement) or Data Processing Agreement, but provides additional insight into our architecture and practices.

The Truvera platform is intended to be deployed within a user-facing identity solution configured by a customer of Dock Labs or one of our integration partners. The security and privacy characteristics of the delivered solution might be different from the characteristics of the Truvera platform documented here. We attempt to call out relevant security considerations in the discussion below.

## Truvera Workspace and API

Organizations use Truvera’s API to set up their identity solution and interact with credentials. In order to make the system easy to use, Truvera stores the organization’s information in the system database. Data which is intended to be private, such as the private keys used to establish ownership of Decentralized IDentifiers (DIDs) and for signing, is encrypted on a per-row basis for each organization. Other data in the database includes presentation templates, PDF designs, verification templates, ecosystem membership, and activity logs. Data which is intended to be public, such as schemas and organization profile logos, is stored in AWS S3 with a public URL. Organizations can set up subaccounts to track the solution information of their customers. There is no way for an organization to access the information of a different organization. Depending on the DID method selected when setting up an organization profile, organization DIDs, revocation registries, and ecosystem information also may be stored on an external blockchain for public access (see below).

Organizations use the API or Truvera Workspace to submit credentials for issuance. These credentials often contain PII of the credential holder. This information is deleted immediately after processing.

Similarly, organizations use the API or Truvera Workspace to verify credential information shared as part of a proof presentation. This information is stored until it is delivered to the verifier either synchronously or via a webhook. The verifier should then call the delete endpoint to purge the information from Truvera.

Organization information is accessible in two ways: 1) through a Truvera Workspace account that is part of the organization’s team and which is protected by an email address or oAuth federated login or 2) through an API key. Users are encouraged to carefully protect these methods of system access. Should access be abused, team members can be removed from an organization and API keys can be revoked.

The Truvera Workspace uses Firebase and Google Analytics to track anonymized user activity so that we can improve the service for all users.

## Truvera Credential Wallets

Credential holders store their credentials in a Truvera Credential Wallet built with the Truvera Wallet SDK. There are two options for storing credentials: on-device or in the cloud.

On-device storage keeps all credential data in an Encrypted Data Vault (EDV). This is usually used in mobile applications, as persistent browser storage can be challenging to configure. Though the process for unlocking the wallet can be customized, mobile applications that use on-device storage will generally put the key for the wallet in the mobile operating system’s keystore. Dock Labs does not have access to the encryption keys or credential data.

Wallet applications can also be configured to use Truvera’s cloud wallet for storage. Our SaaS cloud wallet is an EDV that stores information for multiple users in the same vault. The information is end-to-end encrypted using a key generated in the application. This key is normally derived from a biometric configured by the developer integrating our platform into a user-facing identity solution. A hash of the encryption key is used as the index to the holder’s credential data in the EDV. Credentials can be searched by field name, but the field contents are opaque. Dock Labs does not have access to the encryption keys, but the identity solution that generates the key must be trusted by the user to not access their wallets inappropriately. Credential data that is stored in the cloud wallet may also be cached in the EDV of the edge device for quick access and offline use.

Solution developers can also choose to host their own EDV service accessible by the Truvera Wallet SDK. The API of that service is the same as the Truvera SaaS cloud wallet, but its security posture could be significantly different. Holders should investigate the design of any identity wallet that they use.

Truvera has a deprecated feature to persist issued credentials so that holders can later import them into a wallet using a password provided by the issuer. Instead of using this feature, we recommend setting up a cloud wallet using the user’s biometric collected during verification with the issuer and issuing the credential into that wallet. If it is not possible to set up a wallet, a credential offer should be given to the holder which will result in the credential being issued when the offer is accessed by the holder’s wallet.

Other wallet information may be stored unencrypted in the wallet database, such as the DID:keys associated with the wallet. Credential data is transmitted through a relay service which allows Truvera to route messages to the correct wallet using one of its DIDs. Communication with the relay service is done with encrypted messages using the DIDComm Mediator protocol and the messages are deleted once they are retrieved by the client. These messages are delivered to the correct mobile application with push notifications using Google Firebase.

Truvera’s white label wallets use Firebase and Google Analytics to track anonymized user activity so that we can improve the service for all users.

## General considerations

The SaaS components of the Truvera platform are hosted in the United States (AWS Northern California Availability Zone). European data is processed under the terms of the US-EU Data Sharing Standard Contractual Clauses which are incorporated into our MSA.

Logging for our production systems does not contain PII of any kind. Logging on our public test systems may contain customer information when an error is reported, so we encourage customers not to use real PII when issuing test credentials. We perform internal audits to ensure that our practices conform with this policy.

The above mentioned data storage is preserved in nightly encrypted backups for disaster recovery.

As noted above, some data is stored on a blockchain in order to provide our customers assurance that their identity solution is not locked-in to our services. The specifics of blockchain storage will depend on the DID method selected. Our default blockchain is did:cheqd, which is a Cosmos based proof-of-stake network with a globally diverse set of validators. Information about organizations may be stored on a blockchain, such as organization DIDs, ecosystem information such as the participating organizations, and revocation registries.

Holder information is never stored on a blockchain, with the exception of credential revocation status which is stored in a privacy preserving manner. Revocation registries based on the W3C Bitstring Status List are used in many solutions, though they allow some types of verifier correlation. We also support an accumulator based revocation registry with improved privacy characteristics. You can learn more [in the relevant documentation](/system-architecture/revocation).

The Truvera system will continue to evolve to give our customers more control over how their data is stored and processed. If you have any questions about how we process data, please contact our support team.


# Supported standards

Truvera is built on W3C open standards, it ensures that users can store their credentials on any digital wallet that adheres to these standards and that any stakeholder, wherever they are in the world, can verify the authenticity of the data as long as their verification system adheres to these standards. If there is a standard for which you would like further clarification or support, please [contact us](/support).

## Standards bodies

* [World Wide Web Consortium (W3C)](https://www.w3.org/)
* [OpenID Foundation (OIDF)](https://openid.net/foundation/)
* [Decentralized Identity Foundation (DIF)](https://identity.foundation/)
* [Internet Engineering Task Force (IETF)](https://www.ietf.org/)

## Supported standards

Dock Supports the following open standards:

<table><thead><tr><th width="180">Technology</th><th width="367">Open Standard</th><th>Standard Body</th></tr></thead><tbody><tr><td>Data model</td><td><a href="https://www.w3.org/TR/2022/REC-vc-data-model-20220303/">W3C Verifiable Credentials (VCs) Data Model v1.1</a></td><td>W3C</td></tr><tr><td>Credential variant</td><td><p>Non-Anonymous</p><p><a href="https://www.w3.org/TR/vc-data-model/#json-web-token">W3C-VC with JWT (API only)</a></p><p><a href="https://www.w3.org/TR/vc-data-model/#json-ld">W3C-VC with JSON-LD and Ed25519Signature2020</a></p><p>Anonymous</p><p><a href="https://github.com/docknetwork/crypto-wasm-ts/tree/master/src/anonymous-credentials">W3C JSON-LD with BBS2023</a></p><p><a href="https://github.com/docknetwork/crypto-wasm-ts/tree/master/src/accumulator">W3C JSON-LD with BBDT16</a></p></td><td>W3C<br>IETF</td></tr><tr><td>Decentralized Identifier</td><td><p><a href="https://docs.cheqd.io/product/architecture/adr-list/adr-001-cheqd-did-method">DID:cheqd</a></p><p><a href="https://w3c-ccg.github.io/did-method-key/">DID:key</a></p></td><td>W3C</td></tr><tr><td>Credential Issuance</td><td><a href="https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0-14.html">OpenID for Verifiable Credential Issuance - draft 14</a><br></td><td>OIDF</td></tr><tr><td>Presentation</td><td>Default presentation exchange from <a href="https://identity.foundation/waci-didcomm/">DIF Wallet and Credential Interaction (WACI) v1.0 Draft</a> over <a href="https://identity.foundation/didcomm-messaging/spec/v2.1">DIDComm Messaging v2.1</a><br><a href="https://openid.net/specs/openid-4-verifiable-presentations-1_0-ID3.html">OpenID for Verifiable Presentations - draft 23</a><br></td><td>DIF<br>OIDF</td></tr><tr><td>Revocation</td><td><a href="https://www.w3.org/community/reports/credentials/CG-FINAL-vc-status-list-2021-20230102/">Verifiable Credential Status List 2021</a></td><td>W3C</td></tr><tr><td>Credential Wallet</td><td>Credentials are stored in our wallet SDK using <a href="https://w3c-ccg.github.io/universal-wallet-interop-spec/">the W3C Universal Wallet 2020 specification</a>, as implemented in <a href="https://github.com/docknetwork/universal-wallet">our open source Universal Wallet library</a>.</td><td>W3C</td></tr></tbody></table>

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

## Key standards during issuance

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

## Key standards during verification

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

## Signature formats

Truvera supports following signature formats

<table><thead><tr><th width="186">Credential variant</th><th width="466">Signature formats</th></tr></thead><tbody><tr><td>Standard signature</td><td>ed25519</td></tr><tr><td>Anonymous</td><td>dockbbs23</td></tr><tr><td>Anonymous Ecosystem-Bound</td><td>BBDT16 as an algebraic MAC to build keyed anonymous credentials</td></tr><tr><td>EUDI</td><td>SD-JWT-VC</td></tr></tbody></table>

### Encryption and Cryptography

#### Encryption at rest in Truvera Workspace

Credential documents are stored encrypted with ECDH-ES+A256KW using x25519 key agreement keys. The index is encrypted with searchable encryption.

Other data is stored on RDS and S3 using AWS's default encryption.

#### Encryption in transit

Queued messages are encrypted per the DIDComm Message packing.

#### Cryptographic Primitives

Our credential library uses [Arkworks Math Library](https://github.com/arkworks-rs/algebra) for signing credentials and generating proofs.

We also use [Libsodium](https://libsodium.org/) for encryption in communication and storage.

## Interoperability

Truvera believes that credentials are most useful when they are interoperable across service providers. Our W3C compliant credential format is designed for maximum interoperability. Our anonymous credential format adheres to many W3C standards, but are designed for maximum privacy protection. We also leverage standards from OpenID, IETF, DIF, and related organizations.


# Interoperability with OpenID

The OpenID for Verifiable Credentials work is a product of the OpenID Connect Working Group. The [whitepaper](https://openid.net/wordpress-content/uploads/2022/06/OIDF-Whitepaper_OpenID-for-Verifiable-Credentials-V2_2022-06-23.pdf) OpenID for Verifiable Credentials describes the work and its motivations.

OID4VCs consists of three use cases with OID protocols:

1. Credential issuance: OpenID for Verifiable Credential Issuance (OID4VC)
2. Credential presentation: OpenID for Verifiable Presentations (OID4VP)
3. Pseudonymous user authentication through a wallet: OpenID for Self-Issued Identity Providers

Though it’s a distinct protocol, it uses patterns from [OpenID Connect Core](https://openid.net/specs/openid-connect-core-1_0-final.html). Credential issuance leverages the authorization code flow from oAuth for authenticating the user sufficient to authorize credential issuance and introduces a new “credential issuance” endpoint.

The OpenID4VC is a widely respected standard, that has a large community with lots of contributors. By supporting OpenID4VC Truvera allows customers to issue credentials into various digital wallets. It shows our strong commitment to interoperability and gives them the flexibility needed to build their products.

[More information on OpenID4VC](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html)


# mDL - Mobile Drivers License


# Credential wallet

Truvera's credential wallet technology provides a secure, flexible solution for managing and sharing verifiable credentials across platforms. With the ability to store tamper-proof credentials, the wallet ensures that users can easily share their information for verification, while maintaining full control over their data. Incorporating a Truvera Wallet into your identity solution will help you to comply with data protection standards while also helping your solution to interoperate with other credential technologies.

Truvera identity wallets are built with the Truvera Wallet SDK, [which is published on GitHub](https://github.com/docknetwork/wallet-sdk/) using a proprietary license. This means that you can study the code and understand how it functions. At the center of the Wallet SDK is the [Truvera Credential SDK](/open-source-community/blockchain-sdk), which is an open source library also [available on GitHub](https://github.com/docknetwork/sdk). You can use this library in your own solutions if you are ever unsatisfied with the Truvera wallet offerings.

Truvera provides several options for making an identity wallet available to your credential holders.

### Truvera Mobile Wallet

The [Truvera Mobile Wallet](#truvera-mobile-wallet) is a mature and full-featured identity wallet that is freely available in major app stores to help consumers take control of their identity data.

* iOS users: Download from the the [App store](https://apps.apple.com/br/app/truvera-wallet/id6739359697)
* Android users: Download from the [Google Play store](https://play.google.com/store/apps/details?id=com.truvera.app)

Though the Truvera Wallet could be used for a production use case, the wallet is most often used by developers. Once a solution developer is confident that they can create and verify credentials, most will deploy one of the other solutions on this page for production use.

### White-label wallet

The [Truvera White-Label Wallet](/credential-wallet/white-label-wallet) allows you to easily adapt the Truvera Mobile Wallet for your use case by skinning it with your brand assets and selecting only the features that you need.

### Wallet SDK

[Truvera's Wallet SDK](/credential-wallet/wallet-sdk) gives you all the functionality you need to build a custom wallet. Common ways of using the Wallet SDK include:

* Building a highly customized identity wallet mobile application,
* Embedding identity wallet capabilities into an existing application,
* Embedding the Truvera SDK into your mobile SDK so that your clients can embed wallet capabilities into their applications,
* Building a custom web wallet interface for credential management by storing credentials in the Truvera Cloud Wallet,
* Embedding credential exchange flows into existing web applications.

The SDK is built with a modular feature set, so you can activate only the functionalities you need. This can include secure, local data storage in order to have users to maintain full control of their credentials. It can also include storing end-to-end encrypted credentials in the Truvera Cloud Wallet in order to backup credentials or enable them to be used outside of a mobile application.

### Cloud Wallet

The [Truvera Cloud Wallet](/credential-wallet/wallet-sdk/cloud-wallet) is a hosted service for storing credential data so that it can be accessed outside of a specific mobile application. This can be used for credential recovery onto other device or credential usage in a web browser flow. The data is encrypted before storage using the Wallet SDK and a key generated by the user, so the data cannot be accessed by anyone else.

The cloud wallet provides secure, encrypted storage of credentials, allowing users to access their digital IDs anytime, anywhere. This solution is ideal for organizations that require scalable, cloud-based credential management.




---

[Next Page](/llms-full.txt/1)

