This page covers the main api endpoints which are responsible when an organization wants to retrieve a verifiable credential or a verifiable presentation from a DPP. The flow can be used in a flexible way so that the organization which owns the DPP can decide if a VP or VC should be shared back. Additionally when a DPP is created some automation rules will be already set, that all verification requests to the DPP will be “answered” automatically and the VC will be shared back.
Entities
A Verification Request contains various entities which are covered here in the flow. The following part explains them:
Verification Request
A Verification Request is generated by the “Verifier” who wants to request data from a defined Holder. The verification request contains necessary data of the holders DID, the requested template. The Verification flow can be ONLY started with a Verification Request.
Verification Inquiry
A Verification Inquiry cannot be manually created via the API, so this entity needs to be created when a holder receives a verification request from the verifier. The verification inquiry contains necessary data of the verifiers DID and the requested template. When the verifier wants to respond to a inquiry, he can either accept or decline the inquiry. Additionally when he accepts the request, he can define if he wants to share a VP or the VC with the verifier.
Presentation Rule
This entity can be managed by the organization for a specific wallet. A Presentation Rule defines a set of rules which will configure the handling of an incoming inquiry. For example you can setup rules to automatically answer inquiries which request:
- a specific template, specific verifier and send back a VP
- a specific template, specific verifier and send back a VC
- a specific template, any verifier and send back a VP
- a specific template, any verifier and send back a VC
- any template, any verifier and send back a VP
- any template, any verifier and send back a VC
Example Flows
The following section describes different usecases which can be used with the verification flow. Each section describes the complete flow from start to end.
Case: Automatic VC answer from the DPP Wallet
The first flow is the automatic answer of the DPP with a credential when a verifier requests a specific template from the DPP wallet:
API Call flow
Verifier sends request to Holder
To realize the above mentioned flow via the API, the verifier needs to create a verification-request
first with the endpoint
To track the status of the verification request, you can store the id
of the created verification request for future requests.
Holder receives request and answers automatically
When the DPP Wallet gets created with the POST {{host}}/dpp
endpoint, the wallet gets an automatic “Presentation Rule” created to accept all incoming requests and send out a Verifiable Presentation to the Verifier. So in this explicit flow, we can only track the state of the incoming inquiry, which gets automatically updated.
The holder can fetch the received inquiries with the endpoint Endpoint: GET /verification-inquiries or with the endpoint to fetch a single inquiry with Endpoint: GET /verification-inquiries/:uuid
After a short amount of time, the state
of the inquiry updates to Presented
and contains the sent credential which was provided back to the verifier:
{
"meta": {},
"data": {
"id": "d9044daf-8eb4-44df-8e8a-2de68163220f",
"createdAt": "2024-01-11T13:54:49.820Z",
"updatedAt": "2024-01-11T13:54:49.820Z",
"data": {
"credential": {
"id": "ev-battery-passport-product-public-004:1704960403350:shoes-16ysrnf7fxukqfyr14llkfkte5incvzjf",
"type": [
"VerifiableCredential",
"BatteryDPP"
],
"proof": {
"jws": "eyJhbGciOiJFUzI1NkstUiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..x5Z00sOMfd3cH80poodEsem2lIxVDTlDeksNVnaHJ6wNkgiIG4RN11tIaveAOKiv4d5Ici5OwtArsjwiVEQJHAA",
"type": "EcdsaSecp256k1RecoverySignature2020",
"created": "2024-01-11T08:06:44Z",
"proofPurpose": "assertionMethod",
"verificationMethod": "did:ethr:0x022e10f219c3c9fe6932912198b124c3f9d7acc99d30c943e83b09d587a2362552#controller"
},
"issuer": "did:ethr:0x022e10f219c3c9fe6932912198b124c3f9d7acc99d30c943e83b09d587a2362552",
"@context": [
"https://www.w3.org/2018/credentials/v1",
"http://127.0.0.1:8080/templates/v1/ev-battery-passport-product-public-0-0-4.jsonld",
"https://w3id.org/security/suites/secp256k1recovery-2020/v2"
],
"issuanceDate": "2024-01-11T08:06:43.465Z",
"credentialSubject": {
"uniqueBatteryIdentifier": "optical"
}
},
"sendCredential": true
},
"verifier": "did:ethr:0x022e10f219c3c9fe6932912198b124c3f9d7acc99d30c943e83b09d587a2362552",
"holder": "did:ethr:0x038f5185bd3a9d07be70d5bb329d74a6bf6ba5f19c2b583c93a3e533780635d973",
"walletId": "f91f845a-f218-4dae-b16c-773319282b42",
"organizationId": "b278b70e-385b-4b58-90f5-50ba2d7913b3",
"templateId": "f16989f6-ef97-48b2-a446-b85fd3575f19",
"nonce": "4348dff7-d970-4aab-8ace-6ce08cf3afcc",
"state": "Presented"
}
}
This is because the created DPP wallet contains the presentation rule to accept all received requests automatically and sending back the credential which the DPP holds for the requested template.
Verifier receives the credential from the Holder
When the Verifier now checks his initial sent request with the API, he also now gets back his request data with the state Verified
via the Endpoint: GET /verification-requests/:uuid
The response of the endpoint will then look like the following
{
"meta": {},
"data": {
"id": "f0a942cc-1368-4695-8944-7e9df110a188",
"createdAt": "2024-01-11T13:54:49.774Z",
"updatedAt": "2024-01-11T13:54:49.774Z",
"data": {
"verified": true,
"credential": {
"id": "ev-battery-passport-product-public-004:1704960403350:shoes-16ysrnf7fxukqfyr14llkfkte5incvzjf",
"type": [
"VerifiableCredential",
"BatteryDPP"
],
"proof": {
"jws": "eyJhbGciOiJFUzI1NkstUiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..x5Z00sOMfd3cH80poodEsem2lIxVDTlDeksNVnaHJ6wNkgiIG4RN11tIaveAOKiv4d5Ici5OwtArsjwiVEQJHAA",
"type": "EcdsaSecp256k1RecoverySignature2020",
"created": "2024-01-11T08:06:44Z",
"proofPurpose": "assertionMethod",
"verificationMethod": "did:ethr:0x022e10f219c3c9fe6932912198b124c3f9d7acc99d30c943e83b09d587a2362552#controller"
},
"issuer": "did:ethr:0x022e10f219c3c9fe6932912198b124c3f9d7acc99d30c943e83b09d587a2362552",
"@context": [
"https://www.w3.org/2018/credentials/v1",
"http://127.0.0.1:8080/templates/v1/ev-battery-passport-product-public-0-0-4.jsonld",
"https://w3id.org/security/suites/secp256k1recovery-2020/v2"
],
"issuanceDate": "2024-01-11T08:06:43.465Z",
"credentialSubject": {
"uniqueBatteryIdentifier": "optical"
}
},
"sendCredential": true
},
"verifier": "did:ethr:0x022e10f219c3c9fe6932912198b124c3f9d7acc99d30c943e83b09d587a2362552",
"holder": "did:ethr:0x038f5185bd3a9d07be70d5bb329d74a6bf6ba5f19c2b583c93a3e533780635d973",
"walletId": "67d97d8a-e252-4870-841f-ed4339cb3fc1",
"organizationId": "b278b70e-385b-4b58-90f5-50ba2d7913b3",
"templateId": "f16989f6-ef97-48b2-a446-b85fd3575f19",
"nonce": "4348dff7-d970-4aab-8ace-6ce08cf3afcc",
"state": "Verified"
}
}
Case: Manual answer with a VC from the DPP Wallet
This flow covers the manual answer of an inquiry when no presentation rule for the wallet and the template is in place. Additionally we want to answer with a VC instead of a VP.
sequenceDiagram
Verifier->>+DPP: Send Verification Request
DPP->>DPP: Create Verification Inquiry
DPP->>DPP: Accept the Inquiry manually and share a VC
DPP->>DPP: Fetch latest Credential for requested template
DPP->>DPP: Answer Inquiry with VC
DPP->>Verifier: Send answer with VC
Verifier->>Verifier: Verify VC Signature
API Call flow
Verifier sends request to Holder
To do the above mentioned flow via the API, the verifier needs to create a verification-request
first with the Endpoint: POST /verification-requests ****endpoint
When the call with the defined template, wallet and holder was successful you can track the state of the verification request with the returned id
and the fetch the created request with Endpoint: GET /verification-requests/:uuid
Holder receives request and answers manually
When the DPP wallet acts as the Holder and receives the Inquiry from the Verified and no Presentation Rule matches the given configuration, the inquiry will be created in the state Received
and the holder needs to either Accept
or Decline
the request
The holder can fetch the received inquiries with the endpoint Endpoint: GET /verification-inquiries or with the endpoint to fetch a single inquiry with Endpoint: GET /verification-inquiries/:uuid
When he now wants to respond to the inquiry and accept it he needs to send a “state” update to the Endpoint: PUT /verification-inquiries/:uuid and the additional property to answer with a VC. The payload should look like:
{
"state": "Accept",
"data": {
"sendCredential":"true"
}
}
When the state update was sent the endpoint returns the inquiry with with the state Accepted
and the further processing can be checked by fetching the inquiry with the id from the endpoint Endpoint: GET /verification-inquiries/:uuid
After a short amount of time, the state
of the inquiry updates to Presented
and contains the sent credential which was provided back to the verifier:
{
"meta": {},
"data": {
"id": "d9044daf-8eb4-44df-8e8a-2de68163220f",
"createdAt": "2024-01-11T13:54:49.820Z",
"updatedAt": "2024-01-11T13:54:49.820Z",
"data": {
"credential": {
"id": "ev-battery-passport-product-public-004:1704960403350:shoes-16ysrnf7fxukqfyr14llkfkte5incvzjf",
"type": [
"VerifiableCredential",
"BatteryDPP"
],
"proof": {
"jws": "eyJhbGciOiJFUzI1NkstUiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..x5Z00sOMfd3cH80poodEsem2lIxVDTlDeksNVnaHJ6wNkgiIG4RN11tIaveAOKiv4d5Ici5OwtArsjwiVEQJHAA",
"type": "EcdsaSecp256k1RecoverySignature2020",
"created": "2024-01-11T08:06:44Z",
"proofPurpose": "assertionMethod",
"verificationMethod": "did:ethr:0x022e10f219c3c9fe6932912198b124c3f9d7acc99d30c943e83b09d587a2362552#controller"
},
"issuer": "did:ethr:0x022e10f219c3c9fe6932912198b124c3f9d7acc99d30c943e83b09d587a2362552",
"@context": [
"https://www.w3.org/2018/credentials/v1",
"http://127.0.0.1:8080/templates/v1/ev-battery-passport-product-public-0-0-4.jsonld",
"https://w3id.org/security/suites/secp256k1recovery-2020/v2"
],
"issuanceDate": "2024-01-11T08:06:43.465Z",
"credentialSubject": {
"uniqueBatteryIdentifier": "optical"
}
},
"sendCredential": true
},
"verifier": "did:ethr:0x022e10f219c3c9fe6932912198b124c3f9d7acc99d30c943e83b09d587a2362552",
"holder": "did:ethr:0x038f5185bd3a9d07be70d5bb329d74a6bf6ba5f19c2b583c93a3e533780635d973",
"walletId": "f91f845a-f218-4dae-b16c-773319282b42",
"organizationId": "b278b70e-385b-4b58-90f5-50ba2d7913b3",
"templateId": "f16989f6-ef97-48b2-a446-b85fd3575f19",
"nonce": "4348dff7-d970-4aab-8ace-6ce08cf3afcc",
"state": "Presented"
}
}
This is because the created DPP wallet contains the presentation rule to accept all received requests automatically and sending back the credential which the DPP holds for the requested template.
Verifier receives the credential from the Holder
When the Verifier now checks his initial sent request with the API, he also now gets back his request data with the state Verified
via the Endpoint: GET /verification-requests/:uuid
The response of the endpoint will then look like the following
{
"meta": {},
"data": {
"id": "f0a942cc-1368-4695-8944-7e9df110a188",
"createdAt": "2024-01-11T13:54:49.774Z",
"updatedAt": "2024-01-11T13:54:49.774Z",
"data": {
"verified": true,
"credential": {
"id": "ev-battery-passport-product-public-004:1704960403350:shoes-16ysrnf7fxukqfyr14llkfkte5incvzjf",
"type": [
"VerifiableCredential",
"BatteryDPP"
],
"proof": {
"jws": "eyJhbGciOiJFUzI1NkstUiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..x5Z00sOMfd3cH80poodEsem2lIxVDTlDeksNVnaHJ6wNkgiIG4RN11tIaveAOKiv4d5Ici5OwtArsjwiVEQJHAA",
"type": "EcdsaSecp256k1RecoverySignature2020",
"created": "2024-01-11T08:06:44Z",
"proofPurpose": "assertionMethod",
"verificationMethod": "did:ethr:0x022e10f219c3c9fe6932912198b124c3f9d7acc99d30c943e83b09d587a2362552#controller"
},
"issuer": "did:ethr:0x022e10f219c3c9fe6932912198b124c3f9d7acc99d30c943e83b09d587a2362552",
"@context": [
"https://www.w3.org/2018/credentials/v1",
"http://127.0.0.1:8080/templates/v1/ev-battery-passport-product-public-0-0-4.jsonld",
"https://w3id.org/security/suites/secp256k1recovery-2020/v2"
],
"issuanceDate": "2024-01-11T08:06:43.465Z",
"credentialSubject": {
"uniqueBatteryIdentifier": "optical"
}
},
"sendCredential": true
},
"verifier": "did:ethr:0x022e10f219c3c9fe6932912198b124c3f9d7acc99d30c943e83b09d587a2362552",
"holder": "did:ethr:0x038f5185bd3a9d07be70d5bb329d74a6bf6ba5f19c2b583c93a3e533780635d973",
"walletId": "67d97d8a-e252-4870-841f-ed4339cb3fc1",
"organizationId": "b278b70e-385b-4b58-90f5-50ba2d7913b3",
"templateId": "f16989f6-ef97-48b2-a446-b85fd3575f19",
"nonce": "4348dff7-d970-4aab-8ace-6ce08cf3afcc",
"state": "Verified"
}
}
The Verifier can now see the credential which was shared by the holder and also gets additional information back in the data field:
verified
- indicates if the VC or VP contains a valid signature (boolean flag)credential
- shows that a VC was shared (can be also omitted if a VP was shared)presentation
- shows that a VP was shared (can be also omitted if a VC was shared)
Case: Manual answer with a VP from the DPP Wallet
This flow covers the manual answer of an inquiry when no presentation rule for the wallet and the template is in place. Additionally we want to answer with a VP.
sequenceDiagram
Verifier->>+DPP: Send Verification Request
DPP->>DPP: Create Verification Inquiry
DPP->>DPP: Accept the Inquiry manually and share a VP
DPP->>DPP: Fetch latest Credential for requested template
DPP->>DPP: Issue a Presentation and answer Inquiry with VP
DPP->>Verifier: Send answer with VP
Verifier->>Verifier: Verify VP Signature
API Call flow
Verifier sends request to Holder
To do the above mentioned flow via the API, the verifier needs to create a verification-request
first with the Endpoint: POST /verification-requests ****endpoint
When the call with the defined template, wallet and holder was successful you can track the state of the verification request with the returned id
and the fetch the created request with Endpoint: GET /verification-requests/:uuid
Holder receives request and answers manually
When the DPP wallet acts as the Holder and receives the Inquiry from the Verified and no Presentation Rule matches the given configuration, the inquiry will be created in the state Received
and the holder needs to either Accept
or Decline
the request
The holder can fetch the received inquiries with the endpoint Endpoint: GET /verification-inquiries or with the endpoint to fetch a single inquiry with Endpoint: GET /verification-inquiries/:uuid
When he now wants to respond to the inquiry and accept it he needs to send a “state” update to the Endpoint: PUT /verification-inquiries/:uuid with the payload:
{
"state": "Accept"
}
When the state update was sent the endpoint returns the inquiry with with the state Accepted
and the further processing can be checked by fetching the inquiry with the id from the endpoint Endpoint: GET /verification-inquiries/:uuid
After a short amount of time, the state
of the inquiry updates to Presented
and contains the sent credential which was provided back to the verifier:
{
"meta": {},
"data": {
"id": "d9044daf-8eb4-44df-8e8a-2de68163220f",
"createdAt": "2024-01-11T13:54:49.820Z",
"updatedAt": "2024-01-11T13:54:49.820Z",
"data": {
"credential": {
"id": "ev-battery-passport-product-public-004:1704960403350:shoes-16ysrnf7fxukqfyr14llkfkte5incvzjf",
"type": [
"VerifiableCredential",
"BatteryDPP"
],
"proof": {
"jws": "eyJhbGciOiJFUzI1NkstUiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..x5Z00sOMfd3cH80poodEsem2lIxVDTlDeksNVnaHJ6wNkgiIG4RN11tIaveAOKiv4d5Ici5OwtArsjwiVEQJHAA",
"type": "EcdsaSecp256k1RecoverySignature2020",
"created": "2024-01-11T08:06:44Z",
"proofPurpose": "assertionMethod",
"verificationMethod": "did:ethr:0x022e10f219c3c9fe6932912198b124c3f9d7acc99d30c943e83b09d587a2362552#controller"
},
"issuer": "did:ethr:0x022e10f219c3c9fe6932912198b124c3f9d7acc99d30c943e83b09d587a2362552",
"@context": [
"https://www.w3.org/2018/credentials/v1",
"http://127.0.0.1:8080/templates/v1/ev-battery-passport-product-public-0-0-4.jsonld",
"https://w3id.org/security/suites/secp256k1recovery-2020/v2"
],
"issuanceDate": "2024-01-11T08:06:43.465Z",
"credentialSubject": {
"uniqueBatteryIdentifier": "optical"
}
},
"sendCredential": true
},
"verifier": "did:ethr:0x022e10f219c3c9fe6932912198b124c3f9d7acc99d30c943e83b09d587a2362552",
"holder": "did:ethr:0x038f5185bd3a9d07be70d5bb329d74a6bf6ba5f19c2b583c93a3e533780635d973",
"walletId": "f91f845a-f218-4dae-b16c-773319282b42",
"organizationId": "b278b70e-385b-4b58-90f5-50ba2d7913b3",
"templateId": "f16989f6-ef97-48b2-a446-b85fd3575f19",
"nonce": "4348dff7-d970-4aab-8ace-6ce08cf3afcc",
"state": "Presented"
}
}
This is because the created DPP wallet contains the presentation rule to accept all received requests automatically and sending back the credential which the DPP holds for the requested template.
Verifier receives the presentation from the Holder
When the Verifier now checks his initial sent request with the API, he also now gets back his request data with the state Verified
via the Endpoint: GET /verification-requests/:uuid
The response of the endpoint will then look like the following
{
"meta": {},
"data": {
"id": "f0a942cc-1368-4695-8944-7e9df110a188",
"createdAt": "2024-01-11T13:54:49.774Z",
"updatedAt": "2024-01-11T13:54:49.774Z",
"data": {
"verified": true,
"presentation": {
"type": [
"VerifiablePresentation"
],
"proof": {
"jws": "eyJhbGciOiJFUzI1NkstUiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..owPvDoIaji8RJx1qxOXLAlDSBVBODvvl9GxC7rjNgCBoC9sQV0_wvWhCyrOF25PEGov8ZONrSFrKJpwy3LAHMwA",
"type": "EcdsaSecp256k1RecoverySignature2020",
"domain": "",
"created": "2024-01-11T15:05:30Z",
"challenge": "c0ceb09f-ed0f-4b3e-bc3a-4a563a546fc0",
"proofPurpose": "authentication",
"verificationMethod": "did:ethr:0x038f5185bd3a9d07be70d5bb329d74a6bf6ba5f19c2b583c93a3e533780635d973#controller"
},
"holder": "did:ethr:0x038f5185bd3a9d07be70d5bb329d74a6bf6ba5f19c2b583c93a3e533780635d973",
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://w3id.org/security/suites/secp256k1recovery-2020/v2"
],
"verifiableCredential": [
{
"id": "ev-battery-passport-product-public-004:1704960403350:shoes-16ysrnf7fxukqfyr14llkfkte5incvzjf",
"type": [
"VerifiableCredential",
"BatteryDPP"
],
"proof": {
"jws": "eyJhbGciOiJFUzI1NkstUiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..x5Z00sOMfd3cH80poodEsem2lIxVDTlDeksNVnaHJ6wNkgiIG4RN11tIaveAOKiv4d5Ici5OwtArsjwiVEQJHAA",
"type": "EcdsaSecp256k1RecoverySignature2020",
"created": "2024-01-11T08:06:44Z",
"proofPurpose": "assertionMethod",
"verificationMethod": "did:ethr:0x022e10f219c3c9fe6932912198b124c3f9d7acc99d30c943e83b09d587a2362552#controller"
},
"issuer": "did:ethr:0x022e10f219c3c9fe6932912198b124c3f9d7acc99d30c943e83b09d587a2362552",
"@context": [
"https://www.w3.org/2018/credentials/v1",
"http://127.0.0.1:8080/templates/v1/ev-battery-passport-product-public-0-0-4.jsonld",
"https://w3id.org/security/suites/secp256k1recovery-2020/v2"
],
"issuanceDate": "2024-01-11T08:06:43.465Z",
"credentialSubject": {
"uniqueBatteryIdentifier": "optical"
}
}
]
},
"sendCredential": false
},
"verifier": "did:ethr:0x022e10f219c3c9fe6932912198b124c3f9d7acc99d30c943e83b09d587a2362552",
"holder": "did:ethr:0x038f5185bd3a9d07be70d5bb329d74a6bf6ba5f19c2b583c93a3e533780635d973",
"walletId": "67d97d8a-e252-4870-841f-ed4339cb3fc1",
"organizationId": "b278b70e-385b-4b58-90f5-50ba2d7913b3",
"templateId": "f16989f6-ef97-48b2-a446-b85fd3575f19",
"nonce": "4348dff7-d970-4aab-8ace-6ce08cf3afcc",
"state": "Verified"
}
}
The Verifier can now see the credential which was shared by the holder and also gets additional information back in the data field:
verified
- indicates if the VC or VP contains a valid signature (boolean flag)credential
- shows that a VC was shared (can be also omitted if a VP was shared)presentation
- shows that a VP was shared (can be also omitted if a VC was shared)