Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/soker90/finper/llms.txt

Use this file to discover all available pages before exploring further.

Finper uses JSON Web Tokens (JWT) for authentication. Obtain a token by logging in or registering, then pass it as the token header on every subsequent request. The token is signed with the JWT_SECRET environment variable and expires after 1 hour. The server automatically issues a refreshed token on every authenticated response via the Token response header.

POST /api/auth/login

Authenticate an existing user and receive a JWT. POST /api/auth/login — no token header required.

Request Body

username
string
required
The account username. Case-insensitive — normalized to lowercase internally.
password
string
required
The account password.

Response — 200 OK

token
string
Signed JWT valid for 1 hour. Pass this value in the token header on all subsequent requests.
user
string
The authenticated username string.

Example

curl -X POST http://localhost:3008/api/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username": "alice", "password": "s3cur3pass"}'
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": "alice"
}

POST /api/auth/register

Create a new user account and receive a JWT. POST /api/auth/register — no token header required.
Registration is gated by the ALLOW_REGISTRATION environment variable. If this variable is not set to true, the endpoint returns 403 Forbidden. This prevents unauthorized sign-ups on self-hosted instances.

Request Body

username
string
required
Desired username. Must be between 3 and 15 characters. Normalized to lowercase.
password
string
required
Desired password. Must be at least 5 characters.

Response — 200 OK

token
string
Signed JWT for the newly created user, valid for 1 hour.

Example

curl -X POST http://localhost:3008/api/auth/register \
  -H 'Content-Type: application/json' \
  -d '{"username": "alice", "password": "s3cur3pass"}'
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

GET /api/auth/me

Verify the current token and receive a refreshed token in the response header. GET /api/auth/me — requires token header. This endpoint exists primarily to allow the client to confirm it holds a valid token on app startup. It responds with 204 No Content — all meaningful data is in the Token response header.

Response — 204 No Content

No response body. The refreshed JWT is written into the Token response header by the auth middleware.

Example

curl -X GET http://localhost:3008/api/auth/me \
  -H 'token: <your-jwt>'

Using the Token

Include the JWT in the token header on every authenticated request:
curl http://localhost:3008/api/accounts \
  -H 'token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
In JavaScript using axios:
import axios from 'axios'

const api = axios.create({
  baseURL: 'http://localhost:3008/api',
})

// Attach the token to every request
api.interceptors.request.use((config) => {
  const token = localStorage.getItem('FINPER_TOKEN')
  if (token) config.headers['token'] = token
  return config
})

// Refresh the token from every response
api.interceptors.response.use((response) => {
  const refreshed = response.headers['token']
  if (refreshed) localStorage.setItem('FINPER_TOKEN', refreshed)
  return response
})
Tokens expire after 1 hour. The official Finper client refreshes the token automatically: every API response that comes back from an authenticated endpoint includes a new Token response header, and the axios interceptor stores it in localStorage. If you are building your own client, implement the same refresh pattern to avoid unexpected 401 errors during long sessions.

Build docs developers (and LLMs) love