Authentication
Almost every novem endpoint needs a bearer token. This page covers how you get one, how to manage your tokens, and the handful of public endpoints that don't require auth.
AI assisted, human approved — novem uses AI to review and keep our documentation up to date.
The novem API authenticates with a bearer token. You send it on every
request as an Authorization: Bearer <token> header (the CLI and python
library do this for you once you've logged in). A few endpoints (registration,
login, and the e-mail challenge) are public, so you can bootstrap an account and
a token in the first place.
Every path below also answers OPTIONS with the verbs valid for your token.
Getting a token
| Verb | Path | Auth | Description |
|---|---|---|---|
POST | /v1/register | public | Register a new user account |
POST | /v1/auth | basic | Log in with username + password; creates a token and sets a session cookie |
POST | /v1/token | basic | Create a new named API token; the token value is returned in the response |
GET | /v1/token | token | Verify credentials; returns 200 if the token is valid |
POST | /v1/logout | token | Invalidate the current session |
Note: the token value is shown once, when it's created. Store it
somewhere safe. You can't read it back later, only revoke it and issue a new
one. The CLI keeps it for you in ~/.config/novem/novem.conf.
Giving a token an expiry
By default a token lasts until you revoke it. POST /v1/token takes two optional
fields to bound it instead. Supply at most one of them; supplying both is
rejected with a 400.
expires_in— a duration from now: either an integer number of seconds, or a string like"24 hours"or"7 days".expires_on— an absolute timestamp, e.g."2026-09-01T12:00:00Z".
curl -u you:password https://api.novem.io/v1/token \
-d '{"token_name": "ci-deploy",
"token_description": "deploy pipeline",
"expires_in": "7 days"}'
The response echoes the resulting expires_on as a UTC ISO timestamp, or null
for a token that never expires:
{
"status": "Success",
"token": "novem_...",
"token_name": "ci-deploy",
"expires_on": "2026-08-25T09:14:03Z"
}
The expiry has to be a finite moment in the future. A past timestamp, a zero or
negative duration, and infinity are all rejected with a 400. A token that
never expires is spelled by omitting both fields, not by an infinite one.
The e-mail challenge
Some flows (registering, or verifying an e-mail address) send a code or link to your inbox and ask you to prove you received it.
| Verb | Path | Auth | Description |
|---|---|---|---|
POST | /v1/admin/challenge | public | Answer a challenge by its uid (knowing the uid from the e-mail is the proof, so no token is required) |
Who am I
| Verb | Path | Description |
|---|---|---|
GET | /v1/whoami | The user the current token authenticates as; useful for confirming which account a token belongs to |
Managing your tokens
Your tokens live under /v1/admin/tokens, addressed by name. This is where you
audit and revoke them, for instance to roll a token that may have leaked or to
clean up ones you no longer use.
| Verb | Path | Description |
|---|---|---|
GET | /v1/admin/tokens | List your tokens |
GET | /v1/admin/tokens/:token | A token's folder |
GET | /v1/admin/tokens/:token/info | Token metadata: name, creation time, expiry, last use |
GET | /v1/admin/tokens/:token/log | That token's activity log |
DELETE | /v1/admin/tokens/:token | Revoke the token |
Every token in the list carries an expires_on, null if it never expires.
Expired tokens stay in the list
An expired token stops working the moment it lapses, but it does not disappear.
Nothing sweeps it up in the background. The row is your own record of the
credential: what it was named, what it could reach, and when it lapsed. It stays
listed until you DELETE it yourself, exactly as you would revoke a live one.
Note: a token in your listing is not necessarily a token that works. Check
expires_on against the clock, or read the Expired field on the token's
info card.
/v1/admin/tokens/:token/info still answers for a lapsed token, and it reports
the two states separately:
Expires on: 2026-08-01 09:14
Active: Yes
Expired: Yes
Active: No means you revoked it. Expired: Yes means it ran out on its own.
Both answer 401 on use, but they send you to different fixes.
See also
- API overview — the request shape, verbs and permissions.
- Terminology — usernames, FQNPs and shortnames.
- Profile — your account's identity and settings.