API reference

People and sessions

Sign in, sign out, change your password, and manage the people on your install.

People sign in with email and password and get a session token. The dashboard uses these endpoints, and you can use them too, for example to script a sign-in in a test. See Authentication for how sessions differ from API keys.

The examples put a session token in $SENTINEL_SESSION.

Sign in

POST /v1/sessions

Returns a session token. Send it as a bearer token, like an API key. Sessions last 12 hours. This is the only /v1 route that needs no credentials.

email
string required
The person's email. Case doesn't matter.
password
string required
Their password.
Terminal
curl -X POST "$SENTINEL_URL/v1/sessions" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "ama@example.com",
    "password": "..."
  }'
Response · 201
{
  "token": "snt_sess_q8Vt0yWn5Bc7Hd1Jp4Gs6Fz9Ke3Ua0Ox2Lr8Xk3f9aQ",
  "expires_at": "2026-10-16T21:12:44Z",
  "me": {
    "kind": "user",
    "id": "2d1c0b9a-8f7e-4a6b-9c5d-4e3f2a1b0c9d",
    "name": "Ama Owusu",
    "email": "ama@example.com",
    "role": "reviewer",
    "must_change_password": false
  }
}

A wrong email, a wrong password and a deactivated person all get the same 401, so the response never tells anyone which emails have accounts. Sign-in attempts are limited for each address and each email: about five a minute. Past that you get 429 with a Retry-After header.

The first password

A new person, or one whose password an admin reset, gets a first password and has must_change_password set to true. Until they change it, every other request returns 403 with change the password you were given before doing anything else.

Sign out

DELETE /v1/sessions/current

Ends the session making the request. Returns 204. Calling it with an API key returns 401.

Terminal
curl -X DELETE "$SENTINEL_URL/v1/sessions/current" \
  -H "Authorization: Bearer $SENTINEL_SESSION"

Who am I

GET /v1/me

Says who the credentials belong to: a person, with their role, or an API key. Works with both.

Response · 200
{
  "kind": "api_key",
  "id": "3f2e1d0c-9b8a-4765-8432-10fedcba9876",
  "name": "payments-core"
}

Change your password

POST /v1/me/password

Changes your own password and ends your other sessions. The one making the request stays signed in. Returns 204.

current_password
string required
Your password now, or the first password you were given.
new_password
string required
12 to 72 characters.

List people

GET /v1/users

Returns everyone on the install, active people first. Any signed-in person can call it.

Response · 200
{
  "users": [
    {
      "id": "2d1c0b9a-8f7e-4a6b-9c5d-4e3f2a1b0c9d",
      "email": "ama@example.com",
      "name": "Ama Owusu",
      "role": "reviewer",
      "active": true,
      "created_by": "9c8b7a6f-5e4d-4c3b-8a2f-1e0d9c8b7a6f",
      "created_at": "2026-10-15T08:20:11.402Z",
      "last_sign_in_at": "2026-10-16T09:12:44.118Z",
      "must_change_password": false
    }
  ]
}

Add a person

POST /v1/users

Admins only. Adds a person and returns their first password. This response is the only time it's shown, so pass it on to them straight away. They replace it when they first sign in. Returns 201.

email
string required
Their email. Each email can have one account.
name
string required
Their name, 1 to 100 characters.
role
string required
admin, reviewer, analyst or engineer. See roles.
Terminal
curl -X POST "$SENTINEL_URL/v1/users" \
  -H "Authorization: Bearer $SENTINEL_SESSION" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "kofi@example.com",
    "name": "Kofi Mensah",
    "role": "analyst"
  }'
Response · 201
{
  "user": {
    "id": "5e4d3c2b-1a09-4f8e-9d7c-6b5a4f3e2d1c",
    "email": "kofi@example.com",
    "name": "Kofi Mensah",
    "role": "analyst",
    "active": true,
    "created_by": "9c8b7a6f-5e4d-4c3b-8a2f-1e0d9c8b7a6f",
    "created_at": "2026-10-16T10:02:31.770Z",
    "must_change_password": true
  },
  "password": "..."
}

Change a role, or deactivate someone

PATCH /v1/users/{id}

Admins only. Send role, active or both. A deactivated person is signed out and can't sign in again until an admin reactivates them. People are never deleted, because audit entries name them.

role
string
The new role.
active
boolean
false to deactivate, true to reactivate.

Two changes are refused with 409:

  • your own role or your own account. Ask another admin.
  • anything that would leave the install with no active admin.

Reset a password

POST /v1/users/{id}/password

Admins only. Gives the person a new first password, shown once, and signs them out everywhere. They replace it at their next sign-in.

Response · 200
{
  "password": "..."
}

Errors

EndpointCodeerror
POST /v1/sessions401email or password is wrong, or the account is deactivated
All others401missing or invalid API key or session
POST /v1/sessions429too many sign-in attempts; wait a minute and try again
DELETE /v1/sessions/current401not signed in with a session
POST /v1/me/password403your current password is wrong
POST /v1/users, PATCH400role must be admin, reviewer, analyst or engineer
POST /v1/users409someone with that email already has an account
PATCH409you can't change your own role or deactivate yourself; ask another admin
PATCH409this is the last active admin; make someone else an admin first
PATCH, reset404no such person
Sentinel is a Somu Labs product. © 2026 Somu Labs Ltd.