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

# Node.js / TypeScript

> Official Node.js SDK for the Verilock Identity API.

## Installation

```bash theme={null}
npm install @verilock/node-sdk
```

## Configuration

```typescript theme={null}
import Verilock from '@verilock/node-sdk';

const verilock = new Verilock({
  apiKey: 'qi_live_...',       // or set VERILOCK_API_KEY env var
  baseUrl: 'https://verilock.io/api/v1', // optional
  timeout: 30_000,             // optional, ms (default: 30000)
  maxRetries: 2,               // optional, retries on 429/5xx
});
```

<Tip>
  Use a `qi_test_` key during development. Test keys return simulated results and are free to use.
</Tip>

## Quick Start

```typescript theme={null}
import Verilock from '@verilock/node-sdk';

const verilock = new Verilock({ apiKey: process.env.VERILOCK_API_KEY! });

// Create a KYC session
const session = await verilock.sessions.create({
  applicant_email: 'john@example.com',
  applicant_name: 'John Doe',
  redirect_url: 'https://example.com/callback',
});

// Redirect the user to complete verification
console.log(session.session_url);

// Later, retrieve the result
const result = await verilock.sessions.retrieve(session.id);
console.log(result.status); // 'approved' | 'rejected' | 'pending' | ...
```

## KYC Sessions

### Create a session

```typescript theme={null}
const session = await verilock.sessions.create({
  applicant_email: 'jane@example.com',
  applicant_name: 'Jane Smith',
  redirect_url: 'https://example.com/done',
});
// session.session_url -> hosted verification link
```

### List sessions

```typescript theme={null}
const { data, pagination } = await verilock.sessions.list({
  status: 'approved',
  page: 1,
  per_page: 25,
});
```

### Retrieve a session

```typescript theme={null}
const session = await verilock.sessions.retrieve('sess_abc123');
```

### Upload a document

```typescript theme={null}
import { readFileSync } from 'fs';

await verilock.sessions.uploadDocument({
  session_id: 'sess_abc123',
  file: readFileSync('./id_front.jpg'),
  side: 'front',
  document_type: 'passport',
});
```

### Upload a selfie

```typescript theme={null}
await verilock.sessions.uploadSelfie({
  session_id: 'sess_abc123',
  file: readFileSync('./selfie.jpg'),
});
```

### Submit for evaluation

```typescript theme={null}
const result = await verilock.sessions.submit('sess_abc123');
console.log(result.status); // 'processing'
```

<Info>
  Call `submit()` only after all required documents and selfie have been uploaded. The session enters asynchronous processing and you will receive a webhook when it completes.
</Info>

## AML Screening

### Screen a person

```typescript theme={null}
const result = await verilock.aml.screen({
  name: 'John Doe',
  date_of_birth: '1990-01-15',
  nationality: 'US',
});

if (result.status === 'match') {
  console.log(`Found ${result.matches_found} matches`);
}
```

### Retrieve a screening

```typescript theme={null}
const screening = await verilock.aml.retrieve('aml_abc123');
```

### Submit a decision

```typescript theme={null}
await verilock.aml.decide('aml_abc123', {
  decision: 'false_positive',
  reason: 'Name similarity only, different date of birth.',
});
```

## Transaction Monitoring

### Screen a transaction

```typescript theme={null}
const result = await verilock.transactions.screen({
  transaction_ref: 'TX-001',
  sender_name: 'Alice Corp',
  receiver_name: 'Bob Ltd',
  amount: 15000,
  currency: 'USD',
});

if (result.risk_level === 'high') {
  console.log(`${result.alerts_count} alerts triggered`);
}
```

### Batch screening

```typescript theme={null}
const batch = await verilock.transactions.screenBatch({
  transactions: [
    { transaction_ref: 'TX-002', sender_name: 'Alice', receiver_name: 'Bob', amount: 500, currency: 'EUR' },
    { transaction_ref: 'TX-003', sender_name: 'Carol', receiver_name: 'Dave', amount: 12000, currency: 'USD' },
  ],
});
```

### List, retrieve, and decide

```typescript theme={null}
const { data } = await verilock.transactions.list({ risk_level: 'high' });

const detail = await verilock.transactions.retrieve('txn_abc123');

await verilock.transactions.decide('txn_abc123', {
  decision: 'approve',
  reason: 'Verified sender identity manually.',
});
```

## Premium Features

<Warning>
  Premium features require a paid plan. Calls made without an active subscription return an `InsufficientBalanceError`.
</Warning>

```typescript theme={null}
// Biometric face authentication
const match = await verilock.biometric.verify({ session_id: 'sess_abc123', selfie: fileBuffer });

// Government database validation
const dbCheck = await verilock.database.validate({ document_number: 'AB123456', country: 'US' });

// 1:N face duplicate detection
const duplicates = await verilock.faceSearch.search({ selfie: fileBuffer });

// Crypto wallet compliance screening
const walletResult = await verilock.wallet.screen({ address: '0xabc...', chain: 'ethereum' });

// Reusable KYC credentials
const credential = await verilock.credentials.issue({ session_id: 'sess_abc123' });

// Age verification from selfie
const age = await verilock.ageVerify.verify({ selfie: fileBuffer, min_age: 18 });
```

## Error Handling

All SDK errors extend `VerilockError`. Use specific classes for granular handling.

```typescript theme={null}
import Verilock, {
  VerilockError,
  AuthenticationError,
  InsufficientBalanceError,
  NotFoundError,
  ValidationError,
  RateLimitError,
} from '@verilock/node-sdk';

try {
  const session = await verilock.sessions.create({
    applicant_email: 'john@example.com',
    redirect_url: 'https://example.com/callback',
  });
} catch (err) {
  if (err instanceof InsufficientBalanceError) {
    console.error(`Balance: ${err.balance}, required: ${err.required}`);
  } else if (err instanceof ValidationError) {
    console.error('Field errors:', err.errors);
  } else if (err instanceof RateLimitError) {
    console.error(`Retry after ${err.retryAfter}s`);
  } else if (err instanceof AuthenticationError) {
    console.error('Invalid API key');
  } else if (err instanceof NotFoundError) {
    console.error('Resource not found');
  } else if (err instanceof VerilockError) {
    console.error(`API error [${err.code}]: ${err.message}`);
  }
}
```

## TypeScript Types

The SDK exports all request and response types for full type safety.

```typescript theme={null}
import type {
  CreateSessionParams,
  CreateSessionResponse,
  Session,
  ScreenPersonParams,
  AmlScreeningResult,
  ScreenTransactionParams,
  TransactionScreeningResult,
  PaginatedResponse,
} from '@verilock/node-sdk';
```

<Tip>
  All resource methods accept an optional `RequestOptions` parameter as the last argument for per-request overrides such as custom headers or abort signals.
</Tip>
