People and sessions
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/sessionsReturns 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.
curl -X POST "$SENTINEL_URL/v1/sessions" \
-H "Content-Type: application/json" \
-d '{
"email": "ama@example.com",
"password": "..."
}'
{
"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/currentEnds the session making the request. Returns 204. Calling it with an API key returns 401.
curl -X DELETE "$SENTINEL_URL/v1/sessions/current" \
-H "Authorization: Bearer $SENTINEL_SESSION"
Who am I
GET /v1/meSays who the credentials belong to: a person, with their role, or an API key. Works with both.
{
"kind": "api_key",
"id": "3f2e1d0c-9b8a-4765-8432-10fedcba9876",
"name": "payments-core"
}
Change your password
POST /v1/me/passwordChanges your own password and ends your other sessions. The one making the request stays signed in. Returns 204.
List people
GET /v1/usersReturns everyone on the install, active people first. Any signed-in person can call it.
{
"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/usersAdmins 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.
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"
}'
{
"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.
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}/passwordAdmins only. Gives the person a new first password, shown once, and signs them out everywhere. They replace it at their next sign-in.
{
"password": "..."
}
Errors
| Endpoint | Code | error |
|---|---|---|
POST /v1/sessions | 401 | email or password is wrong, or the account is deactivated |
| All others | 401 | missing or invalid API key or session |
POST /v1/sessions | 429 | too many sign-in attempts; wait a minute and try again |
DELETE /v1/sessions/current | 401 | not signed in with a session |
POST /v1/me/password | 403 | your current password is wrong |
POST /v1/users, PATCH | 400 | role must be admin, reviewer, analyst or engineer |
POST /v1/users | 409 | someone with that email already has an account |
PATCH | 409 | you can't change your own role or deactivate yourself; ask another admin |
PATCH | 409 | this is the last active admin; make someone else an admin first |
PATCH, reset | 404 | no such person |