Iframe Integration

Embed the full Vlens flow inside your app without exposing your API key
View as Markdown

The Identity User Session API lets you embed the complete Vlens verification and contracting UX inside your own application using an iframe or WebView — without exposing your ApiKey or admin credentials to the client.

Sessions are device-bound and user-bound. Each session is tied to a single device (via RSA public key) and expires after 30 minutes. A device is identified by its public key — store generated key pairs securely to avoid repeated mobile verification at each login.


How it works

  1. Your server calls Vlens with the user’s phone/email and session config
  2. The server passes sessionStartingPath to the client app
  3. The client loads the Vlens iframe at <tenancy_name>-onboarding.vlenseg.com/<sessionStartingPath>
  4. The user completes registration, KYC, and/or contract signing
  5. Your app receives completion events via postMessage

Create Auth Session

A session that guides the user through whatever steps are needed based on their current state. Requires only ApiKey — no admin token.

$curl -X POST "https://api.vlenseg.com/api/IdentityUserSession/CreateAuthSession" \
> -H "ApiKey: YOUR_API_KEY" \
> -H "TenancyName: YOUR_TENANT" \
> -H "Content-Type: application/json" \
> -d '{
> "UserPublicKey": "DEVICE_RSA_PUBLIC_KEY",
> "PhoneNumber": "+201234567890",
> "Email": "user@example.com",
> "Language": "AR",
> "redirectUrl": "https://your-app.com/done",
> "sessionPermissions": {
> "allowedContractTypeIds": [414],
> "minimalSignatureFlow": true,
> "DigitalIdentityOnly": false,
> "SendInvitationsForCosigners": false
> },
> "CustomerSigners": [
> {
> "customerSignerIdentifier": "+201234567891",
> "shouldSign": true,
> "signOrder": 0
> }
> ],
> "RequestFieldsValues": {
> "414": {
> "fullName": "Ahmed Mohamed",
> "monthlyIncome": "5000"
> }
> }
> }'

Request fields

FieldRequiredDescription
UserPublicKeyYesRSA public key generated on the device. The private key never leaves the device.
PhoneNumberNoUser’s phone number — pre-fills registration
EmailNoUser’s email address
LanguageNoUI language — "AR" or "EN"
redirectUrlNoWhere to send the user after session completion
sessionPermissions.allowedContractTypeIdsNoList of contract type IDs the user may create in this session
sessionPermissions.minimalSignatureFlowNotrue = streamlined signing UX; false = full application experience
sessionPermissions.DigitalIdentityOnlyNotrue = KYC only, no contracting
sessionPermissions.SendInvitationsForCosignersNotrue = co-signers receive an invitation link via SMS
CustomerSignersNoList of co-signers to add to contracts in this session
RequestFieldsValuesNoPre-filled contract form values, keyed by contract type ID then field key

Response

1{
2 "data": {
3 "sessionId": "af72ed47-7db3-40e6-acbd-e6efe01ca849",
4 "sessionEnd": "2026-05-05T13:55:14.7043492Z",
5 "sessionStartingPath": "/session/start?token=...",
6 "sessionPermissions": { "..." },
7 "redirectUrl": null,
8 "sessionAllowedTypesSignedContracts": {
9 "allTypesSigned": false,
10 "signedContracts": [
11 {
12 "id": "4325a38b-02f7-4437-a3da-6526cb33711c",
13 "typeId": 201,
14 "status": "CustomerSigned",
15 "statusId": 4
16 }
17 ]
18 }
19 },
20 "error_code": null
21}

sessionStartingPath is the path to append to your tenant’s base URL. If null, no session was created.


Create Invitation Session

A session with pre-filled data and an invitation notification (SMS or email) sent to the user. Requires admin bearer token + ApiKey.

Use this when you have already collected the customer’s information and want to minimize the steps they must complete.

$curl -X POST "https://api.vlenseg.com/api/IdentityUserSession/CreateInvitation" \
> -H "ApiKey: YOUR_API_KEY" \
> -H "TenancyName: YOUR_TENANT" \
> -H "Authorization: Bearer ADMIN_TOKEN" \
> -H "Content-Type: application/json" \
> -d '{
> "sessionInput": {
> "UserPublicKey": "DEVICE_RSA_PUBLIC_KEY",
> "PhoneNumber": "+201234567890",
> "Language": "AR",
> "sessionPermissions": {
> "allowedContractTypeIds": [414],
> "minimalSignatureFlow": true,
> "DigitalIdentityOnly": false
> },
> "RequestFieldsValues": {
> "414": {
> "fullName": "Ahmed Mohamed",
> "monthlyIncome": "5000"
> }
> }
> },
> "smsProvider": 0
> }'

