curl -X POST \
"https://verilock.io/api/v1/credentials/issue" \
-H "Authorization: Bearer qi_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"session_id": "ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"credential_type": "IdentityCredential",
"claims": ["full_name", "nationality", "age_over_18", "aml_clear"],
"expiration": "2027-03-19T00:00:00Z"
}'
credential = client.credentials.issue({
"session_id": "ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"credential_type": "IdentityCredential",
"claims": ["full_name", "nationality", "age_over_18", "aml_clear"],
"expiration": "2027-03-19T00:00:00Z",
})
print(credential["jwt"]) # Send to user for wallet storage
const credential = await verilock.credentials.issue({
session_id: 'ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890',
credential_type: 'IdentityCredential',
claims: ['full_name', 'nationality', 'age_over_18', 'aml_clear'],
expiration: '2027-03-19T00:00:00Z',
});
console.log(credential.jwt); // Send to user
{
"id": "vc_e5f6a1b2-c3d4-7890-fedc-ba0987654321",
"status": "issued",
"credential_type": "IdentityCredential",
"issuer_did": "did:verilock:org:your-org-id",
"subject_did": "did:verilock:user:user-uuid",
"claims": ["full_name", "nationality", "age_over_18", "aml_clear"],
"issued_at": "2026-03-19T10:00:00Z",
"expires_at": "2027-03-19T00:00:00Z",
"jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6InZjK3NkLWp3dCJ9.eyJpc3MiOiJkaWQ6dmVyaWxvY2s6b3JnOi4uLiIs..."
}
Decentralized Identity
Verifiable Credentials
Issue and verify W3C-standard verifiable credentials for portable, privacy-preserving identity.
POST
/
credentials
/
issue
curl -X POST \
"https://verilock.io/api/v1/credentials/issue" \
-H "Authorization: Bearer qi_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"session_id": "ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"credential_type": "IdentityCredential",
"claims": ["full_name", "nationality", "age_over_18", "aml_clear"],
"expiration": "2027-03-19T00:00:00Z"
}'
credential = client.credentials.issue({
"session_id": "ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"credential_type": "IdentityCredential",
"claims": ["full_name", "nationality", "age_over_18", "aml_clear"],
"expiration": "2027-03-19T00:00:00Z",
})
print(credential["jwt"]) # Send to user for wallet storage
const credential = await verilock.credentials.issue({
session_id: 'ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890',
credential_type: 'IdentityCredential',
claims: ['full_name', 'nationality', 'age_over_18', 'aml_clear'],
expiration: '2027-03-19T00:00:00Z',
});
console.log(credential.jwt); // Send to user
{
"id": "vc_e5f6a1b2-c3d4-7890-fedc-ba0987654321",
"status": "issued",
"credential_type": "IdentityCredential",
"issuer_did": "did:verilock:org:your-org-id",
"subject_did": "did:verilock:user:user-uuid",
"claims": ["full_name", "nationality", "age_over_18", "aml_clear"],
"issued_at": "2026-03-19T10:00:00Z",
"expires_at": "2027-03-19T00:00:00Z",
"jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6InZjK3NkLWp3dCJ9.eyJpc3MiOiJkaWQ6dmVyaWxvY2s6b3JnOi4uLiIs..."
}
Verifiable Credentials (VCs) let you issue W3C-standard digital credentials from completed verifications. Users can store these credentials in their wallet and share them with other organizations — enabling one-time KYC with privacy-preserving selective disclosure.
Revoked credentials immediately fail verification with
Impact: Onboarding drops from 5 minutes to under 10 seconds. Conversion rate increases by 30%.
Impact: No PII stored, GDPR Article 5(1)(c) compliant (data minimization). No age verification cost per transaction after initial issuance.
Verilock implements the W3C Verifiable Credentials Data Model v2.0 standard with signed JWT format. Credentials are anchored to your organization’s Decentralized Identifier (DID).
Why Verifiable Credentials?
| Traditional KYC | With Verifiable Credentials |
|---|---|
| User re-verifies for every service | Verify once, reuse everywhere |
| Full PII shared each time | Selective disclosure — share only what’s needed |
| No user control over shared data | User chooses what to disclose |
| No interoperability between providers | W3C standard — works across platforms |
| High cost per re-verification | Issue once, verify for free |
How It Works
1
Verification completes
A user completes identity verification through the standard Verilock flow and receives an approved decision.
2
Credential issuance
You issue a verifiable credential containing selected claims from the verification result. The credential is signed as a JWT with your organization’s DID.
3
User stores credential
The user receives the credential as a signed JWT. They can store it in a digital wallet (Verilock wallet, or any W3C-compatible wallet).
4
Selective disclosure
When presenting the credential, the user selectively discloses only the claims required — e.g., “over 18” without revealing their full date of birth.
5
Third-party verification
Any organization with a Verilock API key can verify the credential’s authenticity, check revocation status, and read only the disclosed claims.
Selective Disclosure
Credentials support selective disclosure, allowing holders to reveal only specific claims:| Full Credential Claims | Age Check | Identity Check | AML Check |
|---|---|---|---|
| Full name | — | Full name | — |
| Date of birth | — | — | — |
| Nationality | — | Nationality | Nationality |
| Document number | — | — | — |
| Age over 18: true | Age over 18: true | — | — |
| AML clear: true | — | — | AML clear: true |
| Address | — | — | — |
API Endpoints
Issue a Credential
Issue a W3C Verifiable Credential from an approved verification session.POST /v1/credentials/issue
string
required
ID of an approved verification session.
string
required
Type of credential:
IdentityCredential, AgeCredential, or AddressCredential.string[]
required
Claims to include. Available:
full_name, first_name, last_name, date_of_birth, nationality, document_type, document_number, expiry_date, address, gender, age_over_18, age_over_21, aml_clear, identity_verified.string
ISO 8601 expiration date. Default: 1 year from issuance.
curl -X POST \
"https://verilock.io/api/v1/credentials/issue" \
-H "Authorization: Bearer qi_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"session_id": "ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"credential_type": "IdentityCredential",
"claims": ["full_name", "nationality", "age_over_18", "aml_clear"],
"expiration": "2027-03-19T00:00:00Z"
}'
credential = client.credentials.issue({
"session_id": "ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"credential_type": "IdentityCredential",
"claims": ["full_name", "nationality", "age_over_18", "aml_clear"],
"expiration": "2027-03-19T00:00:00Z",
})
print(credential["jwt"]) # Send to user for wallet storage
const credential = await verilock.credentials.issue({
session_id: 'ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890',
credential_type: 'IdentityCredential',
claims: ['full_name', 'nationality', 'age_over_18', 'aml_clear'],
expiration: '2027-03-19T00:00:00Z',
});
console.log(credential.jwt); // Send to user
{
"id": "vc_e5f6a1b2-c3d4-7890-fedc-ba0987654321",
"status": "issued",
"credential_type": "IdentityCredential",
"issuer_did": "did:verilock:org:your-org-id",
"subject_did": "did:verilock:user:user-uuid",
"claims": ["full_name", "nationality", "age_over_18", "aml_clear"],
"issued_at": "2026-03-19T10:00:00Z",
"expires_at": "2027-03-19T00:00:00Z",
"jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6InZjK3NkLWp3dCJ9.eyJpc3MiOiJkaWQ6dmVyaWxvY2s6b3JnOi4uLiIs..."
}
Verify a Credential
Verify a presented credential JWT. Any organization with a valid API key can call this endpoint.POST /v1/credentials/verify-vc
string
required
The credential JWT to verify.
curl -X POST \
"https://verilock.io/api/v1/credentials/verify-vc" \
-H "Authorization: Bearer qi_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6InZjK3NkLWp3dCJ9..."}'
{
"valid": true,
"credential_id": "vc_e5f6a1b2-c3d4-7890-fedc-ba0987654321",
"issuer_did": "did:verilock:org:issuing-org-id",
"issuer_verified": true,
"expired": false,
"revoked": false,
"disclosed_claims": {
"full_name": "Jean Dupont",
"nationality": "FR",
"age_over_18": true,
"aml_clear": true
},
"verified_at": "2026-03-19T12:00:00Z"
}
Get Credential in W3C Format
Retrieve the full W3C JSON-LD representation of a credential.GET /v1/credentials/{id}/vc
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://www.w3.org/ns/credentials/examples/v2"
],
"type": ["VerifiableCredential", "IdentityCredential"],
"issuer": "did:verilock:org:your-org-id",
"validFrom": "2026-03-19T10:00:00Z",
"validUntil": "2027-03-19T00:00:00Z",
"credentialSubject": {
"id": "did:verilock:user:user-uuid",
"full_name": "Jean Dupont",
"nationality": "FR",
"age_over_18": true,
"aml_clear": true
}
}
Revoke a Credential
POST /v1/credentials/{id}/revoke-vc
string
required
Revocation reason:
user_request, data_correction, fraud_detected, compliance.revoked: true.
Resolve a DID
Resolve any Verilock DID to its DID Document.GET /v1/did/{did}
{
"@context": ["https://www.w3.org/ns/did/v1"],
"id": "did:verilock:org:your-org-id",
"verificationMethod": [{
"id": "did:verilock:org:your-org-id#key-1",
"type": "JsonWebKey2020",
"controller": "did:verilock:org:your-org-id"
}],
"authentication": ["did:verilock:org:your-org-id#key-1"],
"assertionMethod": ["did:verilock:org:your-org-id#key-1"],
"service": [{
"id": "#verification",
"type": "VerificationService",
"serviceEndpoint": "https://verilock.io/api/v1"
}]
}
Use Cases
1. Cross-Platform Onboarding (Fintech)
A neobank verifies a user once and issues a VC. The user later signs up for a crypto exchange in the same ecosystem — instead of redoing KYC, they present their credential.// Neobank: Issue credential after KYC approval
const vc = await neobank.credentials.issue({
session_id: approvedSession.id,
credential_type: 'IdentityCredential',
claims: ['full_name', 'date_of_birth', 'nationality', 'aml_clear'],
});
// Send vc.jwt to user's wallet
// Crypto exchange: Verify the user's credential (no re-KYC needed)
const result = await exchange.credentials.verifyVc({ jwt: userJwt });
if (result.valid && result.disclosed_claims.aml_clear) {
// Onboard user immediately -- no document upload needed
createAccount(result.disclosed_claims);
}
2. Age-Gated E-Commerce (Alcohol / Tobacco)
An online retailer needs to verify a buyer is over 18 at checkout, without collecting or storing personal data (GDPR-friendly).# Issue an AgeCredential with minimal claims
vc = client.credentials.issue(
session_id=session_id,
credential_type="AgeCredential",
claims=["age_over_18"],
expiration="2027-01-01T00:00:00Z",
)
# At checkout, verify the buyer's age credential
result = client.credentials.verify_vc(jwt=buyer_jwt)
if result["valid"] and result["disclosed_claims"]["age_over_18"]:
# Age verified -- no DOB, name, or document stored
proceed_to_payment()
3. Marketplace Trust Layer (Gig Economy)
A freelance marketplace requires verified identities for service providers. Workers verify once and reuse their credential across multiple marketplace platforms.// Marketplace A verifies the worker
const vc = await marketplaceA.credentials.issue({
session_id: approvedSession.id,
credential_type: 'IdentityCredential',
claims: ['full_name', 'nationality', 'identity_verified', 'aml_clear'],
});
// Marketplace B accepts the same credential
const check = await marketplaceB.credentials.verifyVc({ jwt: workerJwt });
if (check.valid && check.disclosed_claims.identity_verified) {
activateProviderAccount(check.disclosed_claims.full_name);
}
4. Travel & Hospitality (Hotel Check-in)
A hotel chain issues identity credentials to verified guests. Guests use them for instant check-in at any hotel in the chain, without presenting physical ID each time.# Hotel issues credential after first verification
vc = client.credentials.issue(
session_id=session_id,
credential_type="IdentityCredential",
claims=["full_name", "nationality", "document_type"],
)
# Future check-ins: verify the credential
result = client.credentials.verify_vc(jwt=guest_jwt)
if result["valid"]:
check_in_guest(
name=result["disclosed_claims"]["full_name"],
nationality=result["disclosed_claims"]["nationality"],
)
5. Regulatory Compliance Sharing (Multi-Jurisdiction)
A payment processor operating in the EU and UK issues separate credentials for different regulatory requirements. The user presents the appropriate credential per jurisdiction.// Issue EU-compliant credential (AMLD6)
const euCred = await verilock.credentials.issue({
session_id: session.id,
credential_type: 'IdentityCredential',
claims: ['full_name', 'date_of_birth', 'nationality', 'aml_clear', 'address'],
});
// Issue UK-compliant credential (FCA)
const ukCred = await verilock.credentials.issue({
session_id: session.id,
credential_type: 'IdentityCredential',
claims: ['full_name', 'date_of_birth', 'nationality', 'aml_clear'],
});
// Each credential is independently verifiable and revocable
Credential Types
| Type | Claims Included | Use Case |
|---|---|---|
IdentityCredential | Any combination of identity claims | General KYC, onboarding, compliance |
AgeCredential | age_over_18, age_over_21 only | Age-gated services, minimal data |
AddressCredential | address, country_of_residence | Proof of residence, shipping verification |
Pricing
| Operation | Cost |
|---|---|
| Issue credential | $0.10 per credential |
| Verify credential | Free |
| Revoke credential | Free |
| DID resolution | Free |
Verifiable Credentials can only be issued from sessions with
decision: approved. Attempting to issue from a declined or pending session returns a 422 error.Combine Verifiable Credentials with Zero-Knowledge Proofs for maximum privacy. Issue a VC with full claims, then let users generate ZK proofs that reveal nothing except “this claim is true.”

