> 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 AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.vlenseg.com/_mcp/server.

# Changelog

Stay up to date with changes to the Vlens API, documentation, and platform.

## October 29, 2026

## New features

### ID card verification from a single PDF

The national ID can now be uploaded as **one PDF that contains both the front and the back**, instead of two separate images.

```bash
POST /api/FRAServices/PersonallyIdentifiableInformationPdf
Content-Type: multipart/form-data

file=@national-id.pdf
phoneNumber=01000000000
```

* Required fields: `file` and `phoneNumber`. Optional: `otpRequestId`, `otpCode`, `transactionId` and `bypassSpoofingCheck`.
* The file must be a real PDF and no larger than 5 MB.
* The front and back are saved as the usual ID front and ID back steps, and the response is the same as for `POST /api/FRAServices/PersonallyIdentifiableInformation`.

The **Check Phone Ownership** page in the portal has a new **Upload ID card as one PDF** option — see [Check Phone Ownership](/portal/check-phone-ownership).

See [Submit the ID as one PDF](/fra-services/pii-inquiry#submit-the-id-as-one-pdf).

### Business Requests: signed date filters

The **Business Requests** page has two new filters: **Customer Signed Date Range** and **Service Provider Signed Date Range**. `GET /api/BusinessRequest/GetRequests` supports the same filters: `CustomerSignedFrom` / `CustomerSignedTo` and `ServiceProviderSignedFrom` / `ServiceProviderSignedTo`.

See [Business Requests](/portal/business-requests) and, for the API, [Retrieve contracts](/e-contracting#retrieve-contracts).

### Business Requests: Contract Name column

The Business Requests list, including child request rows, now shows a **Contract Name** column. See [Business Requests](/portal/business-requests#contract-name-column).

## Enhancements

### Faster liveness GIF loading

The liveness GIF is now generated once and cached, so later views load faster.

### Smaller scan step responses

API responses no longer include duplicate base64 copies of the scan step images (the ID image and the liveness faces).

> **Note**
>
> If your integration read these duplicate base64 image fields from scan step responses, it will no longer find them there.

### Landing page based on permissions (portal)

After login, or when opening an unknown link, users now go to the first page they have permission for. Before, everyone was sent to **Transactions**, and users without that permission saw a "permission denied" page. See [Portal overview](/portal#landing-page-after-login).

## Bug fixes

* OCR validation error `5008` (`Data Misassigned`) is no longer replaced with the generic `5000` (`General Error`). Clients now receive the real error code and message. See [Error codes](/errors#general--document-errors-5xxx)

## October 26, 2026

## New features

### Change Phone Number Session

Users can now change their registered phone number through an invitation link or an embedded session.

* Admins with the new **Change Phone Number Invitation** permission can send an invitation from the **Users** page. The invitation is emailed, so the user's email must be confirmed. English and Arabic email templates are included. See [Users & invitations](/portal/users-and-invitations#change-phone-number-invitation).
* The user confirms the new number with an SMS code (OTP).
* Users with a verified digital identity must also pass a face match against their stored biometric data. For other users, phone ownership is checked and the number is updated right after the OTP is verified.
* The new number can't be the same as the current number.

New endpoints under `api/ChangePhoneNumberSession`: `CreateInvitation`, `CreateSession`, `GetUserSessionSettings`, `SendOtp`, `VerifyOtp` and `ValidateFaceMatch`.

See [Change Phone Number Session](/iframe-session#change-phone-number-session).

### Prevent new request on rejection (iframe)

A new session permission, **Prevent New Request On Rejection** (`sessionPermissions.preventNewRequestOnRejection`), can be set when creating an invitation and is shown in the invitation and session details. When it is enabled, inside the iframe:

* The user can't start a new request for a contract type that was already rejected for them.
* If every allowed contract type is already signed or rejected, the session is treated as fulfilled.

Rejected requests no longer count as signed contracts.

See [Prevent new request on rejection](/iframe-session#prevent-new-request-on-rejection) and, for the portal, [Users & invitations](/portal/users-and-invitations#prevent-new-request-on-rejection).

### Signing status in contract emails

Contract emails now show who has signed: **Customer Signed** or **Service Provider Signed**. Two new placeholders are available for the email subject and body: `{BUSINESS_REQUEST_TYPE}` and `{SIGNING_STATUS}`.

The new default subject is:

```
{TENANT_NAME} - {BUSINESS_REQUEST_TYPE} - {SIGNING_STATUS}
```

See [Contract emails](/e-contracting#contract-emails).

### Infobip base URL and sender name per tenant

The Infobip settings in the portal now include **Base URL** and **Sender Name**, and **Test Connection** uses them. The base URL can be entered without `https://`. Tenants that only saved an API key keep using the default base URL and sender. See [Settings](/portal/settings).

## Enhancements

### Faster, more stable contract PDFs

Contract PDF generation is faster and more stable under load.

### Clear 404 for unknown endpoints

Calls to an endpoint that doesn't exist now return **HTTP 404** `Endpoint not found` instead of an authentication error. See [HTTP error codes](/errors#http-error-codes).

## Bug fixes

* Email matching in user lookups is no longer case-sensitive
* Hidden or invisible characters and extra spaces are removed from the email or phone number before the user lookup

## October 13, 2026

## New features

### SMS provider option on the PII consent OTP

`POST /api/FRAServices/RequestOtpForPii` now accepts an optional `smsProviders` field, matching the rest of the API. Omit it — or send `0` — and the tenant's default provider is used, so existing callers are unaffected.

```bash
POST /api/FRAServices/RequestOtpForPii
{
  "phoneNumber": "+201234567890",
  "smsProviders": 2
}
```

See [PII inquiry with OTP](/fra-services/pii-inquiry-otp) for the full flow.

### Users with AML matches

A new portal page (**Users With AML**) lists users whose ID front scan matched an AML record, showing user ID, name, phone number, transaction ID and scan date. Results are paged, searchable by name, surname, phone, email, ID number or transaction ID, and filterable by date range. Available to tenants and to the host while impersonating a tenant.

Access is controlled by the new **Pages.AmlUsers** permission — grant it to the roles that should see the page.

### Custom confirmation content on business request types

Request types can now carry their own confirmation text, set on the request type screen and saved with each request. It is rendered in the KYC confirmation section of the generated contract, after the standard declaration and before the request fields, for both standard and promissory-note types, in English and Arabic.

It is not shown when the type is single-section or when KYC confirmation is hidden.

## Enhancements

### Scan step retries are driven by one setting

Scan step retries are now controlled solely by the **Scan Step Max Tries Count** feature. The default remains `6`; setting it to `0` means unlimited tries, with every request counted as a new request. The old **Enable Scan Step Retry** checkbox has been removed from the Create/Edit Tenant screens.

> **Note**
>
> Tenants that relied on the old **Enable Scan Step Retry** flag fall back to the 6-try limit after this release. Set **Scan Step Max Tries Count** to `0` for those tenants to keep unlimited retries.

### Hide KYC Confirmation requires Custom Contract Template

**Hide KYC Confirmation** now takes effect only when the **Custom Contract Template** feature is enabled. Without it, the KYC confirmation is always shown in contracts.

### Explicit error codes on the FRA PII inquiry

Both PII inquiry endpoints — `POST /api/FRAServices/PersonallyIdentifiableInformation` and `POST /api/FRAServices/CheckIdAndFRAByTransaction` — now return **HTTP 400** with a specific `error_code` instead of a generic failure:

**OTP not verified**

* `6106` — wrong OTP code. Re-enter it and retry with the same `otpRequestId` (up to 5 tries per OTP)
* `6105` — OTP expired. Request a new OTP and retry
* `6101` — OTP request not valid (unknown, already used, or no tries left). Request a new OTP and retry

**ID image validation failed** (`PersonallyIdentifiableInformation` and `CheckIdAndFRAByTransaction`), with the failing fields in `data.validation_errors`:

* `6125` — ID front image failed validation
* `6126` — ID back image failed validation

See [PII inquiry with OTP](/fra-services/pii-inquiry-otp#errors) and [Error codes](/errors#identity--contract-errors-6xxx).

## Bug fixes

* Deleting a portal user who has signed contracts now returns a clear message instead of an HTTP 500 error. Self-deletion through the Gateway is unchanged
* The **Unlock** action now appears for business request users in the Users list, and unlocking them is allowed by the backend
* After login, users are returned to the link they originally opened — including `/account/...` links such as email verification — instead of the home page

## August 24, 2026

## API

### Commercial Register PDF processing — background processing

CR PDF processing now runs in the background since it can take a long time. Added:

* `POST /v1/ocr/process_pdf` — submit a PDF, returns immediately with a `processing` status
* `GET /v1/ocr/get_process_pdf_result/{transaction_id}` — poll for the result

A webhook notification is sent once processing completes, indicating success or failure. See [OCR](/ocr#process-pdf-background) and [Webhooks](/webhooks).

### OCR spoofing bypass

Added `OcrSpoofingBypassFeature` to bypass spoofing checks for OCR steps only. Spoofing checks remain enforced for Digital Identity (DI) steps and cannot be bypassed there.

### Resend phone OTP during password reset

`POST /api/DigitalIdentity/ForgetPassword/ValidateEmailOtp` can now be called multiple times to resend the OTP. Previously the endpoint could only be called once, forcing users to restart the password reset flow if they didn't receive the code.

### Webhook payload enhancements & session redirect URL

* Session completion data and user metadata are now attached directly to webhook notifications sent to integrated client systems when a user completes onboarding.
* The session redirect URL now returns session history data alongside it, including per-session closure status and allowed contract type activity (which contract types are signed vs. outstanding).

### Contract type activity tracking

Added `AllowedContractTypesActivity` to session history, tracking allowed contract types, signed contracts, contract status, and whether all allowed contract types have been signed.

## Admin dashboard

### User Sessions & Invitations management

* **User Sessions** — new screens to view user onboarding sessions, status updates, and session history, plus a detailed modal view for individual sessions.
* **Invitations** — new screens to view sent invitations, delivery details, and session creation status.

## July 5, 2026

## Documentation

### Expanded API reference

The OpenAPI spec now documents **84 endpoints** across Digital Identity, Business Request, Transactions, and Identity User Session — including flows that were previously guide-only or missing from the reference.

**Authentication & account**

* `POST /api/DigitalIdentity/Login`, `RefreshToken`, `Logout`
* `POST /api/DigitalIdentity/GenerateRegisterLink`, `GenerateLoginLink`
* Full `ForgetPassword/*` and `ForgetPasswordByPhone/*` flows, including V2 variants
* Account deletion: `InitiateDeletion`, `VerifyDeletionOtp`, `SubmitDeletionFaceMatch`, `GetListOfUserDeletionAudits`
* Cancel verified identity: `CancelVerifiedDigitalIdentity`, `CancelVerifiedDigitalIdentityForAdmin`
* Profile: email/phone updates, change password

**Verification data**

* `GET /api/DigitalIdentity/GetUserDigitalIdentityInfo`, `GetUserDigitalIdentityData`
* `GetUserDigitalIdentityImages` / `V2`, `GetStepImage` / `V2`
* `POST /api/DigitalIdentity/LinkUserWithExistingTransaction` — native API only; not for iframe or hosted web links

**Identity User Session**

* Session settings, theme, login, registration steps, eligibility, contract create/sign inside iframe flows

**Transactions**

* `GET /api/Transactions/GetTransactionById` — admin lookup for OCR and DI transaction records

### Registration flows documented separately

Guides now treat **standard registration** and **Consent-based Digital Identity (CDI)** as two distinct products:

| Flow                                                                   | Guide                                                                                            |
| ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| Standard — phone/email OTP → `StepCreate` → `verify/*` KYC             | [User Profile](/user-profile#standard-registration-flow) + [Digital Identity](/digital-identity) |
| CDI — `hasCDI: true` → `StepVerifyCDI` → `StepCreate` with `SkipEmail` | [Consent-based Digital Identity (CDI)](/consent-based-digital-identity)                          |

The CDI page includes comparison diagrams, VLens Network architecture visuals, and image compression guidance for selfie capture.

### Other guide updates

* [Digital Identity](/digital-identity) — delete account, cancel verification, admin identity data/images
* [User Profile](/user-profile) — logout, hosted register/login links, V2 password reset note
* [Iframe Integration](/iframe-session) — session API endpoint reference
* [OCR](/ocr) — admin transaction lookup
* [Authentication](/authentication) — expanded api-key-only endpoint list

## May 12, 2026

## New features

### OAuth login — Google and Microsoft

Users can now register and authenticate using an existing Google or Microsoft account, eliminating the need for a separate email verification OTP.

**New endpoints:**

* `POST /api/DigitalIdentity/Register/StepVerifyOAuthToken` — verifies an OAuth ID token during registration and returns an `oAuthTokenVerificationRequestId`
* `POST /api/DigitalIdentity/VerifyOAuthToken` — verifies an OAuth token to skip email verification for an already-registered user

**Updated endpoint:**

* `POST /api/DigitalIdentity/Register` — now accepts `oAuthTokenVerificationRequestId` in the request body; providing it skips the email verification step

**Supported providers:**

* Google — configure client credentials in the [Google Cloud Platform Console](https://console.cloud.google.com/)
* Microsoft — configure via [Azure AD B2C](https://docs.microsoft.com/azure/active-directory-b2c/)

OAuth provider configuration is managed in the Vlens portal settings.

**Example flow:**

```bash
# 1 — Verify the OAuth token from Google/Microsoft
POST /api/DigitalIdentity/Register/StepVerifyOAuthToken
{
  "provider": "Google",
  "IdToken": "<id_token_from_google>"
}

# 2 — Register, skipping email OTP
POST /api/DigitalIdentity/Register
{
  "phoneNumber": "+201234567890",
  "oAuthTokenVerificationRequestId": "<guid_from_step_1>"
}
```

## October 29, 2025

## Enhancements

### Bulk countersigning

Service providers can now select multiple contracts in the "Manage request traffic" view and countersign them in a single action using **Bulk Customer Sign** — reducing manual signing overhead for high-volume tenants.

### Auto-signer tool improvements

The `serviceprovider_sign_api` auto-signer now supports the `RequestType` configuration option, allowing tenants to limit auto-signing to specific contract types. Remove the option entirely to sign all eligible contract types automatically.

## Bug fixes

* Fixed an issue where the contract status could remain `CustomerSigned` after all service-provider signers had countersigned when one signer had been removed from the list
* Corrected `CreationTimeUtc` timezone handling in webhook payloads for tenants in non-UTC zones

## October 15, 2025

## Enhancements

### Location-based liveness re-validation

The contract activation flow now enforces a 80 km radius check. When a user requests an OTP from a location more than 80 km from their last active device, the system requires liveness re-validation before proceeding. This prevents account takeover from geographically distant devices.

Use `POST /api/BusinessRequest/CustomerSign/StepReValidateLiveness` to handle this case — see the [E-Contracting guide](/e-contracting) for the updated flow.

### Improved AML screening

AML (Anti-Money Laundering) results are now returned in the `services.AML` object on all identity verification responses, including `isVerificationProcessCompleted: true` responses. Previously AML results were only available on the final liveness step.

## Bug fixes

* Fixed `idExpiry` returning `null` for some national ID back scans
* Resolved an edge case where `isDigitalIdentityVerified` stayed `false` after a successful NTRA check when CSO was disabled on the tenant

## October 1, 2025

## New features

### Invitation sessions with pre-filled data

The `POST /api/IdentityUserSession/CreateInvitation` endpoint is now available. Admins can create iframe sessions with form fields pre-populated, so users only need to confirm and sign rather than fill in the full form.

Useful when the service provider has already collected customer information server-side:

```json
{
  "SessionInput": {
    "phoneNumber": "+201234567890",
    "sessionPermissions": {
      "allowedContractTypeIds": [414],
      "minimalSignatureFlow": true
    },
    "RequestFieldsValues": {
      "414": { "fullName": "Ahmed Mohamed", "monthlyIncome": "5000" }
    }
  }
}
```

### Digital Identity Only sessions

The `DigitalIdentityOnly` flag in `sessionPermissions` allows a session that performs KYC verification without proceeding to contract creation. Useful for platforms that verify identity separately from contracting.

## Enhancements

* `GetBusinessRequestTypeTemplateFields` now returns `requestsFieldsWithGroupTitles` — fields organized by section for easier UI rendering
* `GET /api/BusinessRequest/CurrentListIds` added as a lightweight alternative to `CurrentList`, returning only IDs and statuses without document HTML

## September 15, 2025

## Enhancements

### SMS provider selection

The `StepVerifyPhone` endpoint now accepts a `smsProviders` field so tenants can choose which SMS gateway to use for OTP delivery on a per-request basis:

| Value | Provider     |
| ----- | ------------ |
| `1`   | Infobip      |
| `2`   | Vodafone     |
| `3`   | Cequens      |
| `4`   | Victory Link |
| `5`   | BroadNet     |
| `6`   | Ezagel       |
| `7`   | Orange       |

Omit the field to use the tenant default.

### Extracted data flag

All three verification endpoints (`verify/id/front`, `verify/id/back`, `verify/liveness/multi`) now support `getExtractedData: boolean`. Set to `false` when you only need the verification status and don't need the full OCR output — reduces response payload size.

### LinkUserWithExistingTransaction

New endpoint `POST /api/DigitalIdentity/LinkUserWithExistingTransaction` allows associating an existing API-key-only OCR transaction to a logged-in user without repeating the capture flow. See the [Digital Identity guide](/digital-identity#alternative-link-an-existing-transaction) for details.

## Bug fixes

* Fixed `govern_english` returning Arabic characters for some governorates in `IdFrontStepApiOutput`
* Resolved a race condition where concurrent `verify/id/front` calls could generate duplicate transactions for the same user

## September 1, 2025

## New features

### Webhooks — `App.BusinessRequestStatusChange`

Tenants can now subscribe to contract lifecycle events via the Vlens portal. When a business request changes status (e.g. `PendingApproval` → `Approved`, `Approved` → `CustomerSigned`), Vlens sends an HTTP POST to your configured endpoint.

Configure subscriptions under **Webhook Subscriptions** in the portal. Each delivery is logged with the source IP, headers, and body for debugging.

See the [Webhooks guide](/webhooks) for payload format and best practices.

### Co-signer support

`POST /api/BusinessRequest/Create/{typeId}` now accepts `customerSignersIdentifiers` — a list of additional customers who must co-sign the contract. Use `minimumRequiredSignatories` to define how many must sign for the contract to be valid.

### Business request retrieval by ID

`GET /api/BusinessRequest/GetBusinessRequestById/{id}` is now available, returning full contract details for any request by UUID — not limited to the current user's active request.

## Enhancements

* Admin endpoint `GET /api/DigitalIdentity/GetUserDigitalIdentityImages` now returns `livenessFace01Image`, `livenessFace02Image`, `livenessFace03Image` alongside the existing liveness composite image
* `POST /api/BusinessRequest/Create/{typeId}` response now includes `relatedBusinessRequest` for request types with configured sub-contracts

## Documentation

* Developer guide and API reference published at [docs.vlenseg.com](https://docs.vlenseg.com)