Skip to content

Verification API

When you submit a credential for verification, BaseID performs a multi-step cryptographic validation:

Credential string
├─ 1. Format detection (JWT-VC or SD-JWT based on ~ separator)
├─ 2. Decode JWT header → extract issuer DID (iss) and key ID (kid)
├─ 3. Resolve issuer DID → fetch DID Document with public keys
├─ 4. Find verification method → match kid to a public key in the document
├─ 5. Verify signature → cryptographic check using the issuer's public key
├─ 6. Check expiration → reject if exp claim is in the past
└─ 7. Return result → issuer, subject, format, validity
CheckWhat it confirms
Signature validThe credential was signed by the private key matching the issuer’s DID
Issuer resolvedThe issuer DID exists and has a valid DID Document
Not expiredThe credential’s exp claim (if present) is in the future
Not tamperedAny modification to the credential invalidates the signature
  • Revocation status — use the revoke endpoint to manage revocation
  • Trust in the issuer — verification confirms the signature is valid, not that you should trust the issuer. Use the Trust API for reputation
  • Claim accuracy — verification proves the issuer signed the claims, not that the claims are true

POST /v1/verify
Authorization: Bearer <token>

Permission required: credentials:verify

FieldTypeRequiredDescription
credentialstringYesRaw credential string (JWT compact or SD-JWT compact serialization)

The API automatically detects the format:

PatternDetected formatHow it’s verified
Three .-separated parts, no ~jwt_vc_json (JWT-VC)Full JWT verified
Contains ~ separatorsvc+sd-jwt (SD-JWT VC)JWT part before first ~ is verified

You do not need to specify the format — submit any credential string and the API handles it.

Terminal window
curl -X POST https://api.baseid.cloud/v1/verify \
-H "Authorization: Bearer bsk_live_..." \
-H "Content-Type: application/json" \
-d '{
"credential": "eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDprZXk6..."
}'
Terminal window
curl -X POST https://api.baseid.cloud/v1/verify \
-H "Authorization: Bearer bsk_live_..." \
-H "Content-Type: application/json" \
-d '{
"credential": "eyJhbGciOiJFZERTQSJ9.eyJpc3Mi...~eyJfc2QiOi...~"
}'
{
"valid": true,
"format": "jwt_vc_json",
"issuer": "did:key:z6MkIssuer...",
"subject": "did:key:z6MkHolder...",
"error": null
}
{
"valid": false,
"format": "jwt_vc_json",
"issuer": null,
"subject": null,
"error": "JWT-VC verification failed: signature mismatch"
}
FieldTypeDescription
validbooleantrue if signature is valid and credential is not expired
formatstringDetected format: jwt_vc_json or vc+sd-jwt
issuerstring or nullIssuer DID (extracted from iss claim). Null if verification failed before extraction.
subjectstring or nullSubject DID (from credentialSubject.id). Null for bearer credentials or on failure.
errorstring or nullHuman-readable error message. Null on success.

ErrorCauseFix
signature mismatchCredential was tampered with, or signed by a different key than the DID claimsRe-issue the credential with the correct key
missing iss claim in JWTThe JWT doesn’t contain an iss fieldEnsure the credential was issued by BaseID or a compliant issuer
failed to resolve DIDThe issuer’s DID could not be resolvedCheck that the issuer DID is valid and the method is supported (did:key)
no verification method with JWKThe DID Document doesn’t contain a usable public keyThe DID may be malformed or use an unsupported key type
expired credentialThe exp claim is in the pastIssue a new credential with a later expiration

const result = await client.verify.credential(jwtString);
if (result.valid) {
console.log(`Issued by: ${result.issuer}`);
} else {
console.error(`Invalid: ${result.error}`);
}
result = client.verify.credential(jwt_string)
if result["valid"]:
print(f"Issued by: {result['issuer']}")
else:
print(f"Invalid: {result['error']}")
result, err := client.Verify.Credential(jwtString)
if result.Valid {
fmt.Println("Issued by:", result.Issuer)
} else {
fmt.Println("Invalid:", result.Error)
}

MethodExampleResolution
did:keydid:key:z6Mk...Public key encoded in the DID itself — no network request

Additional methods (did:web, did:peer, did:webvh) are available in the core library and will be added to the Cloud API in a future release.


Each verification call is counted toward your monthly API usage. Check current usage via the Usage API.