QFind anything/
API Reference

Users

Users are managed via Keycloak. Assign users to tenants with per-environment roles to control access. List users, assign to tenants, or remove access.

What are users

Users represent people who can access Payment Reconciler. User identity is managed by Keycloak (email, password, SSO). Payment Reconciler stores a local user record linked to Keycloak and supports tenant assignment—granting a user access to specific tenants and environments with a role (admin or viewer).

Access control works as follows: a user must be assigned to a tenant (and optionally a specific environment) to access that tenant's data. The X-Tenant-Id and X-Environment headers in API requests determine which tenant/environment the user is acting in.

Keycloak integration

Users are created or synced from Keycloak. When you create a user via POST /users, the service provisions Keycloak and the local database. By default an invite email is sent with a one-time link; the user sets their password via POST /auth/invite/accept before signing in. Passwords are not returned in API responses in production.

Set sendInvite: false on create to skip the email (development only may return a generated password when invites are disabled).

Invite and assignment emails

EventEmail templateUser action
New user (POST /users)user.invitedAccept link → set password
Resend (POST /users/:id/resend-invite)user.invitedNew accept link
Assign existing user (POST /tenants/:tenantId/users)user.tenant_assignedSign in with existing credentials

Public endpoints (no auth): POST /auth/invite/verify, POST /auth/invite/accept.

See Tenant Branding for org display name and logo. GET /users/me includes memberships[].tenant.branding.

Invite status vs user status

status is the account-level state (ACTIVE, SUSPENDED, INACTIVE). New users are currently created as ACTIVE, even before they accept an invite.

To let the frontend track onboarding, user responses include an invite summary derived from invite records:

FieldMeaning
invite.inviteStatusNOT_SENT, PENDING, ACCEPTED, or EXPIRED for the latest invite
invite.lastInvitedAtTimestamp of the latest invite/resend
invite.inviteAcceptedAtTimestamp when an invite was accepted, if any
invite.inviteExpiresAtExpiry timestamp for the latest invite
invite.inviteCountTotal number of invites/resends created for the user
invite.lastInviteTypeNEW_USER, RESEND, or TENANT_ASSIGNED

Use invite.inviteStatus to show “Invite pending” or “Accepted” in user-management UI. Use status only for account availability/admin deactivation.

Tenant assignment

To give a user access to a tenant:

  • AssignPOST /tenants/:tenantId/users with userId, environment, and role
  • List tenant usersGET /tenants/:tenantId/users to see who has access
  • RemoveDELETE /tenants/:tenantId/users/:userId to revoke access

Assignment can be per-environment (e.g. user has access only to production) or across environments depending on your setup.

Roles

RoleAccess
adminFull access to the tenant environment—create, update, delete resources
viewerRead-only access—list and retrieve, no create/update/delete

Roles are enforced per tenant and environment. A user can be admin for one tenant and viewer for another.

User lifecycle

  • Create — Provision a new user (Keycloak-backed)
  • List — List all users (filter by tenant if needed)
  • Update — Update display name, status
  • DeactivateDELETE /users/:id deactivates the user (soft delete; they lose access)

API Reference

For user creation, tenant assignment parameters, and request/response samples, see Users in the API Reference.