Skip to content

Authentication

The public API authenticates with a single bearer key — there’s no OAuth flow, no client ID/secret pair, and no session cookies.

API keys are created and managed from the API Keys page inside the Logistall web app (Admin section of the sidebar). See the User Guide’s FAQ → Where do I find or create API keys? for the walkthrough, including the permission and feature-module requirements to see that page at all.

When you create a key, the full secret value — starting with lk_ — is shown to you once, in a copyable field. After you close that dialog, Logistall never shows the full value again; the Keys table afterward only shows a short prefix (the first 10 characters) so you can identify which key is which. If you lose the secret, you can’t recover it — revoke the key and create a new one.

Under the hood, only a SHA-256 hash of the key is stored (api_key.key_hash); the raw secret isn’t persisted anywhere in the database.

Send the key on every request using either of these headers:

Terminal window
# Option 1: Authorization: Bearer
curl -H "Authorization: Bearer lk_YOUR_KEY" \
https://tenant.logistall.cloud/api/v1/shipments?limit=10
# Option 2: X-API-Key
curl -H "X-API-Key: lk_YOUR_KEY" \
https://tenant.logistall.cloud/api/v1/shipments?limit=10

If both headers are present, Authorization: Bearer takes precedence. A key that doesn’t start with lk_ — or no key at all — is rejected immediately with:

{ "error": "Missing or invalid API key" }

HTTP status 401.

An unrecognized or revoked key (one that doesn’t hash-match any active key) returns:

{ "error": "Invalid API key" }

Also HTTP status 401.

Keys are scoped to the tenant company they were created under. Authenticating a request resolves which tenant it belongs to by hash-matching against active keys, so a key from one company can never read another company’s data — there’s no way to pass a tenant ID yourself, and there’s nothing to configure.

Revoking a key from the API Keys page sets it inactive immediately; it’s a soft revoke (the row is kept for history), and revoked keys can’t be reactivated — create a new one if you need to restore access.

Every successful authentication updates that key’s last_used_at timestamp, visible in the Keys table, so you can spot keys that are stale or no longer in use.

The key-creation form has an optional free-text scopes field (e.g. read:shipments write:routes). At present this value is stored on the key but is not enforced anywhere by the API — every valid key can read every /v1/* endpoint. Treat scopes as a label for your own bookkeeping today, not an access-control mechanism.