Authentication

Authenticate Scan API requests with X-API-KEY or a dashboard session.

Threatless has two auth modes. Do not mix them on the same request.

API keys (public Scan API)

Create a key in the dashboard, then send it on every /api/** request:

X-API-KEY: YOUR_API_KEY
X-API-KEY
string required
32-character hex key from API Key.

The filter runs before the controller:

SituationStatusBody
Header missing or blank401{ "error": "X-API-KEY MISSING" }
Key does not match a user401{ "error": "X-API-KEY INVALID" }

CORS allows X-API-KEY and Authorization from configured web origins.

Minimal authenticated request

cURL
curl -i -X POST https://api.trythreatless.com/api/v1/scans \
  -H "X-API-KEY: YOUR_API_KEY" \
  -F "file=@./suspect.bin"
JavaScript
const body = new FormData()
body.append('file', fileBlob)

const response = await fetch('https://api.trythreatless.com/api/v1/scans', {
  method: 'POST',
  headers: {
    'X-API-KEY': process.env.THREATLESS_API_KEY,
  },
  body,
})

A 401 body is always JSON with an error string. Do not retry auth failures without rotating the key.

401
{
  "error": "X-API-KEY INVALID"
}

Session JWT (dashboard)

Browser routes under /web/** (except /web/auth/** and Stripe webhooks) expect a Bearer access token issued at login. The Nuxt app stores it in the token cookie and refreshes via POST /web/auth/refresh.

Authorization: Bearer <access-jwt>

Access tokens last 15 minutes. Refresh tokens last 15 days and are httpOnly cookies set by the API.

Auth endpoints

MethodPathNotes
POST/web/auth/registerEmail sign-up
POST/web/auth/loginEmail + password
POST/web/auth/refreshRotate access JWT
POST/web/auth/logoutClear refresh cookie
POST/web/auth/email-confirmationConfirm address
POST/web/auth/reset-password/requestSend reset email
POST/web/auth/reset-passwordSet new password
GET/web/auth/google/startGoogle OAuth
GET/web/auth/google/callbackGoogle OAuth return
Never send X-API-KEY to /web/** and never send a user JWT to /api/v1/scans. Each surface has one auth story.

Where to go next

Previous

Scan a file

POST a multipart file to /api/v1/scans and read the JSON verdict.

Next