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

# Reusable KYC Credentials

> Issue portable, verifiable KYC credentials that users store in their wallet and share across organizations — eliminating redundant verification.

Reusable KYC lets a user verify their identity **once** and reuse the result everywhere. After an approved verification, you issue a portable credential that the user stores in the **Verilock Wallet** app. When another organization needs to verify them, they present the credential instead of redoing the entire KYC flow.

<Info>
  This page covers the **lightweight token-based** credential system. For W3C-standard Verifiable Credentials with selective disclosure and DID-based verification, see [Verifiable Credentials](/premium-features/verifiable-credentials).
</Info>

## Why Reusable KYC?

| Traditional KYC                      | With Reusable Credentials                    |
| ------------------------------------ | -------------------------------------------- |
| User re-verifies for every service   | Verify once, reuse across organizations      |
| 3-5 min onboarding flow each time    | Credential check in under 2 seconds          |
| \$1-3 per verification, per service  | Issue once (\$0.10), verify unlimited (free) |
| High drop-off at repeated KYC steps  | Frictionless onboarding, higher conversion   |
| Full PII collected by every provider | Only shared fields are disclosed             |

## How It Works

<Steps>
  <Step title="User completes KYC">
    The user goes through the standard Verilock verification flow (document upload, liveness check, AML screening) and receives an **approved** decision.
  </Step>

  <Step title="You issue a credential">
    Your backend calls `POST /v1/credentials` with the approved session ID and the fields you want to include. Verilock returns a portable token.
  </Step>

  <Step title="User stores in wallet">
    The credential appears in the user's **Verilock Wallet** app (iOS & Android). The wallet stores the token locally, encrypted and PIN-protected.
  </Step>

  <Step title="User presents credential">
    When another organization requests KYC, the user opens their wallet, scans a QR code, reviews the fields being shared, and consents to disclosure.
  </Step>

  <Step title="Organization verifies instantly">
    The receiving organization calls `POST /v1/credentials/verify` with the token. Verilock validates the credential and returns the shared identity data — no document upload, no selfie, no waiting.
  </Step>
</Steps>

***

## The Verilock Wallet

The **Verilock Wallet** is a mobile app (iOS & Android) that gives users full control over their identity credentials.

### Key Features

* **Encrypted local storage** — credentials are stored on-device with AES-256 encryption, protected by a 6-digit PIN and optional biometrics (Face ID / fingerprint)
* **Consent-based sharing** — users review exactly which fields are being requested and approve or deny each disclosure
* **QR code presentation** — scan a verifier's QR code to initiate a credential presentation, no manual token copy-paste
* **Offline signature verification** — the wallet verifies credential signatures locally using Ed25519, even without an internet connection
* **Revocation checks** — the wallet periodically checks credential status and flags any revoked or expired credentials
* **Backup & restore** — encrypted backup to recover credentials on a new device
* **Multi-credential support** — users can hold credentials from multiple organizations and choose which one to present

<Tip>
  You don't need to build your own wallet. The Verilock Wallet handles credential storage, consent flows, and secure presentation out of the box. Your users download it from the App Store or Google Play.
</Tip>

***

## Use Cases

### 1. Multi-Service Fintech Ecosystem

A fintech group operates a neobank, an investment platform, and an insurance product. A user verifies once on the neobank and reuses the credential for the other two services.

```javascript theme={null}
// Neobank: Issue credential after KYC approval
const cred = await fetch('https://verilock.io/api/v1/credentials', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer qi_live_neobank_key',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    session_id: 'ses_approved_session_id',
    shared_fields: ['full_name', 'date_of_birth', 'nationality'],
    expires_in_days: 365,
  }),
});
// User stores the credential in their Verilock Wallet

// Investment platform: Verify the credential (no re-KYC)
const result = await fetch('https://verilock.io/api/v1/credentials/verify', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer qi_live_invest_key',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ token: userCredentialToken }),
});
// result.shared_data contains { full_name, date_of_birth, nationality }
// Onboard the user immediately
```

**Impact**: Onboarding on the 2nd and 3rd service drops from 5 minutes to under 10 seconds. Conversion rate increases by 30%.

***

### 2. Marketplace Seller Verification

