Credential Verification
A Verifiable Credential is a cryptographically verifiable digital document that contains claims about its subject, such as your school degree certificate. A Verifiable Presentation, on the other hand, is a collection of Verifiable Credentials shared by the user or holder of the credentials when requested by a verifier. Both of these credential formats follow the W3C specification.
The Credential Verification service helps you verify whether the Verifiable Credential or Verifiable Presentation shared with your application by the user is authentic and tamper-evident.
Benefits of Credential Verification
- Format Validation: Validates if the data shared adheres to the expected format and structure.
- Authenticity Verification: Cryptographically verify the shared data to ensure it is tamper-evident and authentic.
How Credential Verification Works
The Credential Verification service verifies the Verifiable Credentials and Verifiable Presentations to validate and cryptographically verify the credentials’ conformance to the standard format and authenticity based on the proof provided in the credential.
sequenceDiagram
actor User
participant Website
participant Credential Verification Service
User->>Website: Shared a credential from Affinidi Vault
Website->>Credential Verification Service: Verify the shared credential
Note over Website, Credential Verification Service: Verifiable Credential [JSON]
Credential Verification Service->>Credential Verification Service: Cryptographically verify the credential
Credential Verification Service->>Website: Response isValid
Note over Credential Verification Service, Website: returns false with list of errors if invalid
Website->>Website: Process shared credentials
Website->>User: Provide accessVerify Credentials using Affinidi Portal
To use the Credential Verification, go to the Credential Verification on the Affinidi Portal under Services.

The Credential Verifications requires two input:
The type of Credentials you want to verify:
- Verifiable Credentials
- Verifiable Presentations
The credential data that you want to verify, for example, the Verifiable Presentations sent by Affinidi Login:
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://schema.affinidi.com/EmailV1-0.jsonld"
],
"id": "claimId:63b5d11c0d1b5566",
"type": [
"VerifiableCredential",
"Email"
],
"holder": {
"id": "did:key:randomdid"
},
"credentialSubject": {
"email": "non-existant-email@non-existant.com"
},
"credentialSchema": {
"id": "https://schema.affinidi.com/EmailV1-0.json",
"type": "JsonSchemaValidator2018"
},
"issuanceDate": "2024-05-29T14:11:46.408Z",
"expirationDate": "2025-05-29T14:11:46.408Z",
"issuer": "did:key:zQ3shiEH16wHAfbQSSuYB1Lc3KSQC31W4gkaXKa8PgCSz83du",
"proof": {
"type": "EcdsaSecp256k1Signature2019",
"created": "2024-05-29T14:11:46Z",
"verificationMethod": "did:key:zQ3shiEH16wHAfbQSSuYB1Lc3KSQC31W4gkaXKa8PgCSz83du#zQ3shiEH16wHAfbQSSuYB1Lc3KSQC31W4gkaXKa8PgCSz83du",
"proofPurpose": "assertionMethod",
"jws": "eyJhbGciOiJFUzI1NksiLCJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdfQ..qjCyJh3FgDkPNyh19NIICW8OR0w_OShLPqeORbAyOu88WOJWeQPbyFIHxCiQ9q3eaUvK0u4Rhd3oGrYkrqYcCQ"
}
}After providing the credential type and credential data, click on Submit button.
The service will respond with success if the credential is valid. If failed, the service will list the errors.

