> ## Documentation Index
> Fetch the complete documentation index at: https://developer.verilock.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Zero-Knowledge Proofs

> Prove identity claims without revealing underlying personal data.

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.

<Info>
  ZKPs are the most privacy-preserving verification method available. No name, date of birth, document, or address is ever revealed to the verifier.
</Info>

## 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

<Steps>
  <Step title="Verification completes">
    A user completes identity verification and their session is approved.
  </Step>

  <Step title="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.
  </Step>

  <Step title="User receives proof">
    The user receives a compact proof token that they can share with any third party.
  </Step>

  <Step title="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.
  </Step>
</Steps>

## 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
```

<ParamField body="session_id" type="string" required>
  ID of an **approved** verification session.
</ParamField>

<ParamField body="claim_type" type="string" required>
  One of: `age_over`, `nationality_is`, `name_matches`, `identity_verified`, `aml_clear`, `residency_country`.
</ParamField>

<ParamField body="claim_value" type="mixed" required>
  The claim parameter: age threshold (integer), country code (string), name (string), or boolean.
</ParamField>

<ParamField body="expires_in_days" type="integer">
  Validity in days (1--365). Default: 90.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  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
    }'
  ```

  ```python Python theme={null}
  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
  ```

  ```javascript Node.js theme={null}
  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
  ```
</RequestExample>

<ResponseExample>
  ```json 201 Created theme={null}
  {
    "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"
  }
  ```

  ```json 422 Claim Failed theme={null}
  {
    "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
  }
  ```
</ResponseExample>

<Warning>
  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.
</Warning>

***

### Verify a Proof

Verify a proof token. This endpoint **never returns personal data** -- only whether the claim is true.

```
POST /v1/zkp/verify
```

<ParamField body="proof_token" type="string" required>
  The proof token to verify.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  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..."}'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "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"
  }
  ```
</ResponseExample>

***

### Get Proof Details

```
GET /v1/zkp/{id}
```

Only accessible by the issuing organization.

***

### Revoke a Proof

```
POST /v1/zkp/{id}/revoke
```

Revoked proofs immediately fail verification.

***

## 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.

```javascript theme={null}
// 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();
}
```

**Compliance benefit**: No PII stored means no data breach risk, no GDPR Article 15 (access) or Article 17 (erasure) obligations for age data.

***

### 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).

```python theme={null}
# 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)
```

**Impact**: Bridges the gap between regulatory compliance and crypto privacy. Users prove compliance without doxxing themselves.

***

### 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.

```javascript theme={null}
// 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.

```python theme={null}
# 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.

```javascript theme={null}
// 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.

```python theme={null}
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](/premium-features/verifiable-credentials) first, then generate ZK proofs from it:

```javascript theme={null}
// 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                  |

<Tip>
  ZK proofs can be verified unlimited times at no cost. Generate proofs generously -- the per-proof cost is included in the session price.
</Tip>

<Warning>
  Proofs can only be generated from sessions with `decision: approved`. The claim must be satisfiable from the session's extracted data.
</Warning>