smsProvider controls which SMS gateway sends the invitation. 0 = default from tenant settings.

Invitation links are short-lived (10 minutes) but the session itself lasts 30 minutes from when the user opens it. The link acts as a one-time OTP:

  • Sent via SMS → no mobile verification required at login or registration
  • Sent via email → no email verification required at registration

Loading the iframe

Concatenate sessionStartingPath to your tenant’s base URL:

https://<tenancy_name>-onboarding.vlenseg.com<sessionStartingPath>
1<iframe
2 src="https://YOUR_TENANT-onboarding.vlenseg.com/session/start?token=..."
3 width="100%"
4 height="700"
5 allow="camera; microphone"
6/>

The allow="camera; microphone" attribute is required for liveness detection to work in the browser.


postMessage integration

The iframe communicates with the parent app via window.postMessage. This is required for device-bound signing — the parent app holds the private key.

Iframe → Parent (signing request):

1window.postMessage({
2 type: "NATIVE_CALL",
3 method: "signContent",
4 requestId: "123",
5 args: { signingBody: "..." }
6}, "*");

Parent → Iframe (signing response):

1window.postMessage({
2 type: "NATIVE_RESPONSE",
3 requestId: "123",
4 success: true,
5 result: "signed-value",
6 source: "native"
7}, "*");

Key storage

The private key must never leave the device. Store it using each platform’s secure enclave:

PlatformStorage
AndroidAndroid Keystore
iOSKeychain with Secure Enclave
Webwindow.crypto (non-exportable)

Security features

Every session request includes three layers of protection:

FeatureDescription
NonceEach request is processed only once — replay attacks are rejected
TimestampRequests are only processed in real-time — intercepted requests expire immediately
Body signatureAll request data is signed with the device private key, preventing MITM tampering

Session permissions reference

PermissionTypeDescription
allowedContractTypeIdsint[]Contract type IDs the user may create in this session
minimalSignatureFlowbooleantrue = streamlined UX; false = full application
DigitalIdentityOnlybooleanRestrict session to KYC only — no contracting
SendInvitationsForCosignersbooleanSend invitation links to co-signers via SMS instead of regular notification

Web app (no-code access)

Users can access the Vlens web app directly at:

https://<tenancy_name>-onboarding.vlenseg.com

No developer configuration is required. The web app manages keys and sessions securely — each browser is treated as a separate device with its own key pair.

To restrict access to invited users only, enable Invitation Only in the portal under Feature Control → Main Feature.


When to use each flow

ScenarioRecommended flow
Mobile app with native ID captureNative API flow
Embed Vlens in a web page with minimal integrationAuth Session (iframe)
Pre-fill customer data server-sideInvitation Session
Redirect user to Vlens-hosted register/login pageUser Profile — Hosted links
KYC only — no contractingAuth Session with DigitalIdentityOnly: true
Restrict to invited usersEnable Invitation Only in portal

Session API endpoints

Your server creates the session with CreateAuthSession or CreateInvitation. The embedded iframe then calls the endpoints below (you do not call these directly from your backend in most integrations).

EndpointPurpose
GET /api/IdentityUserSession/GetUserSessionSettingsSession config (redirect URL, starting path)
GET /api/IdentityUserSession/GetSessionThemeSettingsBranding colors and logo
POST /api/IdentityUserSession/LoginLogin inside the session
POST /api/IdentityUserSession/RegisterStepVerifyPhoneRegistration phone OTP
POST /api/IdentityUserSession/RegisterStepVerifyEmailRegistration email OTP
POST /api/IdentityUserSession/RegisterStepCreateComplete registration
POST /api/IdentityUserSession/CheckExistenceOfEmailOrPhoneCheck if email/phone exists
GET /api/IdentityUserSession/CheckEligibilityCan user create a contract?
GET /api/IdentityUserSession/GetAllRequestTypesList contract types
POST /api/IdentityUserSession/Create/{typeId}Create a business request
GET /api/IdentityUserSession/HasMoreToSignPending signatures remaining
POST /api/IdentityUserSession/CustomerSign/StepValidateOtpSign — validate OTP
POST /api/IdentityUserSession/CustomerSign/StepValidatePaymentSign — validate payment

For the native API equivalents (outside the iframe), see Digital Identity and E-Contracting. To associate a pre-login OCR transaction with a user after native login, see Link an existing transaction — that flow does not apply inside an iframe session.