> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.vlenseg.com/llms.txt.
> For full documentation content, see https://docs.vlenseg.com/llms-full.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.vlenseg.com/_mcp/server.

# Digital Identity

Digital Identity (DI) verification confirms that your users are who they say they are. Vlens performs OCR on the Egyptian national ID (front + back), runs passive liveness detection using three face images, and optionally validates against NTRA and CSO authority databases.

***

## Concepts

### Validation vs. Verification

The user completed all three capture steps and the OCR data passed Vlens internal checks.
`isVerificationProcessCompleted: true`

Validated **plus** NTRA and CSO authority checks both passed.
`isDigitalIdentityVerified: true`

Whether NTRA and CSO checks are required depends on your tenant configuration. If both are disabled, a user is marked Verified as soon as all three capture steps pass.

### The transaction

All three capture steps share a single `transaction_id`. The ID is returned in the first step's response and must be passed to every subsequent step.

```mermaid
sequenceDiagram
    participant App
    participant Vlens

    App->>Vlens: POST /verify/id/front
    Vlens-->>App: transaction_id + OCR front data

    App->>Vlens: POST /verify/id/back (transaction_id)
    Vlens-->>App: OCR back data

    App->>Vlens: POST /verify/liveness/multi (transaction_id)
    Vlens-->>App: isDigitalIdentityVerified: true/false
```

You may submit `id/front` or `id/back` in any order, but **both must complete before liveness**.

***

## Prerequisites

The user must be registered before calling the verification endpoints. Registration returns a **user access token** — use it as `Authorization: Bearer <token>` for all verification calls.

See the [Quick Start](/quickstart) for the registration steps.

***

## Step 1 — Scan ID front

```bash
curl -X POST https://api.vlenseg.com/api/DigitalIdentity/verify/id/front \
  -H "ApiKey: YOUR_API_KEY" \
  -H "Authorization: Bearer USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "image": "BASE64_ID_FRONT_IMAGE",
    "getExtractedData": true
  }'
```

```javascript
const res = await fetch(
  "https://api.vlenseg.com/api/DigitalIdentity/verify/id/front",
  {
    method: "POST",
    headers: {
      "ApiKey": API_KEY,
      "Authorization": `Bearer ${userToken}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ image: base64Front, getExtractedData: true })
  }
);
const { data } = await res.json();
const transactionId = data.idFrontData.transaction_id; // save this
```

```python
import requests

res = requests.post(
    "https://api.vlenseg.com/api/DigitalIdentity/verify/id/front",
    headers={
        "ApiKey": API_KEY,
        "Authorization": f"Bearer {user_token}"
    },
    json={"image": base64_front, "getExtractedData": True}
)
transaction_id = res.json()["data"]["idFrontData"]["transaction_id"]
```

**Save `data.idFrontData.transaction_id`** — you need it for steps 2 and 3.

**Fields extracted from the front:**

| Field                                       | Description         |
| ------------------------------------------- | ------------------- |
| `first_name` / `last_names`                 | Arabic name         |
| `first_name_english` / `last_names_english` | Transliterated name |
| `idNumber`                                  | National ID number  |
| `dateOfBirth`                               | ISO 8601 date       |
| `govern` / `city` / `district`              | Address             |
| `gender`                                    | M / F               |

***

## Step 2 — Scan ID back

```bash
curl -X POST https://api.vlenseg.com/api/DigitalIdentity/verify/id/back \
  -H "ApiKey: YOUR_API_KEY" \
  -H "Authorization: Bearer USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "image": "BASE64_ID_BACK_IMAGE",
    "transaction_id": "TRANSACTION_ID"
  }'
