Users

Reading returns only registered users — those who have accepted an invite. Pending invitations, deactivated accounts and deleted users are not returned, and GET /users/{id} answers 404 for them. Employees with a termination date stay in the list until they are deleted.

Creating and deleting mirror the CMS user management: users are created as regular employees and optionally invited to the app, and only manually created users can be deleted. Profile pictures can be set for any employee, for example from an HR system that holds the photos.

Required scope: read:users for reading, write:users for creating, deleting and setting profile pictures.

Endpoints

GET
/api/open/v1/users

List registered users (paginated, most recently registered first). Filters: ?group_id={id}, ?role={role}, ?since={date} (created on/after)

GET
/api/open/v1/users/{id}

Get a single user

POST
/api/open/v1/users

Create a user (returns 201 with the user)

DELETE
/api/open/v1/users/{id}

Soft delete a user (returns 204)

POST
/api/open/v1/users/{id}/avatar

Set the user's profile picture (multipart/form-data, returns 200 with the user)

List users

curl "https://customer.monotree.com/api/open/v1/users?group_id=1&per_page=25" \
  -H "Authorization: Bearer mono_your_token_here"
Query paramNotes
group_idFilter users that belong to this group.
roleFilter users that hold this role: admin, editor or user_editor. Any other value returns 422.
page, per_pageStandard pagination — see Pagination.
sinceISO 8601 date or datetime; an invalid value returns 422. Filters on created_at — when the account was created or invited — not on registered_at. A user invited before your last sync who accepts the invite after it is not returned by a later since request. To keep a complete list of employees, page through GET /users without since and compare by id, or keep the users whose registered_at is newer than your last sync.

Response

{
  "data": {
    "id": 42,
    "name": "John Doe",
    "first_name": "John",
    "last_name": "Doe",
    "title": "Head of Engineering",
    "email": "john@example.com",
    "type": "default",
    "avatar_url": "https://images.monotree.com/avatars/john-doe.jpg",
    "is_manager": false,
    "roles": ["editor"],
    "groups": [
      { "id": 1, "name": "Kitchen Staff", "type": "department", "is_manager": false, "is_editor": false, "created_at": "2026-01-15T10:00:00+01:00" }
    ],
    "hired_at": "2025-06-01",
    "date_of_birth": "1994-08-12",
    "is_away": false,
    "last_active_on": "2026-03-22T14:05:12.000000Z",
    "registered_at": "2025-06-01T09:00:00+02:00",
    "created_at": "2025-06-01T09:00:00+02:00"
  }
}

Field notes

  • type is default for an employee, or kiosk for a shared kiosk account. Bots and system accounts are never returned.
  • hired_at is the effective hire date: a manual override set in the CMS wins over the synced value.
  • date_of_birth is null unless the customer collects it (e.g. via an onboarding field).
  • title is the employee's job title, typed per user in the CMS, or null. When the company has chosen in the CMS to use the profession as the title, an empty title is filled with the name of the first profession the user was given and follows that profession from then on; a title an admin typed is left alone. The profession group(s) remain the synced position: filter groups[] by type profession, leaving out the App Managers group (name app_managers_group), which every manager is in (see Groups). Departments (type department) are the organizational/location unit; a user can belong to several.
  • avatar_url is a direct URL to the profile picture, or null. Embedded user objects on posts, comments and announcements carry the same field.
  • is_away is true while the user has set themselves as away in the app.
  • last_active_on is when the user was last active, or null. Unlike the other timestamps it is in UTC with microseconds (2026-03-22T14:05:12.000000Z). registered_at and created_at have the Copenhagen offset.
  • is_manager (top level) is true when the user manages at least one group. The is_manager flag on each groups[] entry tells which ones. To resolve an employee's manager(s), fetch the managers of their department group(s) via Groups.
  • roles lists the user's CMS roles: admin, editor and user_editor, in that order, or [] for a regular employee. Monotree's own support accounts are not listed. The /users endpoints include it; users embedded as authors, respondents and so on are not meant to carry it.
  • is_editor on each groups[] entry is true when the user is an editor of that group in the CMS. A group editor can edit content shared with the group, and with the user_editor role can also manage the group's users. Like roles, it is on the /users endpoints only; groups on users embedded elsewhere carry is_manager but not is_editor.

