Users, invitations, groups and delegated admin

The user record, inviting internal and portal users, groups and nested membership, and delegating limited user administration.

The user record#

Users are records in the users system collection:

AttributeValues
emaillogin identifier (unique per tenant)
userTypeINTERNAL (staff) or PORTAL (external)
statusPENDING_ACTIVATION, ACTIVE, INACTIVE, LOCKED, ANONYMIZED (see Anonymizing a user)
profileIdthe one profile that grants permissions
managerIdoptional manager lookup (used by approval hierarchy routing)
firstName, lastName, username, locale, timezoneprofile data
mfaEnabled, lastLoginAt, loginCountread-only status

Writes to users and group-memberships require MANAGE_USERS (or MODIFY_ALL_DATA), whichever path they take — console, JSON:API, batch operations or CLI. Setup → Administration → Users is the console surface.

Inviting users#

POST /api/users
{ "data": { "type": "users", "attributes": { "email": "ana@example.com", "firstName": "Ana", "profileId": "<profile id>" } } }

POST /api/admin/users/{userId}/invite     # (re)send the invitation email

The invitation carries a one-time link; the user sets a password (and enrols MFA if required) and becomes ACTIVE. Users created by SSO just-in-time provisioning or SCIM skip this step.

Portal users are invited with POST /api/admin/users/portal-invite and get the Portal User profile; the maxPortalUsers governor limit applies.

CLI: kelta users list|get|invite|portal-invite|reset-password|token-create|logins; create with kelta api POST /api/users.

Deactivating#

Set status: INACTIVE (console Deactivate, or PATCH). The user can no longer log in and existing sessions stop refreshing. Two things to know:

  • A personal access token owned by the user may keep authenticating for up to the gateway’s identity-cache window (a few minutes). To cut access immediately, revoke the token or remove API_ACCESS from the profile.
  • Records the user created keep their createdBy reference; ownership is not reassigned automatically.

Anonymizing a user#

DELETE /api/users/{id} is refused (409 REFERENCED_RECORD) for any user who created or owns records. To erase such a user’s personal data — a “delete my account” request, GDPR/CCPA-style erasure — anonymize them instead. The user row and its id stay, so every record that points at the user keeps pointing at the same id.

POST /api/admin/users/{id}/anonymize      # requires MANAGE_USERS

Answers 200 {"userId": "…", "status": "ANONYMIZED", "alreadyAnonymized": false}. Anonymizing an anonymized user answers 200 again with alreadyAnonymized: true and changes nothing. A user id from another tenant answers 404; the system user and your own id answer 400.

From a flow, use the ANONYMIZE_USER task with the user id in its parameters:

{ "Type": "Task", "Resource": "ANONYMIZE_USER", "Parameters": { "userId": "${$.input.userId}" }, "End": true }

The step fails unless the flow’s user is an active user whose profile grants MANAGE_USERS. Its output is {"userId": "…", "alreadyAnonymized": true|false}.

Erased — in one transaction:

WhatBecomes
emaildeleted+<id>@invalid (unique, never deliverable)
username, firstName, lastName, phone number, email-verification tokencleared
settings{}
statusANONYMIZED
password, TOTP secret, MFA recovery codesrows deleted (mfaEnabled becomes false)
saved list views, favorites and recents (UI preferences), portal magic-link tokens, registered push devicesrows deleted
personal access tokensrevoked
sign-in sessions and refresh tokensended; access tokens already issued are rejected by the gateway

Kept:

  • the user’s id, userType, profileId, managerId, locale, timezone, createdAt, sign-in counters;
  • the audit history — setup-audit, login-history and field-history rows, including values they recorded before the anonymize;
  • every record the user created, updated or owns — createdBy, updatedBy and owner fields still hold the same id. Erasing tenant data about the person (their orders, messages, documents) is up to the tenant: delete or scrub those records first, for example in the same flow before the ANONYMIZE_USER step.

ANONYMIZED is final: an update that sets any other status, or a new email, answers 409 USER_ANONYMIZED, and status: ANONYMIZED can only be set by the endpoint or the flow action; SCIM answers 404 for an anonymized user. An anonymized user cannot sign in by any method. If the person later signs in through SSO with their old email, just-in-time provisioning creates a new, unrelated user. Each anonymize writes one setup-audit entry (action ANONYMIZED) naming the actor and the user id, without the erased values.

Groups#

user-groups collect users and other groups:

AttributeValues
groupTypePUBLIC (sharing), QUEUE (assignable work queue — approval steps can route to a queue), SYSTEM
sourceMANUAL or synchronised from a provider (SCIM)
oidcGroupNameexternal identifier of a synchronised group

Membership rows (group-memberships) have memberType: USER or GROUP, so groups nest. Effective membership is resolved transitively when permissions and shares are evaluated.

There is no dedicated console page yet; manage groups through the Resource Browser (/resources/user-groups, /resources/group-memberships), the JSON:API, or kelta api. Membership writes require MANAGE_USERS (or MODIFY_ALL_DATA).

Delegated administration#

Full administrators can let selected users manage some users without granting MANAGE_USERS:

  1. Create a delegated-admin scope (Setup → Administration → Delegated admins, requires MANAGE_DELEGATED_ADMINS): the delegates (delegatedUserIds), the profiles they may assign (manageableProfileIds), and the switches canCreateUsers, canDeactivateUsers, canResetPasswords. API: GET/POST /api/admin/delegated-admin-scopes, GET/PATCH/DELETE /api/admin/delegated-admin-scopes/{id}.
  2. Delegates use the scoped endpoints under /api/admin/delegated/* (GET /me for their effective scope, GET|POST /users, PATCH /users/{id}, invite, reset password). The console shows them a filtered Users page.

Guard rails: a scope cannot include a profile that grants a privileged permission (no delegating admin-of-admins); delegates cannot edit their own record, change email, manager or MFA, or move a user outside the manageable profiles; scopes are re-checked on every request, so revoking one is immediate.

Edit this page on GitHub