Skip to main content

Authentication

Authentication

Haltless uses two kinds of credentials, and which one you use depends on what you're doing:

CredentialUse it forHow you send it
Bearer access tokenReading and managing data as a user or application (machines, alerts, settings, reports)Authorization: Bearer <access-token>
API keyStreaming machine data in — direct ingestion and the Edge AgentX-API-Key: <api-key>

Both are sent over HTTPS to https://api.haltless.io/api/v1. Never put a credential in a URL query string or commit one to source control.

Bearer access tokens

Access tokens are short-lived credentials that identify a person or application. You obtain one by logging in, send it on every request, and refresh it when it expires.

Log in to get a token

curl -X POST https://api.haltless.io/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{ "email": "you@example.com", "password": "<your-password>" }'
{
"access_token": "<your-access-token>",
"token_type": "bearer",
"mfa_required": false
}

Alongside the response, Haltless sets a refresh token in a secure, httpOnly cookie. You never read that cookie yourself — it's used only to obtain new access tokens (see Refreshing).

Send the token

Include the access token in the Authorization header on every authenticated request:

curl https://api.haltless.io/api/v1/machines \
-H "Authorization: Bearer <your-access-token>"

Refreshing a token

Access tokens are intentionally short-lived. When one expires, exchange your refresh cookie for a fresh access token instead of logging in again:

curl -X POST https://api.haltless.io/api/v1/auth/refresh \
--cookie "refresh_token=<refresh-cookie>"

Each refresh issues a new access token and rotates the refresh cookie; the previous one stops working. Build your client to refresh automatically when a request comes back 401 Unauthorized, then retry the request once.

Logging out

curl -X POST https://api.haltless.io/api/v1/auth/logout \
-H "Authorization: Bearer <your-access-token>"

Logging out invalidates your current session so the tokens can no longer be used.

Multi-factor authentication

If MFA is enabled on an account, POST /auth/login responds with "mfa_required": true and a short-lived token instead of a full access token. Complete the sign-in by verifying a code from the authenticator app:

curl -X POST https://api.haltless.io/api/v1/auth/mfa/verify \
-H "Content-Type: application/json" \
-d '{
"mfa_token": "<token-from-login>",
"code": "123456"
}'

A successful verification returns a normal access token and sets the refresh cookie, exactly like a password-only login.

note

Enterprise teams can sign in through their own identity provider (single sign-on). If SSO is set up for your organization, your login flow may redirect you there instead of asking for a password. Your account admin manages this.

API keys

API keys are built for machine-to-machine traffic — specifically, getting sensor data into Haltless from the Edge Agent or via direct ingestion. Unlike an access token, a key doesn't expire on a short clock, which makes it a good fit for long-running agents.

API keys are scoped to sending data in. They cannot manage users, settings, billing, or other account administration — those actions require a Bearer access token.

Create a key

Create keys from the dashboard under Settings → API Keys, or from the API. Creating a key requires an account admin's access token:

curl -X POST https://api.haltless.io/api/v1/api-keys \
-H "Authorization: Bearer <admin-access-token>" \
-H "Content-Type: application/json" \
-d '{ "name": "line-3-edge" }'
{
"id": "8c7b1e2a-0f3d-4a9c-9b21-1d6e5f0a7c34",
"name": "line-3-edge",
"key": "<your-new-api-key>",
"created_at": "2026-08-07T10:00:00Z"
}
warning

The full key value is shown only once, at creation. Copy it immediately and store it in a secret manager. If you lose it, create a new key and delete the old one.

Send a key

Pass the key in the X-API-Key header when sending readings:

curl -X POST https://api.haltless.io/api/v1/ingest \
-H "X-API-Key: <your-api-key>" \
-H "Content-Type: application/json" \
-d '{ "readings": [ /* ... */ ] }'

Rotate a key

Give each agent or integration its own key so you can rotate one without disrupting the others. To rotate:

  1. Create a new key with POST /api/v1/api-keys.
  2. Update the agent or integration to use the new key.
  3. Confirm data is still flowing, then delete the old key.

Use a distinct name per key so you can tell them apart later. For a full walkthrough of rotation and best practices, see Managing API keys.

Handling auth errors

StatusMeaningWhat to do
401 UnauthorizedMissing, invalid, or expired credentialFor an access token, refresh and retry; for an API key, check the header and that the key still exists
403 ForbiddenAuthenticated, but not permitted for this actionUse a credential with the right access — for example, a Bearer token instead of an API key for management endpoints
429 Too Many RequestsRate limit exceededBack off and retry — see Rate limiting

See Errors for the full error format.

Next steps