Skip to content

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-Token header or an active session cookie
  • Authentication endpoints (login, register, password reset) do not require authentication
  • Admin-only endpoints are noted per section

Related APIs:


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 identifier
  • name (string) -- display name
  • email (string) -- email address, also used as the login name
  • admin (boolean) -- whether the user has administrator privileges
  • approved (boolean) -- whether the user account has been approved
  • blocked (boolean) -- whether the user account is blocked from signing in
  • state (string) -- account state (e.g., "normal")
  • created_at (string) -- ISO 8601 timestamp of account creation
  • last_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 address
  • password (string, required) -- the user's password
  • remember (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 token
  • 403 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 XML
  • remember (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 assertion
  • 401 Unauthorized -- SAML assertion validation failed
  • 403 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 the Private-Token header 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 name
  • password (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 format
  • 403 Forbidden -- caller is not an administrator
  • 409 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 name
  • email (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 from false to true). Admin-only.
  • blocked (boolean) -- block or unblock the user
  • need_email_confirmation (boolean) -- confirm email on behalf of user (can only change from false to true). 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 change
  • 404 Not Found -- no user with the given ID exists
  • 409 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 administrator
  • 404 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 password
  • new_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 incorrect
  • 403 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 format
  • 409 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 email
  • password (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 name
  • password (string, required) -- password for the new account
  • admin (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 fields
  • 403 Forbidden -- {"msg": "Sign-up using a password is not enabled"} -- self-registration is disabled in server settings
  • 409 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 user
  • 404 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 administrator
  • 404 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 administrator
  • 404 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 administrator
  • 404 Not Found -- no user with the given ID exists