Users & invitations

Team management within a tenant. Backed by users.py (~2,300 lines).

GET /api/users

Lists users belonging to the caller’s tenant.

POST /api/users/create

{ "email": "new.user@acme.com", "name": "New User", "password": "..." }

DELETE /api/users/<id>

Deactivates a user (soft — flips active, doesn’t delete the record).

PUT /api/users/<id>/role

{ "role": "admin" }

Invitations

Rather than creating a user directly, the more common flow is inviting one by email and letting them set their own password:

Route

Method

Purpose

/api/users/invite

POST

Invite a new user — {"email", "name", "role", "instance_id"}

/api/users/invitation

POST

Same shape, used from the dedicated invitations UI

/api/users/invitation/<token>

GET

Public — look up an invitation by its token (renders the accept-invite screen)

/api/users/invitation/accept

POST

Public — {"token", "password"}, completes signup

/api/users/invitation/<id>/resend

POST

Resend the invite email

/api/users/invitation/<id>/cancel

POST

Cancel a pending invitation

/api/users/invitation/<token> and /api/users/invitation/accept are the two invitation routes that don’t require a bearer token — the invited person doesn’t have an account yet, so the invitation token itself is the credential for that single accept step.