Skip to main content

Customer Login

Overview

Authenticate customers (self-service users) using email/username and password with two-factor authentication support. All device and channel context is supplied via HTTP request headers — not the request body.

Endpoint

POST /api/BPMSelfService/commands/SelfLoginCommand

Request Headers

All device identification headers are required for mobile clients and strongly recommended for web clients. They feed into security auditing, session tracking, and device-switch detection.

HeaderRequiredExampleDescription
X-App-ChannelYesMobile / WebClient channel — defaults to Web if absent
X-Device-IdYes (Mobile)a1b2c3d4-e5f6-...Unique device identifier (UUID)
X-Client-PlatformRecommendedAndroid / iOS / ChromeDevice OS or browser
X-App-VersionRecommended2.1.0App or web client version
X-Device-HostOptionalSamsung Galaxy S24Device hostname / name
X-Device-ModelOptionalSM-G991BDevice model code
X-Ip-AddressOptional41.58.12.100Client IP (forwarded by gateway)
X-App-Build-NumberOptional210App build number
X-App-Package-NameOptionalcom.bank.appApp package / bundle identifier
Device Info Storage

When at least one of X-Device-Host, X-Client-Platform, or X-Device-Model is present, the server stores a full JSON device snapshot in the session. Otherwise it falls back to the plain User-Agent string for backward compatibility.

Request Body Parameters

ParameterTypeRequiredDescription
usernamestringYesCustomer username or email
passwordstringYesCustomer password
verificationMethodTypeintegerNo2FA method: 0=Default, 1=Email, 2=SMS, 3=Authenticator (default: 0)
otpCodestringConditionalOTP code for email/SMS verification
setupVerificationCodestringConditionalTOTP code for authenticator setup verification
deviceTokenstringNoBiometric device token — required when activating biometric login for the first time on this device

Response

Successful Login (with OTP step)

{
"status": "success",
"message": "OTP sent successfully",
"data": {
"otpSent": true,
"maskedEmail": "j***@example.com",
"expiresIn": 300
}
}

Fully Authenticated

{
"status": "success",
"message": "Login successful",
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "...",
"expiresIn": 3600
}
}

Device Switch Required (Status 46)

Returned when a mobile user logs in from a device that does not match their registered device and has not yet confirmed the switch. The password was correct — this is a consent prompt, not an error.

{
"ok": true,
"message": "Executed successfully",
"outData": {
"isSuccessful": true,
"statusCode": "46",
"message": "Your credentials have been verified. This device is not your registered device. Would you like to switch to this device?",
"data": {
"requiresDeviceSwitch": true,
"verificationReason": "DEVICE_SWITCH_REQUIRED"
}
}
}

What to do: Show the user a confirmation prompt. If they agree, resend the exact same SelfLoginCommand request with switchDevice: true added to the body. This will trigger OTP verification to complete the device switch.

// Re-call with user consent
body: JSON.stringify({
username: 'customer@example.com',
password: 'SecurePassword123!',
switchDevice: true // ← add this
})

After submitting with switchDevice: true, the server sends an OTP to the user's registered email/phone. Pass the received OTP code back using the standard OTP Validation flow to complete the switch and log in.

note

statusCode: 46 with isSuccessful: true is intentional — credentials were valid, the server is awaiting explicit consent before proceeding.

Example Usage

const response = await fetch('/api/BPMSelfService/commands/SelfLoginCommand', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-App-Channel': 'Mobile',
'X-Device-Id': '550e8400-e29b-41d4-a716-446655440000',
'X-Client-Platform': 'Android',
'X-App-Version': '2.1.0',
'X-Device-Model': 'SM-G991B'
},
body: JSON.stringify({
username: 'customer@example.com',
password: 'SecurePassword123!'
})
});