Authentication
The OpenBoxes API uses session-based authentication with JSESSIONID cookies. You authenticate once via the login endpoint, receive a session cookie, and include that cookie in all subsequent requests.
Login
Authenticate by sending a POST request to the login endpoint with your credentials and a location ID:
curl -X POST \
https://acme.openboxes.cloud/openboxes/api/login \
-H "Content-Type: application/json" \
-c cookies.txt \
-d '{
"username": "admin@acme.com",
"password": "your-password",
"location": "ff808181648b61df01648b6f43210001"
}'
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
username |
string | Yes | Your OpenBoxes username or email |
password |
string | Yes | Your account password |
location |
string | Yes | ID of the warehouse/location to log into |
Successful Response
{
"status": 200,
"data": {
"user": {
"id": "ff808181648b61df01648b6f43210002",
"username": "admin@acme.com",
"firstName": "Admin",
"lastName": "User"
},
"location": {
"id": "ff808181648b61df01648b6f43210001",
"name": "Main Warehouse"
}
}
}
The response sets a JSESSIONID cookie. When using curl, the -c cookies.txt flag saves it to a file for reuse.
Failed Response
{
"errorCode": 401,
"errorMessage": "Invalid username or password"
}
Using the Session Cookie
Include the session cookie in all subsequent API requests using the -b flag:
# List products using the saved session cookie
curl -b cookies.txt \
https://acme.openboxes.cloud/openboxes/api/products
# Create a new product
curl -X POST \
-b cookies.txt \
-H "Content-Type: application/json" \
https://acme.openboxes.cloud/openboxes/api/products \
-d '{"name": "Amoxicillin 250mg", "category": {"id": "cat-123"}}'
Session Timeout
Sessions expire after a period of inactivity (default: 30 minutes). When a session expires, the API may respond in one of two ways:
- HTTP 302 redirect to the login page (most common)
- HTTP 401 Unauthorized with an error message
Always handle both cases in your integration code:
# Check the HTTP status code
response=$(curl -s -o /dev/null -w "%{http_code}" \
-b cookies.txt \
https://acme.openboxes.cloud/openboxes/api/products)
if [ "$response" = "302" ] || [ "$response" = "401" ]; then
echo "Session expired, re-authenticating..."
# Re-authenticate and retry
fi
Logout
End a session explicitly by calling the logout endpoint:
curl -X POST \
-b cookies.txt \
https://acme.openboxes.cloud/openboxes/api/logout
After logout, the JSESSIONID cookie is invalidated and cannot be reused.
Best Practices
Re-use Sessions
Do not call the login endpoint before every request. Authenticate once, store the cookie, and re-authenticate only when the session expires.
# Bad: authenticating on every request
curl -X POST .../api/login -d '...' -c cookies.txt
curl -b cookies.txt .../api/products
# Good: authenticate once, reuse the session
# (re-authenticate only on 302/401)
curl -b cookies.txt .../api/products
Secure Credential Storage
Never hardcode credentials in source code. Use environment variables or a secrets manager:
export OB_USERNAME="admin@acme.com"
export OB_PASSWORD="$(vault read -field=password secret/openboxes)"
curl -X POST \
https://acme.openboxes.cloud/openboxes/api/login \
-H "Content-Type: application/json" \
-c cookies.txt \
-d "{\"username\": \"$OB_USERNAME\", \"password\": \"$OB_PASSWORD\", \"location\": \"$OB_LOCATION\"}"
Handle Redirects
By default, curl follows redirects automatically. To detect session expiry, disable redirect following with -L omitted or use --max-redirs 0:
curl -s --max-redirs 0 \
-b cookies.txt \
-o /dev/null -w "%{http_code}" \
https://acme.openboxes.cloud/openboxes/api/products
# Returns 302 if session expired, 200 if valid
Limitations
- No API keys or tokens: Authentication is session-based only. OAuth2 and API key support are planned Lift platform features.
- Email
+aliases: Usernames containing+characters (e.g.,user+tag@example.com) may fail during form-based login due to URL encoding. Use the JSON API login endpoint shown above to avoid this issue. - Single location per session: Each session is bound to one location. To work with a different location, log in again with the new location ID.