POST
Login
Login with username, email, id, or phone and receive a bearer token or an OTP-required response. OTP is required only when the account has two_auth enabled, or when the organization owner has two_auth_for_team_option enabled (same rules as dashboard Login. For passwordless OTP login (username = email or user id, no password), use LoginWithOtp instead.
Permissions
- This function can be called without a bearer token.
Action
- Runs the Login function and returns JSON.
Push Service
No push is sent because this function only reads data or returns helper information.
Automation
No automation is run for this function.
Special Instructions
- OTP gate matches dashboard: user.two_auth OR owner.two_auth_for_team_option. Personal Two auth off is not enough if Settings → Two auth for team is on.
- When otp_required is true, response may include otp_reason: user_two_auth | two_auth_for_team | force_otp (rate-limit security).
- After success=3, POST the same username/password again with otp from the email.
Required Parameters
| Name | Type | Sample | Explanation |
|---|---|---|---|
passwordpost | string | YOUR PASSWORD | Password for the login identifier. |
Optional Parameters
| Name | Type | Sample | What it gives |
|---|---|---|---|
emailpost | string | [email protected] | Email address for login. You may send username, id, or phone instead. |
usernamepost | string | eli | Username for login. Used when email is not sent. |
idpost | int | 47 | Numeric user id for login. Used when email/username are not sent. |
phonepost | string | 0500000000 | Phone value for login when supported by the account lookup. |
otppost | string | 123456 | One-time code emailed after the first password-only Login when 2FA is required. Send the same username/password again with this otp field. |
Sample Request
{
"url": "\/app\/Login",
"method": "POST",
"body": {
"username": "eli",
"password": "YOUR PASSWORD"
},
"url_user": "https:\/\/{user}.bull36.com\/app\/Login",
"url_domain": "https:\/\/{domain}\/app\/Login"
}Endpoint
POST /app/Login
POST https://{user}.bull36.com/app/Login
POST https://{domain}/app/LoginSample Output
{
"success": "1",
"message": "Login Success",
"token": "YOUR JWT TOKEN",
"token_type": "Bearer",
"expires_in": 43200,
"expires_at": "2026-07-17T13:00:00+00:00",
"redirect_to": "dashboard\/admin"
}OTP Response
{
"success": "3",
"message": "OTP send in your email...!",
"otp_required": true,
"expires_in": 600
}Protection
Login attempts are limited to 8 attempts per 60 seconds. Too many attempts will pause new attempts for 300 seconds.
JavaScript Example
async function getBearerToken({ domain = 'https://{domain}', username, password, otp = '' }) {
const body = new URLSearchParams({ username, password });
if (otp) body.set('otp', otp);
const res = await fetch(`${domain}/app/Login`, {
method: 'POST',
body
});
const data = await res.json();
if (data.otp_required) {
return { otpRequired: true, message: data.message, data };
}
if (!data.token) {
throw new Error(data.message || 'Login failed');
}
return {
token: data.token,
tokenType: data.token_type || 'Bearer',
expiresAt: data.expires_at || null,
raw: data
};
}
// 1) First call returns otp_required and emails a 6-digit code.
const first = await getBearerToken({
domain: 'https://{user}.bull36.com',
username: 'USER EMAIL',
password: 'USER PASSWORD'
});
if (first.otpRequired) {
// 2) Second call completes login with the emailed OTP.
const auth = await getBearerToken({
domain: 'https://{user}.bull36.com',
username: 'USER EMAIL',
password: 'USER PASSWORD',
otp: '123456'
});
console.log(auth.token);
}Error Example
{
"success": "0",
"message": "Login failed"
}