curl -X POST \
"https://verilock.io/api/v1/zkp/prove" \
-H "Authorization: Bearer qi_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"session_id": "ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"claim_type": "age_over",
"claim_value": 18,
"expires_in_days": 90
}'
proof = client.zkp.prove({
"session_id": "ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"claim_type": "age_over",
"claim_value": 18,
"expires_in_days": 90,
})
print(proof["proof_token"]) # Share with verifier
const proof = await verilock.zkp.prove({
session_id: 'ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890',
claim_type: 'age_over',
claim_value: 18,
expires_in_days: 90,
});
console.log(proof.proof_token); // Share with verifier
{
"id": "zkp_a1b2c3d4e5f6",
"claim_type": "age_over",
"claim_value": 18,
"result": true,
"proof_token": "eyJ6a3AiOiJ2ZXJpbG9jay16a3AtdjEiLCJhbGciOiJncm90aDE2In0...",
"issued_at": "2026-03-19T10:00:00Z",
"expires_at": "2026-06-17T10:00:00Z"
}
{
"error": "claim_not_satisfied",
"message": "The claim 'age_over 21' could not be satisfied from the session data.",
"claim_type": "age_over",
"claim_value": 21
}
Decentralized Identity
Zero-Knowledge Proofs
Prove identity claims without revealing underlying personal data.
POST
/
zkp
/
prove
curl -X POST \
"https://verilock.io/api/v1/zkp/prove" \
-H "Authorization: Bearer qi_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"session_id": "ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"claim_type": "age_over",
"claim_value": 18,
"expires_in_days": 90
}'
proof = client.zkp.prove({
"session_id": "ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"claim_type": "age_over",
"claim_value": 18,
"expires_in_days": 90,
})
print(proof["proof_token"]) # Share with verifier
const proof = await verilock.zkp.prove({
session_id: 'ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890',
claim_type: 'age_over',
claim_value: 18,
expires_in_days: 90,
});
console.log(proof.proof_token); // Share with verifier
{
"id": "zkp_a1b2c3d4e5f6",
"claim_type": "age_over",
"claim_value": 18,
"result": true,
"proof_token": "eyJ6a3AiOiJ2ZXJpbG9jay16a3AtdjEiLCJhbGciOiJncm90aDE2In0...",
"issued_at": "2026-03-19T10:00:00Z",
"expires_at": "2026-06-17T10:00:00Z"
}
{
"error": "claim_not_satisfied",
"message": "The claim 'age_over 21' could not be satisfied from the session data.",
"claim_type": "age_over",
"claim_value": 21
}
Zero-Knowledge Proofs (ZKP) allow users to prove specific claims about their identity — such as “I am over 18” or “I passed AML screening” — without disclosing any underlying personal data. The verifier learns nothing except that the claim is true.
Only accessible by the issuing organization.
Revoked proofs immediately fail verification.
Compliance benefit: No PII stored means no data breach risk, no GDPR Article 15 (access) or Article 17 (erasure) obligations for age data.
Impact: Bridges the gap between regulatory compliance and crypto privacy. Users prove compliance without doxxing themselves.
ZKPs are the most privacy-preserving verification method available. No name, date of birth, document, or address is ever revealed to the verifier.
Why Zero-Knowledge Proofs?
| Standard Verification | With ZKP |
|---|---|
| Full PII shared | Zero personal data disclosed |
| Data stored by verifier | Nothing to store — no GDPR liability |
| Re-identification risk | Mathematically impossible to extract PII |
| Per-verification cost | Generate once, verify unlimited times |
| Trust required in verifier | Trustless — cryptographic guarantee |
How It Works
1
Verification completes
A user completes identity verification and their session is approved.
2
Proof generation
You request a ZK proof for specific claims. Verilock generates a cryptographic commitment from the verified session data, without exposing the raw data.
3
User receives proof
The user receives a compact proof token that they can share with any third party.
4
Trustless verification
The verifier submits the proof token to Verilock. The system confirms the proof is valid and the claim is true — without revealing any personal data.
Supported Claim Types
| Claim Type | Value | What It Proves | Example |
|---|---|---|---|
age_over | integer | Age exceeds threshold | User is over 18 |
nationality_is | string | Holds specific nationality | User is a French national |
name_matches | string | Name matches (85% similarity) | User’s name matches “Jean Dupont” |
identity_verified | boolean | Passed KYC verification | User has a verified identity |
aml_clear | boolean | No AML/sanctions matches | User is not on any watchlist |
residency_country | string | Resides in specific country | User resides in Germany |
API Endpoints
Generate a Proof
POST /v1/zkp/prove
string
required
ID of an approved verification session.
string
required
One of:
age_over, nationality_is, name_matches, identity_verified, aml_clear, residency_country.mixed
required
The claim parameter: age threshold (integer), country code (string), name (string), or boolean.
integer
Validity in days (1—365). Default: 90.
curl -X POST \
"https://verilock.io/api/v1/zkp/prove" \
-H "Authorization: Bearer qi_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"session_id": "ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"claim_type": "age_over",
"claim_value": 18,
"expires_in_days": 90
}'
proof = client.zkp.prove({
"session_id": "ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"claim_type": "age_over",
"claim_value": 18,
"expires_in_days": 90,
})
print(proof["proof_token"]) # Share with verifier
const proof = await verilock.zkp.prove({
session_id: 'ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890',
claim_type: 'age_over',
claim_value: 18,
expires_in_days: 90,
});
console.log(proof.proof_token); // Share with verifier
{
"id": "zkp_a1b2c3d4e5f6",
"claim_type": "age_over",
"claim_value": 18,
"result": true,
"proof_token": "eyJ6a3AiOiJ2ZXJpbG9jay16a3AtdjEiLCJhbGciOiJncm90aDE2In0...",
"issued_at": "2026-03-19T10:00:00Z",
"expires_at": "2026-06-17T10:00:00Z"
}
{
"error": "claim_not_satisfied",
"message": "The claim 'age_over 21' could not be satisfied from the session data.",
"claim_type": "age_over",
"claim_value": 21
}
If the claim cannot be satisfied (e.g., user is 17 and you request
age_over: 18), the API returns a 422 error. No proof is generated and no data is leaked about why the claim failed.Verify a Proof
Verify a proof token. This endpoint never returns personal data — only whether the claim is true.POST /v1/zkp/verify
string
required
The proof token to verify.
curl -X POST \
"https://verilock.io/api/v1/zkp/verify" \
-H "Authorization: Bearer qi_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"proof_token": "eyJ6a3AiOiJ2ZXJpbG9jay16a3AtdjEi..."}'
{
"valid": true,
"claim_type": "age_over",
"claim_value": 18,
"result": true,
"expired": false,
"revoked": false,
"times_verified": 3,
"verified_at": "2026-03-19T12:00:00Z"
}
Get Proof Details
GET /v1/zkp/{id}
Revoke a Proof
POST /v1/zkp/{id}/revoke
Use Cases
1. Age Verification Without PII (Gaming / Alcohol / Cannabis)
An online gaming platform needs to verify players are over 18 to comply with regulations, but doesn’t want to collect or store personal data.// Game platform: Verify age proof at registration
const result = await platform.zkp.verify({
proof_token: playerProvidedToken,
});
if (result.valid && result.result === true) {
// Player is verified as over 18
// Zero personal data collected or stored
// No GDPR data subject access requests to handle
createPlayerAccount();
}
2. Anonymous AML Compliance (DeFi / Crypto)
A DeFi protocol needs to verify users are not sanctioned without collecting identity data (preserving pseudonymity while meeting compliance).# DeFi protocol: Check AML status without collecting identity
result = client.zkp.verify(proof_token=user_proof)
if result["valid"] and result["claim_type"] == "aml_clear" and result["result"]:
# User has passed AML screening
# Protocol knows nothing about the user's identity
# Compliant with OFAC while preserving privacy
allow_protocol_access(wallet_address)
3. Employment Nationality Check (HR / Recruitment)
An employer needs to verify a candidate has the right to work in a country, without collecting passport or visa copies during the application stage.// HR system: Verify right to work
const proof = await hr.zkp.verify({
proof_token: candidateProof,
});
if (proof.valid && proof.claim_type === 'nationality_is') {
// Candidate confirmed as national of the required country
// No passport copy collected during application
// Physical documents only needed at contract signing
moveToNextStage(candidate);
}
4. Privacy-Preserving Credit Check (Lending)
A lending platform needs to verify identity without building a full profile. The user proves specific facts needed for the credit decision.# Generate multiple proofs from one session
age_proof = client.zkp.prove(
session_id=session_id,
claim_type="age_over",
claim_value=18,
)
identity_proof = client.zkp.prove(
session_id=session_id,
claim_type="identity_verified",
claim_value=True,
)
aml_proof = client.zkp.prove(
session_id=session_id,
claim_type="aml_clear",
claim_value=True,
)
# User shares all three proofs with the lender
# Lender verifies each independently
# Result: identity confirmed, age confirmed, AML clear
# No name, DOB, address, or document data shared
5. Anonymous Event Access (Conferences / Venues)
A conference organizer needs to verify attendees have been identity-verified (for security) without collecting their personal data.// Conference check-in: Scan QR code containing proof token
const result = await venue.zkp.verify({
proof_token: scannedToken,
});
if (result.valid && result.claim_type === 'identity_verified' && result.result) {
// Attendee has a verified identity -- allow entry
// No name or photo collected at the door
openGate();
}
6. Cross-Border Residency Verification (EU Regulations)
A financial service needs to confirm a user resides in the EU for MiCA compliance, without collecting their full address.proof = client.zkp.prove(
session_id=session_id,
claim_type="residency_country",
claim_value="FR", # Or any EU country code
)
# Verifier checks
result = client.zkp.verify(proof_token=proof["proof_token"])
if result["valid"] and result["result"]:
# User confirmed as resident of France
# No address, no utility bill, no data stored
enable_eu_services()
Combining ZKP with Verifiable Credentials
For maximum flexibility, issue a Verifiable Credential first, then generate ZK proofs from it:// Step 1: Issue a full credential after KYC
const vc = await verilock.credentials.issue({
session_id: session.id,
credential_type: 'IdentityCredential',
claims: ['full_name', 'date_of_birth', 'nationality', 'aml_clear'],
});
// Step 2: User generates ZKP proofs for specific claims
const ageProof = await verilock.zkp.prove({
session_id: session.id,
claim_type: 'age_over',
claim_value: 18,
});
// User now has:
// - A full VC for services that need identity data (banks, regulated platforms)
// - A ZK proof for services that only need age verification (e-commerce, gaming)
| Scenario | Use VC | Use ZKP |
|---|---|---|
| Regulated onboarding (bank, exchange) | Yes | — |
| Age-gated content | — | Yes |
| Cross-platform KYC reuse | Yes | — |
| Anonymous compliance proof | — | Yes |
| Marketplace trust | Yes | — |
| Privacy-preserving access control | — | Yes |
Pricing
| Operation | Cost |
|---|---|
| Generate proof | Included with session |
| Verify proof | Free |
| Revoke proof | Free |
ZK proofs can be verified unlimited times at no cost. Generate proofs generously — the per-proof cost is included in the session price.
Proofs can only be generated from sessions with
decision: approved. The claim must be satisfiable from the session’s extracted data.
