Users API
REST endpoints to list, retrieve, create, update, and delete users in octoja.
Users API
The Users API lets you query and manage user records. All endpoints require a valid access token in the Authorization: Bearer <token> header — see API Authentication for how to obtain one.
For the complete, always-current list of endpoints, parameters, and response fields for the version you are running, use the interactive OpenAPI (Swagger) interface at https://<your-octoja-instance>/openapi/index.html. This article keeps only the permissions, behaviors, and validation rules that the schema cannot express.
Endpoints
Get the current user
GET /api/users/me returns a session-scoped view of the authenticated caller whose shape differs from the regular User object: the email field is named email (not mailAddress), the full groups objects are returned with their resolved permissions (not only groupIds), and an additional preferences field is included. Field-by-field details are in Swagger.
Creating a user
Requires the users.manage permission. Required: mailAddress (the login email address, which must be unique) and lastname. firstname and password are optional; the full field list is in Swagger.
If you create a user without a password, that user has no local password login and needs a linked OIDC / SSO login before they can sign in. A common example is Microsoft SSO. For Microsoft SSO, the first sign-in may require a Microsoft administrator in the Microsoft tenant to grant consent for octoja.
POST /api/users creates the account directly and assigns no groups. To let someone choose their own password, start out in the right groups, and link an SSO login as part of sign-up, send an invitation instead — see Inviting a user.
Updating a user
POST /api/users/{id}
Requires the users.manage permission. Send only the fields you want to change. Each field is wrapped in an UpdateValue<T> envelope of the shape { "hasValue": true, "value": <T> }; omit the field entirely to leave it untouched. Sending a bare value (for example "newFirstname": "Max") is rejected as a deserialization error. The full updatable-field list is in Swagger; the fields below carry behavior worth knowing:
{
"newFirstname": { "hasValue": true, "value": "Max" },
"newPassword": { "hasValue": true, "value": null }
}
newMailAddress— new login email address; must be unique.newPassword— avalueofnullremoves the local password login, making the account SSO-only unless a new password is set later.newFirstname/newLastname— avalueofnullclears the name.newMobileNumber— the number SMS and call notifications go to. An empty or whitespace-onlyvalueclears it.newRemoteSupportDisplayName— the name shown on the customer's device during a remote support session. An empty or whitespace-onlyvalueclears it; the name from the technician name template is shown instead, or the user's own name if no template is set.newTotpSecret— avalueofnulldisables TOTP.oidcProvidersToUnlink— OIDC providers to unlink, for example["Microsoft"].
Group membership is not part of this request. A user's groups are assigned through POST /api/groups/{id} with newMemberUserIds, which requires the groups.manage permission — see Groups API.
Validation rules
newMailAddresswith an empty or whitespace-onlyvalue, or one already used by another user, returns400 Bad Request.newPasswordwith an empty or whitespace-onlyvaluereturns400 Bad Request— usenullto remove the password.
Deleting a user
Requires the users.manage permission. A safety guard applies: deleting a user is rejected if it would leave no remaining member of a group with the groups.manage permission.
Inviting a user
POST /api/user-invitations
Requires the users.manage permission. An invitation records who is being onboarded and emails them a link; the account itself is created when they accept. Required: mailAddress and lastname. firstname is optional. groupIds sets the groups the new account joins on acceptance and additionally requires the groups.manage permission — without it the request returns 403 Forbidden. The response carries the invitation id and the invite URL, so you can pass the link on through another channel as well.
The recipient has two ways to accept: set a password through POST /api/user-invitations/accept (minimum 8 characters), or sign in with an OIDC provider, which links that provider to the new account. Either way, any group that was deleted between invitation and acceptance is dropped from the assignment.
Validation rules
- An empty or whitespace-only
mailAddressreturns400 Bad Request. - An address that already belongs to a user, or that already has a pending invitation, returns
400 Bad Request. groupIdscontaining an unknown group ID returns400 Bad Request.- Invitations expire 7 days after they are sent.
POST /api/user-invitations/{id}/resendemails the link again and restarts those 7 days; calling it within 60 seconds of the last send returns429 Too Many Requests. POST /api/user-invitations/acceptreturns404 Not Foundfor an unknown or already-accepted token,410 Gonefor an expired one,400 Bad Requestfor a password shorter than 8 characters, and409 Conflictif a user with that address was created in the meantime.
GET /api/user-invitations lists every invitation, newest first, including the ones already accepted or revoked. Read the status field to tell them apart.
Update your own profile
POST /api/users/me is available to every authenticated user — no users.manage permission required. Fields use the same UpdateValue<T> envelope as "Updating a user" and the endpoint returns the updated user. Behaviors worth knowing:
newFirstname— avalueofnullor an empty string clears it.newLastname— an empty or whitespace-onlyvalueis rejected with400 Bad Request.newMobileNumber— the number your SMS and call notifications go to. An empty or whitespace-onlyvalueclears it.newTotpSecret— avalueofnulldisables TOTP.oidcProvidersToUnlink— unlink your own OIDC sign-ins, for example["Microsoft"]. Rejected with400 Bad Requestif it would leave you with no way to sign in (no local password and no remaining linked login).
Change your own password
POST /api/users/me/change-password
Available to every authenticated user. This endpoint uses plain fields (currentPassword, newPassword), not the UpdateValue envelope. It returns 400 Bad Request if either field is empty, if the account has no local password set, or if currentPassword is incorrect. On success the response is 204 No Content.
Remove your own password
DELETE /api/users/me/password
Available to every authenticated user. This removes your local password so the account signs in through SSO only. It returns 400 Bad Request if no password is set, or if the account has no linked OIDC login — octoja always keeps at least one sign-in method, so the password stays in place until another login is linked. On success the response is 204 No Content.
Update your preferences
POST /api/users/me/preferences is available to every authenticated user and updates the preferences object returned by GET /api/users/me. It returns the updated preferences object. Behaviors worth knowing:
toggleFavoriteAssetId— toggles the device in the favorites list: adds it if absent, removes it if present. Maximum 100 favorites; adding beyond that is rejected with400 Bad Request.startPage— the page shown after sign-in. One of a fixed set of values (Dashboard,Cases,Devices,Customers,PatchCycles); defaultDashboard.openDevicesInNewTab— whether device links open in a new browser tab.locale— your profile language, for examplede. SMS, call, and app-push notifications are sent in this language; SMS and calls fall back to English and push to the device language when it is unset. An empty or whitespace-only value clears it.welcomeSeen— whether you have already seen the welcome dialog. The web interface sets this totrueonce you close it.
Fields worth knowing
The full User object is documented field-by-field in Swagger. A few fields carry behavior that is easy to miss:
mailAddress— the login email address on the standard User object; noteGET /api/users/mereturns this asemailinstead.groupIds— the IDs of the groups this user belongs to; the resolved group objects with permissions are returned only byGET /api/users/me. Read-only on this object — membership is set through the Groups API.hasPassword/hasTotpSecret— booleans that report whether a local password or TOTP is set, without exposing the secret.oidcLogins— linked OIDC sign-ins; each entry carriesproviderId(for exampleMicrosoft),subjectId, andlinkedAt.
Was this helpful?
More in API Reference
API AuthenticationAPI Design PrinciplesError CodesAbout APIStill need help? Ask the team