Skip to content

Login & Logout


Login

POST /api/authenticate

Public endpoint. No authentication required.

Request Body

{
  "username": "jane.doe@acme.com",
  "password": "your-password"
}
Field Type Required Description
username string Yes Account username or email address
password string Yes Account password

Response - Success (no 2FA)

HTTP/1.1 200 OK
Set-Cookie: access_token_cookie=<jwt>; HttpOnly; SameSite=Lax; Path=/
Set-Cookie: refresh_token_cookie=<jwt>; HttpOnly; SameSite=Lax; Path=/api/token-refresh
Set-Cookie: csrf_access_token=<token>; SameSite=Lax; Path=/
Set-Cookie: csrf_refresh_token=<token>; SameSite=Lax; Path=/api/token-refresh
{
  "login": true
}

Response - 2FA Required

When 2FA is enabled on the account, the login step returns a challenge instead of a full session:

{
  "requires_2fa": true
}

Submit the TOTP code to /api/verify-2fa to complete login.

Response - First Sign-In

When the account has never been used:

{
  "first_signin": true,
  "session_token": "<short-lived-token>"
}

Use session_token to set a new password via /api/first-signin.

Error - Invalid Credentials

HTTP/1.1 401 Unauthorized

{
  "Message": "Invalid username or password.",
  "Code": "User.InvalidCredentials"
}

Rate Limiting

After 3 consecutive failed login attempts, the account is temporarily locked with exponential backoff. Subsequent failures increase the lockout duration.


Logout

POST /api/logout

Authentication required. CSRF header required: X-XSRF-TOKEN

Invalidates the current session by clearing authentication cookies server-side.

Example Request

POST /api/logout HTTP/1.1
Host: acme.knosc.com
Cookie: access_token_cookie=<jwt>
X-XSRF-TOKEN: <csrf-token>

Response

HTTP/1.1 200 OK
Set-Cookie: access_token_cookie=; Expires=Thu, 01 Jan 1970 00:00:00 GMT
Set-Cookie: refresh_token_cookie=; Expires=Thu, 01 Jan 1970 00:00:00 GMT

Code Examples

curl - Login

curl -c cookies.txt -X POST https://acme.knosc.com/api/authenticate \
  -H "Content-Type: application/json" \
  -d '{"username": "jane.doe@acme.com", "password": "your-password"}'

curl - Logout

CSRF=$(grep csrf_access_token cookies.txt | awk '{print $NF}')
curl -b cookies.txt -X POST https://acme.knosc.com/api/logout \
  -H "X-XSRF-TOKEN: $CSRF"

Python

import requests

BASE = "https://acme.knosc.com"
session = requests.Session()

# Login
r = session.post(f"{BASE}/api/authenticate", json={
    "username": "jane.doe@acme.com",
    "password": "your-password"
})
assert r.json().get("login"), "Login failed"

# ... use the session ...

# Logout
csrf = session.cookies.get("csrf_access_token")
session.post(f"{BASE}/api/logout", headers={"X-XSRF-TOKEN": csrf})