Users API
The Users API manages user accounts, authentication, and identity on the Canvus server. Use it to sign users in and out, create and manage accounts, handle password resets, and perform administrative operations like blocking or approving users.
Authentication overview:
- Most endpoints require a
Private-Tokenheader or an active session cookie - Authentication endpoints (login, register, password reset) do not require authentication
- Admin-only endpoints are noted per section
Related APIs:
- Group membership is managed through the Groups API
- Long-lived API tokens are managed through the Access Tokens API
User object
Every user-related endpoint that returns user data uses the same JSON structure.
Note: User IDs (and group IDs) are integers, unlike most other API resources which use UUIDs.
Fields:
id(integer) -- unique user identifiername(string) -- display nameemail(string) -- email address, also used as the login nameadmin(boolean) -- whether the user has administrator privilegesapproved(boolean) -- whether the user account has been approvedblocked(boolean) -- whether the user account is blocked from signing instate(string) -- account state (e.g.,"normal")created_at(string) -- ISO 8601 timestamp of account creationlast_login(string) -- ISO 8601 timestamp of last sign-in, or empty string if never signed in
Example:
{
"id": 1002,
"name": "Alice Chen",
"email": "alice@example.com",
"admin": false,
"approved": true,
"blocked": false,
"state": "normal",
"created_at": "2025-03-15T09:22:41.817Z",
"last_login": "2025-03-28T14:05:12.003Z"
}
Sign In
Signs the user in with email and password, returning a session token.
POST /api/v1/users/login
Authentication: None required.
Streaming: Not supported.
Request body (JSON):
email(string, required) -- the user's email addresspassword(string, required) -- the user's passwordremember(boolean, optional) -- if true, extends the session lifetime
curl -X POST \
-H "Content-Type: application/json" \
-d '{"email":"alice@example.com","password":"s3cureP@ss"}' \
https://canvus.example.com/api/v1/users/login
Response (200 OK):
{
"token": "lmFU9obmM5v4o6jdCXsRW6v5bLD9w47aGIP4eMRnf3A",
"user": {
"id": 1002,
"name": "Alice Chen",
"email": "alice@example.com",
"admin": false,
"approved": true,
"blocked": false,
"state": "normal",
"created_at": "2025-03-15T09:22:41.817Z",
"last_login": "2025-03-28T14:05:12.003Z"
}
}
Use the returned token value in subsequent requests as the Private-Token header.
Token validation mode: You can also POST an existing token to validate and renew it. If valid, the session lifetime is extended and a new token is returned.
token(string, required) -- an existing access token to validate
curl -X POST \
-H "Content-Type: application/json" \
-d '{"token":"lmFU9obmM5v4o6jdCXsRW6v5bLD9w47aGIP4eMRnf3A"}' \
https://canvus.example.com/api/v1/users/login
Error responses:
401 Unauthorized-- invalid email/password or invalid token403 Forbidden-- account is blocked or not yet approved
SAML 2.0 Sign In
Validates a SAML 2.0 assertion and signs the user in. The server must have SAML authentication enabled in server settings.
POST /api/v1/users/login/saml
Authentication: None required.
Streaming: Not supported.
Request body (JSON):
inResponseTo(string, required) -- the request ID known to the SAML initiator (correlates response to request)responseXml(string, required) -- the full SAML response XMLremember(boolean, optional) -- if true, extends the session lifetime
curl -X POST \
-H "Content-Type: application/json" \
-d '{"inResponseTo":"_abc123","responseXml":"<samlp:Response>...</samlp:Response>","remember":true}' \
https://canvus.example.com/api/v1/users/login/saml
Response (200 OK): Same token + user object as the standard sign-in endpoint.
Error responses:
400 Bad Request-- invalid or malformed SAML assertion401 Unauthorized-- SAML assertion validation failed403 Forbidden-- SAML sign-in is disabled in server settings
Sign Out
Invalidates a session token, signing the user out.
POST /api/v1/users/logout
Authentication: Required.
Streaming: Not supported.
Request body (JSON, optional):
token(string, optional) -- specific token to invalidate. If omitted, the token from thePrivate-Tokenheader is invalidated.
curl -X POST \
-H "Private-Token: lmFU9obmM5v4o6jdCXsRW6v5bLD9w47aGIP4eMRnf3A" \
https://canvus.example.com/api/v1/users/logout
Response (200 OK): Empty body on success.
List Users
Returns all user accounts on the server.
GET /api/v1/users
Authentication: Required.
Streaming: Supports ?subscribe for live updates.
Query parameters:
subscribe(boolean, optional) -- if true, keeps the connection open and streams updates as newline-delimited JSON
curl -H "Private-Token: YOUR_TOKEN" \
https://canvus.example.com/api/v1/users
Response (200 OK):
[
{
"id": 100,
"name": "Guest",
"email": "",
"admin": false,
"approved": true,
"blocked": false,
"state": "normal",
"created_at": "2025-03-15T09:20:18.817Z",
"last_login": "2025-03-15T09:21:48.569Z"
},
{
"id": 1000,
"name": "Admin",
"email": "admin@example.com",
"admin": true,
"approved": true,
"blocked": false,
"state": "normal",
"created_at": "2025-03-15T09:20:33.392Z",
"last_login": "2025-03-28T14:05:12.003Z"
},
{
"id": 1002,
"name": "Alice Chen",
"email": "alice@example.com",
"admin": false,
"approved": true,
"blocked": false,
"state": "normal",
"created_at": "2025-03-15T09:22:41.817Z",
"last_login": ""
}
]
Get Single User
Returns details for a specific user.
GET /api/v1/users/:user_id
Authentication: Required.
Streaming: Supports ?subscribe for live updates.
Path parameters:
user-id(integer, required) -- the ID of the user
curl -H "Private-Token: YOUR_TOKEN" \
https://canvus.example.com/api/v1/users/1002
Response (200 OK):
{
"id": 1002,
"name": "Alice Chen",
"email": "alice@example.com",
"admin": false,
"approved": true,
"blocked": false,
"state": "normal",
"created_at": "2025-03-15T09:22:41.817Z",
"last_login": ""
}
Error responses:
404 Not Found-- no user with the given ID exists
Create User
Creates a new user account. If no password is provided, the server sends a password reset email to the new user.
POST /api/v1/users
Authentication: Admin required.
Streaming: Not supported.
Request body (JSON):
email(string, required) -- email address, used as the login name. Must be unique across all users.name(string, required) -- display namepassword(string, optional) -- initial password. If omitted, a password reset email is sent.admin(boolean, optional) -- grant administrator privileges. Default:false.approved(boolean, optional) -- mark the account as approved. Default depends on server settings.blocked(boolean, optional) -- create the account in blocked state. Default:false.
curl -X POST \
-H "Private-Token: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"email":"bob.martinez@example.com","name":"Bob Martinez","password":"b0bSecure!"}' \
https://canvus.example.com/api/v1/users
Response (201 Created):
{
"id": 1003,
"name": "Bob Martinez",
"email": "bob.martinez@example.com",
"admin": false,
"approved": true,
"blocked": false,
"state": "normal",
"created_at": "2025-03-28T15:10:22.501Z",
"last_login": ""
}
Error responses:
400 Bad Request-- missing required fields or invalid email format403 Forbidden-- caller is not an administrator409 Conflict-- a user with this email already exists
Update User
Changes user profile data. Regular users can update their own name and blocked fields. Administrators can change all fields of any user.
PATCH /api/v1/users/:user_id
Authentication: Required. Admin required for other users' profiles or admin-only fields.
Streaming: Not supported.
Path parameters:
user-id(integer, required) -- the ID of the user to update
Request body (JSON) -- all fields optional, include only those being changed:
name(string) -- display nameemail(string) -- email address. Must be unique. (Admin-only for other users.)password(string) -- new password. Admin-only.admin(boolean) -- grant or revoke admin privileges. Admin-only.approved(boolean) -- approve the user (can only change fromfalsetotrue). Admin-only.blocked(boolean) -- block or unblock the userneed_email_confirmation(boolean) -- confirm email on behalf of user (can only change fromfalsetotrue). Admin-only.
curl -X PATCH \
-H "Private-Token: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Alice Chen-Williams"}' \
https://canvus.example.com/api/v1/users/1002
Response (200 OK):
{
"id": 1002,
"name": "Alice Chen-Williams",
"email": "alice@example.com",
"admin": false,
"approved": true,
"blocked": false,
"state": "normal",
"created_at": "2025-03-15T09:22:41.817Z",
"last_login": "2025-03-28T14:05:12.003Z"
}
Error responses:
403 Forbidden-- insufficient permissions for the requested change404 Not Found-- no user with the given ID exists409 Conflict-- email already in use by another user
Delete User
Permanently deletes a user account.
DELETE /api/v1/users/:user_id
Authentication: Admin required.
Streaming: Not supported.
Path parameters:
user-id(integer, required) -- the ID of the user to delete
curl -X DELETE \
-H "Private-Token: YOUR_TOKEN" \
https://canvus.example.com/api/v1/users/1003
Response (200 OK): Empty body on success.
Error responses:
403 Forbidden-- caller is not an administrator404 Not Found-- no user with the given ID exists
Change Password
Allows a user to change their own password by providing the current password. Administrators can change the password of any user.
POST /api/v1/users/:user_id/password
Authentication: Required.
Streaming: Not supported.
Path parameters:
user-id(integer, required) -- the ID of the user
Request body (JSON):
current_password(string, required) -- the user's current passwordnew_password(string, required) -- the desired new password
curl -X POST \
-H "Private-Token: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"current_password":"s3cureP@ss","new_password":"n3wS3cure!"}' \
https://canvus.example.com/api/v1/users/1002/password
Response (200 OK): Returns the updated user object.
{
"id": 1002,
"name": "Alice Chen",
"email": "alice@example.com",
"admin": false,
"approved": true,
"blocked": false,
"state": "normal",
"created_at": "2025-03-15T09:22:41.817Z",
"last_login": "2025-03-28T14:05:12.003Z"
}
Error responses:
400 Bad Request-- current password is incorrect403 Forbidden-- non-admin trying to change another user's password
Change Email
Initiates an email change for a user. The server sends a confirmation link to the new email address.
POST /api/v1/users/:user_id/change-email
Authentication: Required.
Streaming: Not supported.
Path parameters:
user-id(integer, required) -- the ID of the user
Request body (JSON):
email(string, required) -- the new email address
curl -X POST \
-H "Private-Token: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"email":"alice.new@example.com"}' \
https://canvus.example.com/api/v1/users/1002/change-email
Error responses:
400 Bad Request-- invalid email format409 Conflict-- email already in use by another user
Confirm Email
Confirms a user's email address using a token received via email. This completes the email change or registration process.
POST /api/v1/users/confirm-email
Authentication: None required.
Streaming: Not supported.
Request body (JSON):
token(string, required) -- the confirmation token from the email
curl -X POST \
-H "Content-Type: application/json" \
-d '{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}' \
https://canvus.example.com/api/v1/users/confirm-email
Response (200 OK): Returns the confirmed user object.
Error responses:
400 Bad Request--{"msg": "Invalid email confirmation token."}-- token is expired, malformed, or already used
Request Password Reset
Sends a password reset email to the specified address. If the email matches an existing account, the user receives a reset token.
For security, this endpoint returns success even if no matching account exists.
POST /api/v1/users/password/create-reset-token
Authentication: None required.
Streaming: Not supported.
Request body (JSON):
email(string, required) -- the email address of the account to reset
curl -X POST \
-H "Content-Type: application/json" \
-d '{"email":"alice@example.com"}' \
https://canvus.example.com/api/v1/users/password/create-reset-token
Response (200 OK): Empty body on success.
Validate Password Reset Token
Checks whether a password reset token is still valid without consuming it. Use this to verify a token before showing the password reset form.
GET /api/v1/users/password/validate-reset-token
Authentication: None required.
Streaming: Not supported.
Query parameters:
token(string, required) -- the reset token from the email
curl "https://canvus.example.com/api/v1/users/password/validate-reset-token?token=eyJhbGciOiJIUzI1NiJ9..."
Response (200 OK): Empty body if the token is valid.
Error responses:
400 Bad Request--{"msg": "Invalid token"}-- token is expired, malformed, or already consumed
Reset Password
Sets a new password using a reset token from the password reset email.
POST /api/v1/users/password/reset
Authentication: None required.
Streaming: Not supported.
Request body (JSON):
token(string, required) -- the reset token from the emailpassword(string, required) -- the new password
curl -X POST \
-H "Content-Type: application/json" \
-d '{"token":"eyJhbGciOiJIUzI1NiJ9...","password":"myN3wP@ssword!"}' \
https://canvus.example.com/api/v1/users/password/reset
Response (200 OK): Returns the updated user object on success.
Error responses:
400 Bad Request--{"msg": "Invalid token"}-- token is expired, malformed, or already consumed
Register User (Self-Registration)
Allows a new user to create their own account. Self-registration must be enabled in the server settings.
On success, the server sends a confirmation email. The account is not active until the email is confirmed via the Confirm Email endpoint.
POST /api/v1/users/register
Authentication: None required.
Streaming: Not supported.
Request body (JSON):
email(string, required) -- email address, used as the login name. Must be unique.name(string, required) -- display namepassword(string, required) -- password for the new accountadmin(boolean, optional) -- ignored for non-admin callers. Default:false.approved(boolean, optional) -- ignored for non-admin callers. Default depends on server settings.blocked(boolean, optional) -- default:false
curl -X POST \
-H "Content-Type: application/json" \
-d '{"email":"carol.nguyen@example.com","name":"Carol Nguyen","password":"c@r0lSecure"}' \
https://canvus.example.com/api/v1/users/register
Response (201 Created): Returns the new user object.
Error responses:
400 Bad Request-- missing required fields403 Forbidden--{"msg": "Sign-up using a password is not enabled"}-- self-registration is disabled in server settings409 Conflict-- a user with this email already exists
Block User
Blocks a user account, preventing them from signing in. All active sessions are revoked.
Regular users can block their own account. Administrators can block any user.
POST /api/v1/users/:user_id/block
Authentication: Required.
Streaming: Not supported.
Path parameters:
user-id(integer, required) -- the ID of the user to block
curl -X POST \
-H "Private-Token: YOUR_TOKEN" \
https://canvus.example.com/api/v1/users/1002/block
Response (200 OK):
{
"id": 1002,
"name": "Alice Chen",
"email": "alice@example.com",
"admin": false,
"approved": true,
"blocked": true,
"state": "normal",
"created_at": "2025-03-15T09:22:41.817Z",
"last_login": "2025-03-28T14:05:12.003Z"
}
Error responses:
403 Forbidden-- non-admin trying to block another user404 Not Found-- no user with the given ID exists
Unblock User
Unblocks a previously blocked user account, allowing them to sign in again.
POST /api/v1/users/:user_id/unblock
Authentication: Admin required.
Streaming: Not supported.
Path parameters:
user-id(integer, required) -- the ID of the user to unblock
curl -X POST \
-H "Private-Token: YOUR_TOKEN" \
https://canvus.example.com/api/v1/users/1002/unblock
Response (200 OK):
{
"id": 1002,
"name": "Alice Chen",
"email": "alice@example.com",
"admin": false,
"approved": true,
"blocked": false,
"state": "normal",
"created_at": "2025-03-15T09:22:41.817Z",
"last_login": "2025-03-28T14:05:12.003Z"
}
Error responses:
403 Forbidden-- caller is not an administrator404 Not Found-- no user with the given ID exists
Approve User
Approves a user account that is pending approval (e.g., after self-registration when admin approval is required).
POST /api/v1/users/:user_id/approve
Authentication: Admin required.
Streaming: Not supported.
Path parameters:
user-id(integer, required) -- the ID of the user to approve
curl -X POST \
-H "Private-Token: YOUR_TOKEN" \
https://canvus.example.com/api/v1/users/1002/approve
Response (200 OK):
{
"id": 1002,
"name": "Alice Chen",
"email": "alice@example.com",
"admin": false,
"approved": true,
"blocked": false,
"state": "normal",
"created_at": "2025-03-15T09:22:41.817Z",
"last_login": ""
}
Error responses:
403 Forbidden-- caller is not an administrator404 Not Found-- no user with the given ID exists
Force Password Reset
Forces a password reset for a user. All of the user's active sessions are revoked, and the user must set a new password on next sign-in.
POST /api/v1/users/:user_id/reset-password
Authentication: Admin required.
Streaming: Not supported.
Path parameters:
user-id(integer, required) -- the ID of the user
curl -X POST \
-H "Private-Token: YOUR_TOKEN" \
https://canvus.example.com/api/v1/users/1002/reset-password
Response (200 OK): Returns the updated user object.
Error responses:
403 Forbidden-- caller is not an administrator404 Not Found-- no user with the given ID exists