VC Claim Notification
The VC Claim Notification is an optional component of the Credential Issuance flow that allows applications to be notified through a WebHook URL when the user claims a credential offer from your application.
The notification contains details, such as the Issuance ID
and Configuration ID
, related to the Verifiable Credential (VC) claimed by the user. You can use these details to retrieve and save a copy of the claimed VC into your system.
Important Note
The Credential Issuance service retains the copy of the claimed VC only if the VC Claim Notification option is enabled and retained for 3 days; afterwards, it is permanently deleted from Affinidi’s database.
You must retrieve a copy of the claimed credential within this period if you wish to keep a copy of the user’s issued credential. Follow this guide to retrieve a copy of the claimed credential using Affinidi TDK.
Setting up VC Claim Notification
To enable notification to your application once the user claims the credential offer, simply enable the VC Claim Notification option in the Credential Issuance configuration and provide the WebHook URL from your application.
The WebHook URL must be accessible online and accept JSON-formatted data containing the Configuration ID and the Issuance ID of the claimed credential. If the initial call fails, the Credential Issuance service will retry sending the details to the WebHook URL a maximum of 3 times.
Otherwise, use this guide to retrieve the list of claimed credentials.

Note
The VC Claim Notification does not yet support any authentication method for the WebHook URL used for notification. You must secure the URL in other ways, like restricting access by accepting only requests from Affinidi’s domain (affinidi.io
).Get a Copy of Claimed Credential
To get a copy of the claimed credentials issued from your application, you can either use the Issuance ID associated with the credential offer or based on the time range.
Get Claimed Credential by Issuance ID
In this example, we are retrieving the copy of the credential using the Issuance ID sent by the notification.
- Install the required libraries.
npm install -S @affinidi-tdk/auth-provider @affinidi-tdk/credential-issuance-client
pip install affinidi_tdk_auth_provider affinidi_tdk_credential_issuance_client
composer require affinidi-tdk/affinidi-tdk-php
```bash
<dependency>
<groupId>com.affinidi.tdk</groupId>
<artifactId>credential.issuance.client</artifactId>
<version>1.4.0</version>
</dependency>
```
- Import the libraries into the code. We are importing the Credential Issuance client (Credential Issuance Service) to create a Credential Offer and the Auth Provider to generate the Project Scoped Token for the Authorisation header.
import { ClaimedCredentialResponse, Configuration, CredentialsApi } from "@affinidi-tdk/credential-issuance-client"
import { AuthProvider } from '@affinidi-tdk/auth-provider'
import affinidi_tdk_auth_provider
import affinidi_tdk_credential_issuance_client
require_once 'vendor/autoload.php';
use AffinidiTdk\AuthProvider\AuthProvider;
use AffinidiTdk\Clients\CredentialIssuanceClient;
import com.affinidi.tdk.authProvider.AuthProvider;
import com.affinidi.tdk.credential.issuance.client.ApiClient;
import com.affinidi.tdk.credential.issuance.client.Configuration;
import com.affinidi.tdk.credential.issuance.client.auth.ApiKeyAuth;
import com.affinidi.tdk.credential.issuance.client.apis.CredentialsApi;
import com.affinidi.tdk.credential.issuance.client.models.ClaimedCredentialResponse;
- Generate an Authorisation token to call the client using the Personal Access Token for the specific project.
Use the Affinidi CLI Token command to generate the Personal Access Token (PAT) for the Auth Provider.
If you have created the Personal Access Token (PAT) with the
--key-id
flag in Affinidi CLI, you must also set thekeyId
with the supplied value in the AuthProvider class.
// NOTE: set your variables for PAT
const privateKey = "<PAT_PRIVATE_KEY_STRING>"
const passphrase = "<PAT_KEY_PAIR_PASSPHRASE>"
const tokenId = "<PAT_ID>"
const projectId = "<PROJECT_ID>"
const authProvider = new AuthProvider({
privateKey,
passphrase,
tokenId,
projectId
})
const authConfiguration = new Configuration({
apiKey: authProvider.fetchProjectScopedToken.bind(authProvider)
})
stats = {
"privateKey": "<PAT_PRIVATE_KEY_STRING>",
"passphrase": "<PAT_KEY_PAIR_PASSPHRASE>",
"tokenId": "<PAT_ID>",
"projectId": "<PROJECT_ID>"
}
authProvider = affinidi_tdk_auth_provider.AuthProvider(stats)
projectScopedToken = authProvider.fetch_project_scoped_token()
configuration = affinidi_tdk_credential_issuance_client.Configuration()
# Configure API key authorization: ProjectTokenAuth
configuration.api_key['ProjectTokenAuth'] = projectScopedToken
$params = [
'privateKey' => "<PAT_PRIVATE_KEY_STRING>",
'passphrase' => '<PAT_KEY_PAIR_PASSPHRASE>',
'tokenId' => '<PAT_ID>',
'projectId' => '<PROJECT_ID>'
];
$authProvider = new AuthProvider($params);
$tokenCallback = [$authProvider, 'fetchProjectScopedToken'];
Dotenv dotenv = null;
dotenv = Dotenv.configure().load();
// Alternatively you can create an auth provider by explicitly passing the configurations
AuthProvider authProvider = new AuthProvider.Configurations()
.projectId(dotenv.get("PROJECT_ID"))
.privateKey(dotenv.get("PRIVATE_KEY"))
.passphrase(dotenv.get("PASSPHRASE"))
.tokenId(dotenv.get("TOKEN_ID"))
.build();
- Retrieve credential with Issuance ID of the claimed verifiable credential.
async function getClaimedCredentialByIssuanceId() {
const api = new CredentialsApi(authConfiguration)
const projectId = "<Project_ID>"
const configId = "<Config_ID>"
const issuanceId = "<Issuance_ID>"
const { data } = await api.getIssuanceIdClaimedCredential(projectId, configurationId, issuanceId);
const claimedCrendetial : ClaimedCredentialResponse = data
return claimedCrendetial
}
getClaimedCredentialByIssuanceId()
.then((claimedCrendetial) => console.log(claimedCrendetial))
.catch((error) => console.log(error))
with affinidi_tdk_credential_issuance_client.ApiClient(configuration) as api_client:
api_instance = affinidi_tdk_credential_issuance_client.CredentialsApi(api_client)
projectId = "<Project_ID>"
configId = "<Config_ID>"
issuanceId = "<Issuance_ID>"
api_response = api_instance.get_issuance_id_claimed_credential(projectId, configId, issuanceId)
// Configure API key authorization: ProjectTokenAuth
$config = CredentialIssuanceClient\Configuration::getDefaultConfiguration()->setApiKey('authorization', '', $tokenCallback);
$apiInstance = new CredentialIssuanceClient\Api\CredentialsApi(
new GuzzleHttp\Client(),
$config
);
try {
$projectId = "<Project_ID>";
$configId = "<Config_ID>";
$issuanceId = "<Issuance_ID>";
$result = $apiInstance->getIssuanceIdClaimedCredential($projectId, $configId, $issuanceId);
return $result;
} catch (Exception $e) {
echo 'Exception when calling method: ', $e->getMessage(), PHP_EOL;
}
try {
ApiClient defaultClient = Configuration.getDefaultApiClient();
// Configure API key authorization: ProjectTokenAuth
ApiKeyAuth ProjectTokenAuth = (ApiKeyAuth) defaultClient.getAuthentication("ProjectTokenAuth");
ProjectTokenAuth.setApiKey(authProvider.fetchProjectScopedToken());
CredentialsApi apiInstance = new CredentialsApi(defaultClient);
String projectId = "<Project_ID>";
String configId = "<Config_ID>";
String issuanceId = "<Issuance_ID>";
ClaimedCredentialResponse response = apiInstance.getIssuanceIdClaimedCredential(projectId, configurationId, issuanceId);
return response;
} catch (Exception e) {
e.printStackTrace();
}
Get Claimed Credential by Time Range
In this example, we are retrieving the list of claimed credentials using a time range.
- Install the required libraries.
npm install -S @affinidi-tdk/auth-provider @affinidi-tdk/credential-issuance-client
pip install affinidi_tdk_auth_provider affinidi_tdk_credential_issuance_client
composer require affinidi-tdk/affinidi-tdk-php
```bash
<dependency>
<groupId>com.affinidi.tdk</groupId>
<artifactId>credential.issuance.client</artifactId>
<version>1.4.0</version>
</dependency>
```
- Import the libraries into the code. We are importing the Credential Issuance client (Credential Issuance Service) to create a Credential Offer and the Auth Provider to generate the Project Scoped Token for the Authorisation header.
import { ClaimedCredentialListResponse, Configuration, CredentialsApi } from "@affinidi-tdk/credential-issuance-client"
import { AuthProvider } from '@affinidi-tdk/auth-provider'
import affinidi_tdk_auth_provider
import affinidi_tdk_credential_issuance_client
require_once 'vendor/autoload.php';
use AffinidiTdk\AuthProvider\AuthProvider;
use AffinidiTdk\Clients\CredentialIssuanceClient;
import com.affinidi.tdk.authProvider.AuthProvider;
import com.affinidi.tdk.credential.issuance.client.ApiClient;
import com.affinidi.tdk.credential.issuance.client.Configuration;
import com.affinidi.tdk.credential.issuance.client.auth.ApiKeyAuth;
import com.affinidi.tdk.credential.issuance.client.apis.CredentialsApi;
import com.affinidi.tdk.credential.issuance.client.models.ClaimedCredentialListResponse;
- Generate an Authorisation token to call the client using the Personal Access Token for the specific project.
Use the Affinidi CLI Token command to generate the Personal Access Token (PAT) for the Auth Provider.
If you have created the Personal Access Token (PAT) with the
--key-id
flag in Affinidi CLI, you must also set thekeyId
with the supplied value in the AuthProvider class.
// NOTE: set your variables for PAT
const privateKey = "<PAT_PRIVATE_KEY_STRING>"
const passphrase = "<PAT_KEY_PAIR_PASSPHRASE>"
const tokenId = "<PAT_ID>"
const projectId = "<PROJECT_ID>"
const authProvider = new AuthProvider({
privateKey,
passphrase,
tokenId,
projectId
})
const authConfiguration = new Configuration({
apiKey: authProvider.fetchProjectScopedToken.bind(authProvider)
})
stats = {
"privateKey": "<PAT_PRIVATE_KEY_STRING>",
"passphrase": "<PAT_KEY_PAIR_PASSPHRASE>",
"tokenId": "<PAT_ID>",
"projectId": "<PROJECT_ID>"
}
authProvider = affinidi_tdk_auth_provider.AuthProvider(stats)
projectScopedToken = authProvider.fetch_project_scoped_token()
configuration = affinidi_tdk_credential_issuance_client.Configuration()
# Configure API key authorization: ProjectTokenAuth
configuration.api_key['ProjectTokenAuth'] = projectScopedToken
$params = [
'privateKey' => "<PAT_PRIVATE_KEY_STRING>",
'passphrase' => '<PAT_KEY_PAIR_PASSPHRASE>',
'tokenId' => '<PAT_ID>',
'projectId' => '<PROJECT_ID>'
];
$authProvider = new AuthProvider($params);
$tokenCallback = [$authProvider, 'fetchProjectScopedToken'];
Dotenv dotenv = null;
dotenv = Dotenv.configure().load();
// Alternatively you can create an auth provider by explicitly passing the configurations
AuthProvider authProvider = new AuthProvider.Configurations()
.projectId(dotenv.get("PROJECT_ID"))
.privateKey(dotenv.get("PRIVATE_KEY"))
.passphrase(dotenv.get("PASSPHRASE"))
.tokenId(dotenv.get("TOKEN_ID"))
.build();
- Retrieve credential with Issuance ID of the claimed verifiable credential.
async function getClaimedCredentialByRange() {
const api = new CredentialsApi(authConfiguration)
const projectId = "<Project_ID>"
const configId = "<Config_ID>"
const rangeStartTime = "2025-02-05T00:00:00.000Z"
const rangeEndTime = "2025-02-06T00:00:00.000Z";
// to get the next page from the list, get the exclusiveStartkey from the previous list response, null if getting the first page.
const next = null;
const { data } = api.getClaimedCredentials(projectId, configurationId, rangeStartTime, rangeEndTime, next)
const claimedCrendetials : ClaimedCredentialListResponse = data
return claimedCrendetials
}
getClaimedCredentialByRange()
.then((claimedCrendetials) => console.log(claimedCrendetials))
.catch((error) => console.log(error))
with affinidi_tdk_credential_issuance_client.ApiClient(configuration) as api_client:
api_instance = affinidi_tdk_credential_issuance_client.CredentialsApi(api_client)
projectId = "<Project_ID>"
configId = "<Config_ID>"
rangeStartTime = "2025-02-05T00:00:00.000Z"
rangeEndTime = "2025-02-06T00:00:00.000Z";
# to get the next page from the list, get the exclusiveStartkey from the previous list response, null if getting the first page.
next = null;
api_response = api_instance.get_claimed_credentials(projectId, configId, rangeStartTime, rangeEndTime, next)
// Configure API key authorization: ProjectTokenAuth
$config = CredentialIssuanceClient\Configuration::getDefaultConfiguration()->setApiKey('authorization', '', $tokenCallback);
$apiInstance = new CredentialIssuanceClient\Api\CredentialsApi(
new GuzzleHttp\Client(),
$config
);
try {
$projectId = "<Project_ID>";
$configId = "<Config_ID>";
$rangeStartTime = "2025-02-05T00:00:00.000Z"
$rangeEndTime = "2025-02-06T00:00:00.000Z";
// to get the next page from the list, get the exclusiveStartkey from the previous list response, null if getting the first page.
$next = null;
$result = $apiInstance->getClaimedCredentials($projectId, $configId, $rangeStartTime, $rangeEndTime, next);
return $result;
} catch (Exception $e) {
echo 'Exception when calling method: ', $e->getMessage(), PHP_EOL;
}
try {
ApiClient defaultClient = Configuration.getDefaultApiClient();
// Configure API key authorization: ProjectTokenAuth
ApiKeyAuth ProjectTokenAuth = (ApiKeyAuth) defaultClient.getAuthentication("ProjectTokenAuth");
ProjectTokenAuth.setApiKey(authProvider.fetchProjectScopedToken());
CredentialsApi apiInstance = new CredentialsApi(defaultClient);
String projectId = "<Project_ID>";
String configId = "<Config_ID>";
String rangeStartTime = "2025-02-05T00:00:00.000Z";
String rangeEndTime = "2025-02-06T00:00:00.000Z";
// to get the next page from the list, get the exclusiveStartkey from the previous list response, null if getting the first page.
String next = null;
ClaimedCredentialListResponse response = apiInstance.getClaimedCredentials(projectId, configurationId, rangeStartTime, rangeEndTime, next);
return response;
} catch (Exception e) {
e.printStackTrace();
}
Glad to hear it! Please tell us how we can improve more.
Sorry to hear that. Please tell us how we can improve.
Thank you for sharing your feedback so we can improve your experience.