Verify Credentials using Affinidi TDK
If you want to validate Verifiable Credentials or Verifiable Presentations shared by the users from your application, use the Credential Verification Client of the Affinidi TDK to call the Credential Verification service.
Follow the sample code below to validate a credential.
- Install the required libraries (in our example, we will use Credential Verification Service).
npm install -S @affinidi-tdk/auth-provider @affinidi-tdk/credential-verification-clientpip install affinidi_tdk_auth_provider affinidi_tdk_credential_verification_clientcomposer require affinidi-tdk/affinidi-tdk-php<dependency>
<groupId>com.affinidi.tdk</groupId>
<artifactId>credential.verification.client</artifactId>
<version>1.2.1</version>
</dependency>dotnet add package AffinidiTdk.CredentialVerificationClient
dotnet add package AffinidiTdk.AuthProvider- Import the libraries into the code. We are importing the Credential Verification client (Credential Verification Service) to validate a credential and the Auth Provider to generate the Project Scoped Token for the Authorisation header.
import { DefaultApi, Configuration as AuthConfiguration, VerifyCredentialInput } from '@affinidi-tdk/credential-verification-client'
import { AuthProvider } from '@affinidi-tdk/auth-provider'import affinidi_tdk_auth_provider
import affinidi_tdk_credential_verification_clientrequire_once 'vendor/autoload.php';
use AffinidiTdk\AuthProvider\AuthProvider;
use AffinidiTdk\Clients\CredentialVerificationClient;import com.affinidi.tdk.authProvider.AuthProvider;
import com.affinidi.tdk.credential.verification.client.Configuration;
import com.affinidi.tdk.credential.verification.client.ApiClient;
import com.affinidi.tdk.credential.verification.client.auth.ApiKeyAuth;
import com.affinidi.tdk.credential.verification.client.models.VerifyCredentialInput;
import com.affinidi.tdk.credential.verification.client.models.VerifyCredentialOutput;
import com.affinidi.tdk.credential.verification.client.models.W3cCredential;
import com.affinidi.tdk.credential.verification.client.models.W3cCredentialCredentialSchema;
import com.affinidi.tdk.credential.verification.client.models.W3cCredentialCredentialSubject;
import com.affinidi.tdk.credential.verification.client.models.W3cCredentialHolder;
import com.affinidi.tdk.credential.verification.client.models.W3cCredentialStatus;
import com.affinidi.tdk.credential.verification.client.models.W3cPresentationContext;
import com.affinidi.tdk.credential.verification.client.models.W3cProof;
import com.affinidi.tdk.credential.verification.client.apis.DefaultApi;using AffinidiTdk.AuthProvider;
using AffinidiTdk.CredentialVerificationClient.Api;
using AffinidiTdk.CredentialVerificationClient.Client;
using AffinidiTdk.CredentialVerificationClient.Model;
using Newtonsoft.Json.Linq;- Generate an Authorisation token to call the client using the Personal Access Token for the specific project.
// 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 AuthConfiguration({
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_verification_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("<PAT_PRIVATE_KEY_STRING>"))
.passphrase(dotenv.get("<PAT_KEY_PAIR_PASSPHRASE>"))
.tokenId(dotenv.get("<PAT_ID>"))
.build();var authProvider = new AuthProvider(new AuthProviderParams
{
TokenId = "YOUR_TOKEN_ID",
PrivateKey = "YOUR_PRIVATE_KEY",
ProjectId = "YOUR_PROJECT_ID"
Passphrase = "YOUR_PASSPHRASE",
});
string projectScopedToken = await authProvider.FetchProjectScopedTokenAsync();- Initiate the Credential Verification module with the authorisation header and call the client method with the credential data.
const api = new DefaultApi(authConfiguration)
const request: VerifyCredentialInput = {
"verifiableCredentials": [
{
...
}
]
}
const { data } = await api.verifyCredentials(request)with affinidi_tdk_credential_verification_client.ApiClient(configuration) as api_client:
api_instance = affinidi_tdk_credential_verification_client.DefaultApi(api_client)
request_json = {
"verifiableCredentials": [
{
...
}
]
}
verify_credentials_input = affinidi_tdk_credential_verification_client.VerifyCredentialInput.from_dict(request_json)
api_response = api_instance.verify_credentials(verify_credentials_input=verify_credentials_input)// Configure API key authorization: ProjectTokenAuth
$config = CredentialVerificationClient\Configuration::getDefaultConfiguration()->setApiKey('authorization', '', $tokenCallback);
$apiInstance = new CredentialVerificationClient\Api\DefaultApi(
new GuzzleHttp\Client(),
$config
);
try {
$request = array(
"verifiableCredentials" => array(
array(
...
)
)
);
$result = $apiInstance->verifyCredentials($request);
print_r($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());
DefaultApi apiInstance = new DefaultApi(defaultClient);
ArrayList<W3cCredential> vcData = new ArrayList<W3cCredential>(List.of(new W3cCredential()
.atContext(new W3cPresentationContext())
.id("")
.type(new ArrayList<String>())
.holder(new W3cCredentialHolder())
.credentialSubject(new W3cCredentialCredentialSubject())
.credentialStatus(new W3cCredentialStatus())
.issuanceDate("")
.issuer("")
.expirationDate("")
.proof(new W3cProof())
.credentialSchema(new W3cCredentialCredentialSchema())
));
VerifyCredentialInput requestInput = new VerifyCredentialInput()
.verifiableCredentials(vcData);
VerifyCredentialOutput response = apiInstance.verifyCredentials(requestInput);
System.out.println(response.toString());
} catch (Exception e) {
e.printStackTrace();
}// Pass the projectScopedToken generated from AuthProvider package
Configuration config = new Configuration();
config.AddApiKey("authorization", projectScopedToken);
DefaultApi api = new DefaultApi(config);
// Sample VC data from the portal
var vc = new JObject
{
{
"@context", new JArray(
"https://www.w3.org/2018/credentials/v1",
"https://schema.affinidi.com/EmailV1-0.jsonld"
)
},
{
"id", "claimId:97fa9b2e9d1f70bd5da4f202"
},
{
"type", new JArray(
"VerifiableCredential",
"Email"
)
},
{
"holder", new JObject
{
{ "id", "did:key:890890890890890" }
}
},
{
"credentialSubject", new JObject
{
{ "email", "lorem@ipsum.com" }
}
},
{
"credentialSchema", new JObject
{
{ "id", "https://schema.affinidi.com/EmailV1-0.json" },
{ "type", "JsonSchemaValidator2018" }
}
},
{ "issuanceDate", "2025-06-01T06:10:15.081Z" },
{ "expirationDate", "2030-06-01T06:10:14.954Z" },
{ "issuer", "did:key:890890890890890" },
{
"proof", new JObject
{
...
}
}
};
VerifyCredentialInput input = new VerifyCredentialInput(verifiableCredentials: [vc]);
VerifyCredentialOutput result = api.VerifyCredentials(input);The Credential Verification client will return TRUE if the the credential is valid or FALSE if it fails, include the list of errors.
{
"isValid": true,
"errors": []
}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.