Skip to navigation

User Profile

Login, token refresh, and account management — email, phone, and password

View as Markdown

This page covers all user-facing account management flows: login (with OTP), token refresh, email and phone updates, password change, and password reset.


Registration paths

Vlens has two separate registration flows. Choose one per user based on CheckExistenceOfEmailOrPhone:

FlowWhen to useUser-facing stepsDocumented in
StandardhasCDI is false or absent — new user8 — phone OTP (send + enter), email OTP (send + enter), account, ID front, ID back, livenessThis page → Standard registration flow
CDIhasCDI: true — network identity eligible for consent-based reuse2 — phone OTP (consent), livenessConsent-based Digital Identity (CDI)

Do not combine steps from both flows (for example, do not call verify/id/front after a CDI StepCreate).


Standard registration flow

Phone OTP → optional email OTP → StepCreate → then ID scan and liveness on the Digital Identity page. Login only repeats the phone OTP step afterward.

This diagram is the standard path only. If CheckExistenceOfEmailOrPhone returns hasCDI: true, stop here and follow Consent-based Digital Identity (CDI) instead — no verify/* steps afterward.

After standard registration, login does not repeat the ID or liveness steps. The user only enters phone + password and validates the SMS OTP.


Login

Login calls the same endpoint twice — first to trigger the OTP SMS, then to validate it and receive tokens.

Step 1 — Submit credentials (triggers SMS OTP)

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/Login" \
-H "ApiKey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"geoLocation": { "latitude": 30.0444, "longitude": 31.2357 },
"imei": "DEVICE_ID",
"phoneNumber": "+201234567890",
"password": "USER_PASSWORD",
"smsProviders": 0
}'

Save data.phoneNumberOtpRequestId from the response.

Step 2 — Validate OTP and receive tokens

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/Login" \
-H "ApiKey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"geoLocation": { "latitude": 30.0444, "longitude": 31.2357 },
"imei": "DEVICE_ID",
"phoneNumber": "+201234567890",
"password": "USER_PASSWORD",
"smsProviders": 0,
"phoneNumberOtpRequestId": "OTP_REQUEST_ID",
"phoneNumberOtp": "123456"
}'

Response:

{
"data": {
"accessToken": "eyJ...",
"refreshToken": "eyJ...",
"expireInSeconds": 86400,
"isDigitalIdentityVerified": true,
"hasPendingRequest": false,
"user": {
"fullName": "Ahmed Mohamed",
"phoneNumber": "+201234567890",
"idNumber": "29901234567890"
}
},
"error_code": null
}

smsProviders values: 0 = default, 1 = Infobip, 2 = Vodafone, 3 = Cequens, 4 = Victory Link, 5 = BroadNet, 6 = Ezagel, 7 = Orange.


When you do not want to build a registration or login UI, generate a signed Vlens web URL server-side and redirect the user to it. This is a browser redirect flow — not the same as Iframe Integration and not related to linking a pre-login transaction.

EndpointPurpose
POST /api/DigitalIdentity/GenerateRegisterLinkHosted registration flow
POST /api/DigitalIdentity/GenerateLoginLinkHosted login flow

Both accept optional phoneNumber, email, latitude, longitude, imei, and returnUrl. The response data field is the URL to open in a browser.

curl -X POST https://api.vlenseg.com/api/DigitalIdentity/GenerateRegisterLink \
-H "ApiKey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+201234567890",
"returnUrl": "https://yourapp.com/registration-complete"
}'

Refresh token

User token Admin token Tokenexpired? POST /DigitalIdentity/RefreshToken{ refreshToken } POST /credentials/RefreshToken{ refreshToken } New accessToken+ refreshToken
curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/RefreshToken" \
-H "ApiKey: YOUR_API_KEY" \
-H "Authorization: Bearer CURRENT_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"refreshToken": "YOUR_REFRESH_TOKEN"}'

Both return data.accessToken and data.refreshToken.


Log out

Invalidate the current user session. Requires ApiKey and a user bearer token.

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/Logout" \
-H "ApiKey: YOUR_API_KEY" \
-H "Authorization: Bearer USER_TOKEN"

Update email

emailOtpRequestId UpdateEmailRequest{ email: new@example.com } ValidateUpdateEmailRequestOtp{ emailOtpRequestId, emailOtp } ✅ Email updated

Step 1 — Request email OTP

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/UpdateEmailRequest" \
-H "ApiKey: YOUR_API_KEY" \
-H "Authorization: Bearer USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"email": "new@example.com"}'

Save data.emailOtpRequestId from the response.

Step 2 — Validate OTP

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/ValidateUpdateEmailRequestOtp" \
-H "ApiKey: YOUR_API_KEY" \
-H "Authorization: Bearer USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"emailOtpRequestId": "OTP_REQUEST_ID",
"emailOtp": "123456"
}'

Verify email (post-registration)

If email verification was skipped during registration (skipEmail: true), the user can verify later.

emailOtpRequestId VerifyEmail{ email } VerifyEmail{ email, emailOtpRequestId, emailOtp } ✅ Email verified

Step 1 — Request email OTP

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/VerifyEmail" \
-H "ApiKey: YOUR_API_KEY" \
-H "Authorization: Bearer USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'

Save data.emailOtpRequestId.

Step 2 — Validate OTP

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/VerifyEmail" \
-H "ApiKey: YOUR_API_KEY" \
-H "Authorization: Bearer USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"emailOtpRequestId": "OTP_REQUEST_ID",
"emailOtp": "123456"
}'

Update phone number

Changing a phone number requires liveness re-validation before the OTP is sent.

To let a user change their number through an invitation link or an embedded session instead, see Change Phone Number Session.

No Yes No Yes SendPhoneOtp{ newPhone, password } Livenessrequired? phoneNumberOtpRequestId returned ReValidateLiveness{ phone, password, image: face } New phoneNumberOtpRequestId ValidatePhoneOtp{ phoneNumberOtpRequestId, OTP } deferCommit? ✅ Phone number updated isCommitPending: true Admin: CommitPhoneChange{ phoneNumberOtpRequestId }

Step 1 — Send OTP to new number

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/UpdatePhone/SendPhoneOtp" \
-H "ApiKey: YOUR_API_KEY" \
-H "Authorization: Bearer USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+201234567891",
"password": "USER_PASSWORD",
"smsProviders": 0
}'

Save data.phoneNumberOtpRequestId.

Step 2 — Re-validate liveness (if required)

If the response indicates liveness re-validation is needed:

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/UpdatePhone/ReValidateLiveness" \
-H "ApiKey: YOUR_API_KEY" \
-H "Authorization: Bearer USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+201234567891",
"password": "USER_PASSWORD",
"image": "BASE64_FACE_IMAGE"
}'

Save the new data.phoneNumberOtpRequestId from this response.

Step 3 — Validate OTP

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/UpdatePhone/ValidatePhoneOtp" \
-H "ApiKey: YOUR_API_KEY" \
-H "Authorization: Bearer USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"phoneNumberOtpRequestId": "OTP_REQUEST_ID",
"phoneNumberOtp": "123456"
}'

By default the phone number is updated as soon as the OTP validates. To defer the actual change — for example, so an admin can review it first — send "deferCommit": true in this request. The response then returns data.isCommitPending: true instead of updating the number immediately, and you need step 4 below.

Step 4 — Commit the change (admin, only if deferred)

Only needed when step 3 was called with deferCommit: true. Requires an authorized admin access token.

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/UpdatePhone/CommitPhoneChange" \
-H "ApiKey: YOUR_API_KEY" \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"phoneNumberOtpRequestId": "OTP_REQUEST_ID"
}'

Use the same phoneNumberOtpRequestId from step 3. VLens re-validates the OTP request and the user’s Digital Identity before applying the new phone number.


Change password

Changing the current password sends an OTP to the registered email to confirm the change.

emailOtpRequestId ChangePasswordRequest{ currentPassword, newPassword } ValidateChangePasswordRequest{ passwords, emailOtpRequestId, emailOtp } ✅ Password changed

Step 1 — Request password change

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/ChangePasswordRequest" \
-H "ApiKey: YOUR_API_KEY" \
-H "Authorization: Bearer USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"currentPassword": "CURRENT_PASSWORD",
"newPassword": "NEW_PASSWORD"
}'

Save data.emailOtpRequestId.

Step 2 — Validate OTP and confirm change

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/ValidateChangePasswordRequest" \
-H "ApiKey: YOUR_API_KEY" \
-H "Authorization: Bearer USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"currentPassword": "CURRENT_PASSWORD",
"newPassword": "NEW_PASSWORD",
"emailOtpRequestId": "OTP_REQUEST_ID",
"emailOtp": "123456"
}'

Reset password

Yes No Forgot password Haveemail access? Via email + phone4 steps Via phone only3 steps ForgetPassword/SendEmailOtp ForgetPassword/ValidateEmailOtp→ triggers phone OTP ForgetPassword/ValidatePhoneOtp→ returns userId + resetCode ForgetPassword/Reset{ userId, resetCode, newPassword } ✅ Password reset ForgetPasswordByPhone/SendPhoneOtp ForgetPasswordByPhone/ValidatePhoneOtp→ returns userId + resetCode ForgetPasswordByPhone/Reset{ userId, resetCode, newPassword }

V2 variants (SendEmailOtpV2, ValidateEmailOtpV2, ValidatePhoneOtpV2, ResetV2) follow the same steps with updated validation rules.

Via email + phone (4 steps)

Step 1 — Send OTP to email

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/ForgetPassword/SendEmailOtp" \
-H "ApiKey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"emailOrPhoneNumber": "+201234567890",
"idNumber": ""
}'

Save data.emailOtpRequestId.

Step 2 — Validate email OTP (triggers phone OTP)

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/ForgetPassword/ValidateEmailOtp" \
-H "ApiKey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"emailOrPhoneNumber": "+201234567890",
"idNumber": "",
"emailOtpRequestId": "EMAIL_OTP_REQUEST_ID",
"emailOtp": "123456",
"smsProviders": 0
}'

Save data.phoneNumberOtpRequestId.

Step 3 — Validate phone OTP

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/ForgetPassword/ValidatePhoneOtp" \
-H "ApiKey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"emailOrPhoneNumber": "+201234567890",
"idNumber": "",
"phoneNumberOtpRequestId": "PHONE_OTP_REQUEST_ID",
"phoneNumberOtp": "123456"
}'

Save data.userId and data.passwordResetCode.

Step 4 — Set new password

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/ForgetPassword/Reset" \
-H "ApiKey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"userId": 12345,
"resetCode": "RESET_CODE",
"password": "NEW_PASSWORD"
}'

Via phone only (3 steps)

Step 1 — Send OTP to phone

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/ForgetPasswordByPhone/SendPhoneOtp" \
-H "ApiKey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"phoneNumber": "+201234567890"}'

Save data.phoneNumberOtpRequestId.

Step 2 — Validate phone OTP

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/ForgetPasswordByPhone/ValidatePhoneOtp" \
-H "ApiKey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+201234567890",
"phoneNumberOtpRequestId": "OTP_REQUEST_ID",
"phoneNumberOtp": "123456"
}'

Save data.userId and data.passwordResetCode.

Step 3 — Set new password

curl -X POST "https://api.vlenseg.com/api/DigitalIdentity/ForgetPasswordByPhone/Reset" \
-H "ApiKey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"userId": 12345,
"resetCode": "RESET_CODE",
"password": "NEW_PASSWORD"
}'