Skip to content
OAOpenAppPhysical Security as a Service
Login

Users

Endpoints under the Users tag manage user accounts in organization context. Most routes require X-Org (see Organization context & pagination). Response bodies follow UserResponse, CreateUserRequest, UpdateUserRequest, AddRolesRequest, DeleteRolesRequest, and PaginatedResponse where applicable — see the API reference.

Related: Listing members inside an organization tree uses GET /orgs/{org_id}/users (list_org_users) under the Orgs tag — see Organizations.

ConcernHTTPoperationIdNotes
CreatePOST /userscreate_userHeader X-Org required; body CreateUserRequest (email and localized name fields per bundle). Query flags include_deleted, only_deleted, include_metadata.
SearchGET /users/searchsearch_usersQuery q, org_id, scope (all searches globally — needs users:list on root org), limit, offset, exclude_ids. Returns PaginatedResponse.
GetGET /users/{id}get_userHeader X-Org; optional include_deleted, include_metadata.
UpdatePUT /users/{id}update_userBody UpdateUserRequest.
Soft deleteDELETE /users/{id}delete_user
Hard deleteDELETE /users/{id}/purgehard_delete_userIrreversible purge.
Add rolesPOST /users/{id}/rolesadd_rolesBody AddRolesRequest (roles).
Remove rolesDELETE /users/{id}/rolesdelete_rolesBody DeleteRolesRequest.

Avatar uploads (POST /users/{id}/image, multipart) may be exposed by your deployment; the Python SDK includes upload_image / upload_image_from_url helpers when that route is available.

CapabilityPythonRust (openapp_sdk)GoTypeScript (AsyncClient)
Create / get / update / delete / purgeclient.users.*client.users()create, get, update, delete, purgeUsersAPI (full)Not on façade — extend via core transport or use another SDK
Searchsearch — passes q and optional filters; wire pagination uses limit / offset per OpenAPI (Python also accepts cursor as an extra query key — prefer offset alignment with the bundle)search(query) — sends q only; use transport() + RequestSpec for scope, offset, etc.SearchUsersNot on façade
Rolesadd_roles, remove_rolesadd_roles, remove_rolesAddRoles, DeleteRolesNot on façade
Avatarupload_image, upload_image_from_url (when route exists)Use transport or RESTGenerated client if present in your bundleNot on façade

401 / 403 when the caller lacks users:* permissions or X-Org context.404 for unknown user ids.409 on create/delete conflicts.422 on validation.400 on bad search parameters. Bodies follow ApiErrorResponse — see Errors & retries.

page = await client.users.search(
"alice",
org_id="org_123",
limit=20,
)
user = await client.users.create(
email="new.user@example.com",
org_id="org_123",
roles=["users:read"],
)

Get / update / delete / purge (/users/{id})

Section titled “Get / update / delete / purge (/users/{id})”

update_user replaces the row with UpdateUserRequest (optional email, name as LocalizedString). delete_user is a soft delete; hard_delete_user is irrecoverable. All four require X-Org.

user = await client.users.get(user_id)
updated = await client.users.update(user_id, name={"value": {"en": "Renamed"}})
await client.users.delete(user_id)
await client.users.purge(user_id)

Add and remove roles (POST / DELETE /users/{id}/roles)

Section titled “Add and remove roles (POST / DELETE /users/{id}/roles)”

Wire body AddRolesRequest / DeleteRolesRequest is a map of org id → role list (e.g. { "org_123": ["users:read"] }), letting one call grant or revoke roles across multiple orgs in a single request. Both routes require users:create (or admin) in each affected org.

await client.users.add_roles(user_id, ["users:read"])
await client.users.remove_roles(user_id, ["users:read"])

The Python helper sends a flattened {"roles": [...]} shape; for full OpenAPI parity (per-org grants in one call) issue POST|DELETE /users/{id}/roles through AsyncClient._request with the { "<org_id>": [...] } map directly.