Authentication
Authentication
Haltless uses two kinds of credentials, and which one you use depends on what you're doing:
| Credential | Use it for | How you send it |
|---|---|---|
| Bearer access token | Reading and managing data as a user or application (machines, alerts, settings, reports) | Authorization: Bearer <access-token> |
| API key | Streaming machine data in — direct ingestion and the Edge Agent | X-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.
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"
}
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:
- Create a new key with
POST /api/v1/api-keys. - Update the agent or integration to use the new key.
- 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
| Status | Meaning | What to do |
|---|---|---|
401 Unauthorized | Missing, invalid, or expired credential | For an access token, refresh and retry; for an API key, check the header and that the key still exists |
403 Forbidden | Authenticated, but not permitted for this action | Use a credential with the right access — for example, a Bearer token instead of an API key for management endpoints |
429 Too Many Requests | Rate limit exceeded | Back off and retry — see Rate limiting |
See Errors for the full error format.
Next steps
- See the API authentication reference for endpoint-level details.
- Learn key rotation and hygiene in Managing API keys.
- Put it all together in the Quickstart.