Create a user

curl -X POST https://customer.monotree.com/api/open/v1/users \
  -H "Authorization: Bearer mono_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "Jane",
    "last_name": "Doe",
    "email": "jane@example.com",
    "phone": "12345678",
    "phone_country_code": "NO",
    "groups": [1],
    "hired_at": "2026-09-01",
    "send_invite": true
  }'
FieldNotes
first_name, last_nameRequired. Max 255 characters each.
emailRequired. A valid email, max 255 characters; an address with no dot in its domain, such as name@gmail, returns 422. Lower-cased and trimmed; must not belong to a user who is not deleted (deactivated users included).
phoneOptional. Max 50 characters.
phone_country_codeOptional. ISO 3166-1 alpha-2, two letters (e.g. NO) — used to format the number for SMS invites sent from the CMS.
localeOptional. A locale code — use one from Locales. Any language Monotree knows is accepted, including one not activated on the platform.
hired_atOptional date. Defaults to today.
groupsOptional array of distinct group ids — departments, professions and custom groups (see Groups). The memberships count as manually added, so admins can change them in the CMS. The App Managers group and system groups are refused with 422: App Managers membership follows manager status.
send_inviteOptional boolean, default false. Emails the employee an invite to the app.

Returns 201 with the same user object as GET /users/{id}, with registered_at null (a restored account can differ, see below). A new user only shows up in GET /users after accepting the invite, and then with its original created_at, so a since-based sync will not pick it up — keep the id from the create response if you need to delete the user before that.

  • An email already used by a user who is not deleted, deactivated or not, is rejected with 422 (errors.email).
  • An email belonging to a deleted user restores that account instead of creating a duplicate. The response is still 201 and carries the existing id. first_name and last_name are written over the old values; locale, hired_at, phone and phone_country_code only when you send a value (the phone fields are left alone while the company hides all phone numbers), and hired_at does not default to today. The groups you send are added; the old memberships were removed when the user was deleted.
  • A restored account keeps its registration and its earlier invite. An employee who had registered comes back with their original registered_at, is listed in GET /users at once and can sign in with their old login. send_invite sends nothing when the account was invited before.
  • Users are always created as regular employees (type: default) — bots have their own endpoints.

Delete a user

curl -X DELETE https://customer.monotree.com/api/open/v1/users/42 \
  -H "Authorization: Bearer mono_your_token_here"

Soft deletes the user, same as deleting in the CMS: they lose access and disappear from the app; creating a user with the same email later restores the account. Returns 204.

Deleting a user also removes them from their groups, removes their boxes from the org chart (their reports move up one level), disconnects any AI client they connected, and deletes their personal staff cards and any published card assigned only to them — see Staff Cards.

Only manually created users can be deleted — a user synced from an external system (HR or rota portal) belongs to that sync and returns 422. Admins return 403 (Admins cannot be changed through the API.). Bots, system accounts and already deleted users return 404. Deactivated users can be deleted.

Set a profile picture

curl -X POST https://customer.monotree.com/api/open/v1/users/42/avatar \
  -H "Authorization: Bearer mono_your_token_here" \
  -F "media=@./jane.jpg"

Send the image as a multipart/form-data field named media (jpg, png, gif, bmp, webp, avif, heic or heif; not svg. The same rule as the app's own upload). Returns 200 with the user object; avatar_url already points at the new picture.

  • Works for any employee, including invited-but-unregistered and deactivated users. Admins return 403. Bots return 404, set theirs with PUT /bots/{id}.
  • A missing file or a file that is not an image returns 422 (errors.media).
  • Replaces whatever picture the user has, including one they chose themselves, and deletes the previous file. Colleagues are not notified.

A user's certificates, journeys and achievements are read on their own pages: GET /users/{userId}/certificates, GET /users/{userId}/journeys and GET /users/{userId}/achievements. To send a user a direct message as a bot, see Direct Messages.