Users

A user is a member of staff with a Trialflare account. Most integrations only need GET /users/me, to find the team and permissions behind their key; the rest of these endpoints administer other users' accounts and need the team permissions noted.

Endpoints

Method Path Description
GET /users/me The account behind the key. 5 requests per minute — call it once, not before every request.
PUT /users/<userId> Update a user's details. Your own account, or users.manage / team.manage. 10 requests per minute.
DELETE /users/<userId> Delete a user. Needs users.delete. 5 requests per minute.
POST /users/<userId>/disable Disable an account. Body: {"reason": "..."} (required, logged). Needs users.manage.
POST /users/<userId>/enable Re-enable a disabled account. Needs users.manage.
DELETE /users/<userId>/mfa Reset a user's two-factor authentication: their authenticator app and passkeys are removed and they set up a new second factor on next sign-in. Needs users.manage. 5 requests per minute.
PUT /users/<userId>/permissions/<scopeId> Replace a user's permissions at one scope.
PUT /users/<userId>/roles/<roleId> Give a user a trial role.
DELETE /users/<userId>/roles/<roleId> Take a role away.
PUT /users/<userId>/teams/<teamId> Switch which of your teams is current. Your own account only.

Your own account

GET /users/me returns:

{
  "_id": "…",
  "firstName": "Ada", "lastName": "Lovelace", "email": "ada@example.org",
  "team": "<current team _id>",
  "teams": ["<team _id>", "…"],
  "permissions": {"<teamId>": ["users.create", "trials.create"], "<trialId>": ["trial.admin"], "…": []},
  "timezone": "Europe/London",
  "otpEnabled": true, "hasPasskey": false, "hasPassword": true,
  "mcpEnabled": false
}

permissions is keyed by scope _id — a team, a trial, a site or a group — and lists the permission keys held there. It is the effective set, so permissions that come from a role are included.

Updating a user

PUT /users/<userId> accepts firstName, lastName (2–30 characters), email, timezone (an IANA name such as Europe/London) and mcpEnabled (whether the user may connect an AI assistant). A team.manage holder may also set incorrectLoginAttempts — usually to 0, to clear a lockout.

Disabling is preferable to deleting when someone leaves: a disabled account keeps its permissions, roles and history and is signed out everywhere; a deleted one leaves only its email address in the event log.

Permissions

PUT /users/<userId>/permissions/<scopeId> takes {"permissions": ["trial.read", "trial.readParticipantStudyData"]} and replaces the user's permissions at that scope — the trial, site, group or team whose _id you give. Send the full list you want them to end up with; an empty list removes everything at that scope. You need the ability to change permissions at that scope yourself (trial.admin on the trial, or users.manage / team.manage on the team). The change is logged with what was granted and what was revoked.

The available keys are listed in Roles and permissions (trial.*, site.*, group.*) and Team permissions.

Roles

Where a trial has roles defined, PUT /users/<userId>/roles/<roleId> and DELETE /users/<userId>/roles/<roleId> add and remove them; both return the user's full roles list. Roles are created and edited under the trial: see Trials.