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

NameTypeSampleExplanation
password
post
stringYOUR PASSWORDPassword for the login identifier.

Optional Parameters

NameTypeSampleWhat it gives
email
post
string[email protected]Email address for login. You may send username, id, or phone instead.
username
post
stringeliUsername for login. Used when email is not sent.
id
post
int47Numeric user id for login. Used when email/username are not sent.
phone
post
string0500000000Phone value for login when supported by the account lookup.
otp
post
string123456One-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/Login

Sample 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"
}