Authentication
How to authenticate your API requests.
Overview
The LogisticsWMS External API supports two authentication methods. Both produce a Bearer token that you include in the Authorization header of every API
request.
Option A: API Client Credentials (Recommended)
Self-managed credentials created directly in the WMS application. Best for most integrations — no external identity provider needed.
Option B: OAuth2 via Auth0
Managed by the LogisticsWMS team. Used for legacy integrations and integrations requiring Auth0-specific features.
Option A: API Client Credentials
Create and manage your own API credentials directly in the WMS application, under Plugins → REST API → API Clients. This is the recommended method for new integrations.
Step 1: Create an API Client
In the WMS application, navigate to Plugins → REST API → API Clients and click Create. The system will generate a client_id and
client_secret.
client_secret is shown only once when the API client is created. Store it securely — if lost, you must regenerate it.
Step 2: Exchange Credentials for a Token
Send a POST request to the token endpoint with your credentials as form data.
curl -X POST https://app.logistics-wms.com/api/external/v1/auth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET"
Step 3: Receive the Token
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600
}
| Field | Description |
|---|---|
access_token |
The JWT token to use in API requests |
token_type |
Always Bearer |
expires_in |
Token validity in seconds (3600 = 1 hour) |
Step 4: Use the Token
Include the token in the Authorization header of every API request.
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Token Management
API Client tokens are valid for 1 hour (3600 seconds). To avoid unnecessary token requests:
- Cache the token. Store the access token and reuse it until it expires.
- Track expiration. Use the
expires_infield to schedule token refresh before expiry. Refresh 5 minutes before the token expires. - Handle 401 responses. If you receive a
401 Unauthorized, your token may have expired. Request a new token and retry.
Managing Your API Clients
| Action | Description |
|---|---|
| Enable / Disable | Temporarily suspend access without deleting the client |
| Regenerate Secret | Invalidate the current secret and generate a new one (the old secret stops working immediately) |
| Delete | Permanently remove the API client and revoke all access |
Option B: OAuth2 via Auth0
For legacy integrations, the LogisticsWMS team can provision OAuth2 credentials via Auth0. Contact help@logistics-wms.com to request OAuth2 API access.
When registered, you will receive:
- A client_id
- A client_secret
- The audience URL for the API
- Your assigned tenant (the warehouse context your credentials are scoped to)
Request an Access Token
curl -X POST https://logistics-wms.eu.auth0.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"audience": "YOUR_AUDIENCE",
"grant_type": "client_credentials"
}'
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 86400
}
OAuth2 tokens are valid for 24 hours (86400 seconds). Use the token the same way — in the Authorization: Bearer header.
Example Requests
curl (API Client)
# 1. Get an access token
TOKEN=$(curl -s -X POST https://app.logistics-wms.com/api/external/v1/auth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET" \
| jq -r '.access_token')
# 2. Use the token to call the API
curl -X GET https://app.logistics-wms.com/api/external/v1/product \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json"
Python (requests)
import requests
# 1. Get an access token
token_response = requests.post(
"https://app.logistics-wms.com/api/external/v1/auth/token",
data={
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET"
}
)
access_token = token_response.json()["access_token"]
# 2. Use the token to call the API
response = requests.get(
"https://app.logistics-wms.com/api/external/v1/product",
headers={
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
)
print(response.json())
Java (HttpClient)
import java.net.http.*;
import java.net.URI;
import com.fasterxml.jackson.databind.ObjectMapper;
ObjectMapper mapper = new ObjectMapper();
HttpClient client = HttpClient.newHttpClient();
// 1. Get an access token
HttpRequest tokenRequest = HttpRequest.newBuilder()
.uri(URI.create("https://app.logistics-wms.com/api/external/v1/auth/token"))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString(
"client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET"))
.build();
HttpResponse<String> tokenResponse = client.send(
tokenRequest, HttpResponse.BodyHandlers.ofString());
String accessToken = mapper.readTree(tokenResponse.body())
.get("access_token").asText();
// 2. Use the token to call the API
HttpRequest apiRequest = HttpRequest.newBuilder()
.uri(URI.create("https://app.logistics-wms.com/api/external/v1/product"))
.header("Authorization", "Bearer " + accessToken)
.header("Content-Type", "application/json")
.GET()
.build();
HttpResponse<String> response = client.send(
apiRequest, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
JavaScript (Node.js / fetch)
// 1. Get an access token
const tokenResponse = await fetch(
"https://app.logistics-wms.com/api/external/v1/auth/token",
{
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: "client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET"
}
);
const { access_token } = await tokenResponse.json();
// 2. Use the token to call the API
const response = await fetch(
"https://app.logistics-wms.com/api/external/v1/product",
{
headers: {
"Authorization": `Bearer ${access_token}`,
"Content-Type": "application/json"
}
}
);
console.log(await response.json());
Multi-Tenant Context
Your API credentials are scoped to a specific tenant (warehouse). The tenant context is automatically determined from your token — whether it's an API Client token or an OAuth2 token. You do not need to include a tenant identifier in your requests.
All data you create and query is isolated to your tenant. You cannot access data from other tenants.
Authentication Errors
| HTTP Status | Cause | What to Do |
|---|---|---|
401 Unauthorized |
Missing, expired, or invalid token | Request a new access token and retry. Verify your client credentials are correct. |
403 Forbidden |
Valid token but insufficient permissions | Contact help@logistics-wms.com to verify your account permissions and scopes. |
503 Service Unavailable |
API token service is not configured (API Client auth only) | The server-side JWT signing key is not set. Contact the LogisticsWMS team. |
Security Best Practices
- Always use HTTPS. Never send tokens over unencrypted connections.
- Store credentials securely. Use environment variables or a secrets manager. Never hardcode
client_idorclient_secretin source code. - Do not share credentials. Each integration should use its own set of credentials for audit and revocation purposes.
- Do not expose tokens in URLs. Always send tokens in the
Authorizationheader, never as query parameters. - Rotate credentials periodically. Use the Regenerate Secret action in the WMS to issue new credentials if you suspect a compromise.
- Minimize token lifetime. API Client tokens expire after 1 hour by design. Cache them in memory but do not persist to disk unless encrypted.