API login best practices

Sign in to your BILL sandbox developer account with the /Login.json API endpoint.

The required fields for signing in are userName, password, orgId, and devKey. Retrieve these values as part of your sandbox sign up process. See Sign up process for more information.

Set the required values in the cURL command example and run the command in your choice of command line system.

curl --request POST 'https://api-sandbox.bill.com/api/v2/Login.json' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'userName={username}' \
--data 'password={password}' \
--data 'orgId={organization_ID}' \
--data 'devKey={developer_key}'

In response, your API session is created and a sessionId is generated. Use the sessionId in all subsequent API calls to confirm that you are in a signed in session. See the Login API for more information.

❗️

WARNING

Personal Identifiable Information (PII) is NOT safe as query string parameters.
BILL PII includes (but is not limited to) userName, password, devKey, and sessionId.

URLs are commonly stored in browser histories and server logs. In an API request, sending sensitive information with query string parameters is not safe.

If an attacker has access to a URL that includes query string parameters, they may have access to the PII.

API login session validity

If your API session is inactive or idle for 35 minutes, the session expires and you are automatically signed out.

After signing in, making any subsequent call resets the 35 minutes timer. You are required to sign in again and generate a new sessionId only if the session is inactive or idle for 35 minutes.

Login timer example

In this example, a timer is set for 34 minutes (one minute before the login timer expires). At every subsequent API call, the timer is canceled and a new timer is started. When the timer expires, you login again and retrieve a new sessionId.

from threading import Timer

# Login API call (new sessionId generated)

# Set a timer for 34 minutes
# (One minute before the timer expires)
def newTimer():
   global t
   t = Timer(2040, {Login API call})

# Start timer
newTimer()
t.start()

# Reset timer to zero at every subsequent API call
t.cancel()
newTimer()
t.start()