An e-commerce marketplace verifies sellers at sign-up. When a seller also wants to sell on a partner marketplace, they present the same credential instead of uploading documents again.

```python theme={null}
# Primary marketplace: Issue credential
response = requests.post(
    "https://verilock.io/api/v1/credentials",
    headers={"Authorization": "Bearer qi_live_marketplace_a_key"},
    json={
        "session_id": "ses_seller_approved",
        "shared_fields": ["full_name", "nationality", "address"],
        "expires_in_days": 180,
    },
)

# Partner marketplace: Accept the credential
result = requests.post(
    "https://verilock.io/api/v1/credentials/verify",
    headers={"Authorization": "Bearer qi_live_marketplace_b_key"},
    json={"token": seller_credential_token},
)
if result.json()["valid"]:
    activate_seller_account(result.json()["shared_data"])
```

**Impact**: Sellers activate on partner platforms in seconds. Reduces seller onboarding friction and increases supply-side growth.

***

### 3. Age-Restricted Purchases (Alcohol, Tobacco, Gaming)

An online retailer verifies age at account creation and issues a lightweight credential. On every subsequent purchase, the credential is checked — no repeated age verification.

```python theme={null}
# At sign-up: Verify age and issue credential
credential = requests.post(
    "https://verilock.io/api/v1/credentials",
    headers={"Authorization": "Bearer qi_live_key"},
    json={
        "session_id": "ses_age_verified",
        "shared_fields": ["full_name", "date_of_birth"],
        "expires_in_days": 365,
    },
).json()

# At every checkout: Quick credential check
check = requests.post(
    "https://verilock.io/api/v1/credentials/verify",
    headers={"Authorization": "Bearer qi_live_key"},
    json={"token": customer_token},
)
dob = check.json()["shared_data"]["date_of_birth"]
# Calculate age from DOB and proceed
```

**Impact**: Age verification only happens once. Every subsequent purchase is frictionless and free (verify calls are free).

***

### 4. Recurring Contractor Onboarding (Gig Economy)

A staffing agency verifies contractor identity once. When contractors are placed at different client companies, the client verifies the credential instead of running a separate background check.

```javascript theme={null}
// Agency: Issue credential for verified contractor
const cred = await fetch('https://verilock.io/api/v1/credentials', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer qi_live_agency_key',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    session_id: 'ses_contractor_verified',
    shared_fields: ['full_name', 'date_of_birth', 'nationality', 'document_type'],
    expires_in_days: 90,
  }),
});

// Client company: Verify contractor on day 1
const result = await fetch('https://verilock.io/api/v1/credentials/verify', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer qi_live_client_key',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ token: contractorToken }),
});
if (result.valid) {
  // Contractor is verified — ready to start
}
```

**Impact**: Contractors start work on day 1 without delays. Client companies save \$2-5 per contractor on redundant verification.

***

### 5. Multi-Jurisdiction Compliance (EU ↔ UK)

A payment processor operating across the EU and UK verifies users once and issues credentials scoped to each jurisdiction's requirements.

```python theme={null}
# Issue credential with EU-required fields (AMLD6)
eu_cred = requests.post(
    "https://verilock.io/api/v1/credentials",
    headers={"Authorization": "Bearer qi_live_key"},
    json={
        "session_id": "ses_approved",
        "shared_fields": ["full_name", "date_of_birth", "nationality", "address"],
        "expires_in_days": 365,
    },
).json()

# Issue a lighter credential for UK operations (FCA)
uk_cred = requests.post(
    "https://verilock.io/api/v1/credentials",
    headers={"Authorization": "Bearer qi_live_key"},
    json={
        "session_id": "ses_approved",
        "shared_fields": ["full_name", "date_of_birth", "nationality"],
        "expires_in_days": 365,
    },
).json()

# Each credential includes only what's required per jurisdiction
```

***

## API Reference

### Create Credential

```
POST /v1/credentials
```

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

<ParamField body="shared_fields" type="string[]">
  Fields to include. Default: `["full_name", "date_of_birth", "document_type", "nationality"]`.

  Available: `full_name`, `first_name`, `last_name`, `date_of_birth`, `nationality`, `document_type`, `document_number`, `expiry_date`, `address`, `gender`.
