API documentation out of date

The API documentation on the Mattermost web site appears to be out of date. It also looks like there have been non-backward-compatible changes made at some point without bumping the API version number.

For example, this is the documented API response for the /api/v4/users endpoint side-by-side with the actual response from a 10.5.10 (ESR) server. I’ve normalized the values on the Actual side to "string", true, and 0 except for the one occurrence of "true" (see below) and given parameters that appear on both sides the same sort order as the documentation.

EDIT: The Actual data below was pulled using an API key belonging to an administrator.

Documented Actual
[
  {
    "id": "string",
    "create_at": 0,
    "update_at": 0,
    "delete_at": 0,
    "username": "string",
    "first_name": "string",
    "last_name": "string",
    "nickname": "string",
    "email": "string",
    "email_verified": true,
    "auth_service": "string",
    "roles": "string",
    "locale": "string",
    "notify_props": {
      "email": "string",
      "push": "string",
      "desktop": "string",
      "desktop_sound": "string",
      "mention_keys": "string",
      "channel": "string",
      "first_name": "string"
    },
    "timezone": {
      "automaticTimezone": "string",
      "useAutomaticTimezone": true,
      "manualTimezone": "string"
    },
    "props": {},
    "last_password_update": 0,
    "last_picture_update": 0,
    "failed_attempts": 0,
    "mfa_active": true,
    "terms_of_service_id": "string",
    "terms_of_service_create_at": 0
  }
]
[
  {
    "id": "string",
    "create_at": 0,
    "update_at": 0,
    "delete_at": 0,
    "username": "string",
    "first_name": "string",
    "last_name": "string",
    "nickname": "string",
    "email": "string",
    "auth_service": "string",
    "roles": "string",
    "locale": "string",
    "notify_props": {
      "email": "string",
      "push": "string",
      "desktop": "string",
      "desktop_sound": "string",
      "mention_keys": "string",
      "channel": "string",
      "first_name": "string",
      "comments": "string",
      "desktop_threads": "string",
      "email_threads": "string",
      "push_status": "string",
      "push_threads": "string"
     },
    "auth_data": "string",
    "position": "string",
    "timezone": {
      "automaticTimezone": "string",
      "useAutomaticTimezone": "true",
      "manualTimezone": "string"
    },
    "disable_welcome_email": true
  }
]

Because it can be difficult to track all the changes visually, here’s a diff of the two blocks.

--- docs.json	2025-09-12 10:02:39
+++ actual.json	2025-09-12 10:02:39
@@ -9,7 +9,6 @@
     "last_name": "string",
     "nickname": "string",
     "email": "string",
-    "email_verified": true,
     "auth_service": "string",
     "roles": "string",
     "locale": "string",
@@ -20,19 +19,20 @@
       "desktop_sound": "string",
       "mention_keys": "string",
       "channel": "string",
-      "first_name": "string"
-    },
+      "first_name": "string",
+      "comments": "string",
+      "desktop_threads": "string",
+      "email_threads": "string",
+      "push_status": "string",
+      "push_threads": "string"
+     },
+    "auth_data": "string",
+    "position": "string",
     "timezone": {
       "automaticTimezone": "string",
-      "useAutomaticTimezone": true,
+      "useAutomaticTimezone": "true",
       "manualTimezone": "string"
     },
-    "props": {},
-    "last_password_update": 0,
-    "last_picture_update": 0,
-    "failed_attempts": 0,
-    "mfa_active": true,
-    "terms_of_service_id": "string",
-    "terms_of_service_create_at": 0
+    "disable_welcome_email": true
   }
 ]

Ignore the notify_props.first_name “change” and the closing brace below it.. those are just triggered by the final item in the list acquiring a comma when more items are added.

None of these parameters are marked as optional or have any “only returned if…” mentions in their docs, which makes the 8 documented parameters not returned by a current server breaking changes, which should have triggered an API version bump from v4 to v5.

There are also a number of new-additions that are not documented; though the lack of documentation is aggravating, at least those shouldn’t break existing API client code.

I also note a bug where timezone.useAutomaticTimezone is documented to return a boolean, but actually returns a string representation of a boolean (compare with the undocumented new disable_welcome_email attribute which returns an actual boolean).

I haven’t been able to quickly find when these changes were made. There is no reference to these changes in the v10 Changelog. The only reference to API deprecations in the list of Removed and Deprecated Features are for /api/v4/image being marked as deprecated, and the pageSizeparameter being removed in 10.0. There don’t seem to be any mentions of API changes in Announcements on here.

So, I have a couple questions:

  1. Should we expect breaking changes without an API version change? This seems antithetical to the whole idea of a versioned API.
  2. Are there more up-to-date API docs somewhere else?

Thanks!

1 Like

I just talked to @jwilander on the community chat (thanks for taking all that time!) and so I’ve got a followup to my own post.

There are three explanations that cover some of the issues I raised:

  • Documentation Staleness: Yes, the documentation is out of date. There are a number of parameters that are returned by a server that are not documented, and those are being added.

  • “true” vs true: The return type of useAutomaticTimezone being a string instead of a boolean is a design flaw, but “working as designed”, and the documentation is being updated to reflect the actual return type.

  • Restricted Values: Some fields are only returned when the requesting user is authorized to see them (e.g. a user requesting data about themselves, or an admin requesting data), however these are not noted in the documentation.

As a result of our conversation there is already a PR addressing the first two issues, and partially addressing the third.

There are some issues still outstanding, and I’m planning to open GitHub Issues covering them, and will possibly be submitting some PRs to help address them (if I can find the time).

  1. The above PR only partially addresses the restricted values issue. First, it only references the problem for this one endpoint, while surely there are other endpoints where there are similarly restricted values. Second, it does not exhaustively identify which values have access restrictions.

  2. Some values are not returned if they are empty, false, or 0 (zero). But this behaviour isn’t consistently applied, and only affects some values, not all. This behaviour also needs to be documented somewhere.

  3. The combination of 1 and 2 means that the meaning of the API not returning a value is ambiguous, which is a problem of its own. Client code will need to guess about whether an omitted value is falsy, or whehter it actually has a value that the code isn’t able to retrieve.

  4. It’s not entirely clear to me that there aren’t other reasons why a value might not be returned. For example, what if a value applies to a feature that the server license doesn’t support? The fact that documenting this hasn’t been a priority, combined with item 2 being inconsistently applied, make it hard to trust that there aren’t other reasons for values being optional hiding in the code somewhere.