```

```javascript
await fetch(
  "https://api.vlenseg.com/api/DigitalIdentity/verify/id/back",
  {
    method: "POST",
    headers: {
      "ApiKey": API_KEY,
      "Authorization": `Bearer ${userToken}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      image: base64Back,
      transaction_id: transactionId
    })
  }
);
```

```python
requests.post(
    "https://api.vlenseg.com/api/DigitalIdentity/verify/id/back",
    headers={"ApiKey": API_KEY, "Authorization": f"Bearer {user_token}"},
    json={"image": base64_back, "transaction_id": transaction_id}
)
```

**Additional fields from the back:**

| Field              | Description    |
| ------------------ | -------------- |
| `maritalStatus`    | Marital status |
| `job` / `jobTitle` | Occupation     |
| `religion`         | Religion       |
| `idExpiry`         | ID expiry date |
| `releaseDate`      | ID issue date  |

***

## Step 3 — Liveness detection

**All three images must be captured within 0.5 seconds of each other.** Identical images or images captured too far apart will fail the liveness check. Compress each image to under 500 KB for best performance.

```bash
curl -X POST https://api.vlenseg.com/api/DigitalIdentity/verify/liveness/multi \
  -H "ApiKey: YOUR_API_KEY" \
  -H "Authorization: Bearer USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "image": "BASE64_ID_FRONT",
    "face_1": "BASE64_FACE_1",
    "face_2": "BASE64_FACE_2",
    "face_3": "BASE64_FACE_3",
    "transaction_id": "TRANSACTION_ID",
    "getExtractedData": true
  }'
```

```javascript
const res = await fetch(
  "https://api.vlenseg.com/api/DigitalIdentity/verify/liveness/multi",
  {
    method: "POST",
    headers: {
      "ApiKey": API_KEY,
      "Authorization": `Bearer ${userToken}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      image: base64Front,
      face_1: base64Face1,
      face_2: base64Face2,
      face_3: base64Face3,
      transaction_id: transactionId,
      getExtractedData: true
    })
  }
);
const { data } = await res.json();

if (data.isDigitalIdentityVerified) {
  // User is fully verified — proceed to contract creation
}
```

```python
res = requests.post(
    "https://api.vlenseg.com/api/DigitalIdentity/verify/liveness/multi",
    headers={"ApiKey": API_KEY, "Authorization": f"Bearer {user_token}"},
    json={
        "image": base64_front,
        "face_1": base64_face1,
        "face_2": base64_face2,
        "face_3": base64_face3,
        "transaction_id": transaction_id,
        "getExtractedData": True
    }
)
is_verified = res.json()["data"]["isDigitalIdentityVerified"]
```

**Success response:**

```json
{
  "data": {
    "isVerificationProcessCompleted": true,
    "isDigitalIdentityVerified": true,
    "user": { "idNumber": "29901234567890" }
  },
  "services": {
    "liveness": true,
    "spoofing": { "fake": false },
    "SRC": { "isValid": true },
    "AML": { "AML_matched": false }
  },
  "error_code": null
}
```

***

## Alternative: link an existing transaction

If your app captures the national ID **before** the user logs in (using API-key-only calls), you can link the completed transaction to the user after login instead of repeating the capture flow.

```bash
curl -X POST https://api.vlenseg.com/api/DigitalIdentity/LinkUserWithExistingTransaction \
  -H "ApiKey: YOUR_API_KEY" \
  -H "Authorization: Bearer USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "transactionId": "EXISTING_TRANSACTION_ID",
    "getExtractedData": true
  }'
```

**When to use this:** The client performs OCR using only the `ApiKey` while the user is not yet authenticated. After login, call this endpoint to associate the completed verification with the user's account — no re-capture needed.

***

## Backend verification services

Each response includes a `services` object with results from the backend checks:

| Service            | Field                              | What it checks                                              |
| ------------------ | ---------------------------------- | ----------------------------------------------------------- |
| **Spoofing**       | `services.spoofing.fake`           | Whether the document is a photocopy or digital reproduction |
| **Classification** | `services.classification.doc_type` | Document type detection                                     |
| **Liveness**       | `services.liveness`                | Whether the face images passed liveness detection           |
| **AML**            | `services.AML.AML_matched`         | Whether the user is on an AML watchlist                     |
| **SRC**            | `services.SRC.isValid`             | Whether the ID validates against the national registry      |

***

## Admin: retrieve verification images

Admins with the `Requests` permission can retrieve stored identity images for audit or support:

```bash
# Step 1 — Get file names
curl "https://api.vlenseg.com/api/DigitalIdentity/GetUserDigitalIdentityImages\
?emailOrPhoneNumber=%2B201234567890" \
  -H "ApiKey: YOUR_API_KEY" \
  -H "Authorization: Bearer ADMIN_TOKEN"

# Step 2 — Download a specific image as base64
curl "https://api.vlenseg.com/api/DigitalIdentity/GetStepImage\
?TransactionId=TX_ID&FileName=FILENAME" \
  -H "ApiKey: YOUR_API_KEY" \
  -H "Authorization: Bearer ADMIN_TOKEN"
```