</ParamField>

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

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST \
    "https://verilock.io/api/v1/credentials" \
    -H "Authorization: Bearer qi_live_your_api_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "session_id": "ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "shared_fields": ["full_name", "date_of_birth", "nationality"],
      "expires_in_days": 180
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://verilock.io/api/v1/credentials",
      headers={
          "Authorization": "Bearer qi_live_your_api_key_here",
          "Content-Type": "application/json",
      },
      json={
          "session_id": "ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
          "shared_fields": ["full_name", "date_of_birth", "nationality"],
          "expires_in_days": 180,
      },
  )
  ```

  ```javascript Node.js theme={null}
  const res = await fetch('https://verilock.io/api/v1/credentials', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer qi_live_your_api_key_here',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      session_id: 'ses_a1b2c3d4-e5f6-7890-abcd-ef1234567890',
      shared_fields: ['full_name', 'date_of_birth', 'nationality'],
      expires_in_days: 180,
    }),
  });
  ```
</RequestExample>

<ResponseExample>
  ```json 201 Created theme={null}
  {
    "id": "cred_e5f6a1b2-c3d4-7890-fedc-ba0987654321",
    "token": "Abc123Def456Ghi789Jkl012Mno345Pqr678Stu901Vwx234Yz5678Ab901Cdef",
    "status": "active",
    "shared_fields": ["full_name", "date_of_birth", "nationality"],
    "verification_level": "standard",
    "expires_at": "2026-09-12T14:00:00Z"
  }
  ```
</ResponseExample>

<Tip>
  The `token` is the portable credential. Share it with the user — they store it in their Verilock Wallet and present it to other organizations instead of re-verifying.
</Tip>

***

### Get Credential

```
GET /v1/credentials/{id}
```

Retrieve credential details (only accessible by the issuing organization).

***

### Verify Credential

```
POST /v1/credentials/verify
```

Verify a credential token and retrieve the shared identity data. This endpoint can be called by **any organization** with a valid API key.

<ParamField body="token" type="string" required>
  The 64-character credential token.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST \
    "https://verilock.io/api/v1/credentials/verify" \
    -H "Authorization: Bearer qi_live_your_api_key_here" \
    -H "Content-Type: application/json" \
    -d '{"token": "Abc123Def456Ghi789Jkl012Mno345Pqr678Stu901Vwx234Yz5678Ab901Cdef"}'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 Valid theme={null}
  {
    "valid": true,
    "credential_id": "cred_e5f6a1b2-...",
    "verification_level": "standard",
    "shared_data": {
      "full_name": "Jean Dupont",
      "date_of_birth": "1990-05-15",
      "nationality": "FR"
    },
    "verification_result": {
      "decision": "approved",
      "risk_score": 12.50,
      "completed_at": "2026-03-16T14:02:15Z"
    },
    "issued_at": "2026-03-16T14:05:00Z",
    "expires_at": "2026-09-12T14:00:00Z"
  }
  ```

  ```json 404 Invalid theme={null}
  {
    "valid": false,
    "reason": "expired"
  }
  ```
</ResponseExample>

Possible `reason` values: `not_found`, `expired`, `revoked`.

***

### Revoke Credential

```
DELETE /v1/credentials/{id}
```

Permanently revoke a credential. Only the issuing organization can revoke.

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "message": "Credential revoked."
  }
  ```
</ResponseExample>

<Warning>
  Revoked credentials are immediately invalid. Any subsequent `verify` calls will return `"reason": "revoked"`. The user's wallet will also flag the credential as revoked on next sync.
</Warning>

***

## Pricing

| Operation         | Cost             |
| ----------------- | ---------------- |
| Issue credential  | \$0.10           |
| Verify credential | Free (unlimited) |
| Revoke credential | Free             |

***

## Going Further

<CardGroup cols={2}>
  <Card title="W3C Verifiable Credentials" icon="id-badge" href="/premium-features/verifiable-credentials">
    Need selective disclosure and DID-based verification? Issue W3C-standard credentials that are interoperable with any conforming wallet or verifier.
  </Card>

  <Card title="Zero-Knowledge Proofs" icon="lock-keyhole" href="/premium-features/zero-knowledge-proofs">
    Prove claims like "over 18" or "AML clear" without revealing any personal data. Maximum privacy for sensitive use cases.
  </Card>
</CardGroup>
