# Versions and compatibility

Location: [gRPC API](https://developer.m-files.com/APIs/gRPC-API/index.md) > [Runtime conventions](https://developer.m-files.com/APIs/gRPC-API/index.md#runtime)

HTML version: https://developer.m-files.com/APIs/gRPC-API/runtime/versioning/

One published bundle of `.proto` files works against servers of many versions. The API grows by
addition, and the server tells you what it supports.

## How the API changes

The gRPC API is the API that the M-Files clients themselves use, so it evolves with the product.
Almost all changes are additions that follow the [compatibility rules](#compatibility-rules)
below, and code written for one version usually keeps working with newer servers. M-Files may
also change the API in other ways as the product evolves, including deprecating and removing
methods. Methods documented as "For M-Files components only" are internal and can change without
notice.

To see what a new version changes, compare its bundle with the one you built against: a diff of
the `.proto` files shows the added, changed and removed methods and fields, and a coding agent can
update your code from it.

## What the server tells you

[QueryVersion](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCQueryVersion/QueryVersion/index.md) (anonymous) returns packed 64-bit
versions, 16 bits each for major, minor, build and revision
([Connecting](https://developer.m-files.com/APIs/gRPC-API/runtime/connecting/index.md#is-the-server-reachable) shows the decoding):

| Field | Example | Meaning |
|---|---|---|
| `server_version` | 7318397729964032 = 26.11.16645.0 | The server's version. |
| `oldest_compatible_client_version` | 5348033629585408 = 19.2.7357.0 | The oldest client version that the server currently accepts. |
| `oldest_compatible_admin_client_version` | 19.2.7357.0 | The same for administrative clients. |
| `oldest_compatible_replica_server_version` | 19.2.7357.0 | The same for replica servers. |

[GetServerCapabilities](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCLogin/GetServerCapabilities/index.md) (anonymous) returns
[ServerVaultCapabilities](https://developer.m-files.com/APIs/gRPC-API/Reference/Messages/MFiles.ServerVaultCapabilities/index.md): one boolean per optional feature
(for example `search_results_sorting`, `vault_login_accounts`). A feature is available when its
flag is true; a flag that the server's version does not know arrives as false. After login,
`session_data.server_vault_capabilities` gives the same flags for the server and the vault.

Prefer capability flags to version comparisons where a flag exists. Use `server_version` for
behavior that has no flag, and to report the server version in your logs.

## What you tell the server

[ClientData](https://developer.m-files.com/APIs/gRPC-API/Reference/Messages/MFiles.ClientData/index.md) goes with [LogIn](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCLogin/LogIn/index.md):

| Field | Send |
|---|---|
| `type` | `CLIENT_TYPE_SERVER_API` for a service or script; it is recorded with the session. |
| `version` | Optional. A packed version, as in `QueryVersion`: the version of the server that the bundle you generated your stubs from was published for, for example 26.11.0.0. |
| `capabilities` | [ClientCapabilities](https://developer.m-files.com/APIs/gRPC-API/Reference/Messages/MFiles.ClientCapabilities/index.md): set a flag only for a newer behavior your code handles. Unset flags keep the server's older behavior. |
| `language` | The language for server texts, for example `en`. |

Why `version` matters: some administrative operations check it and refuse clients that report an
older version (or none) with an "operation not supported by old client" error, and an
administrator can make the server refuse logins from clients older than a configured version
(`E_MFILES_INCOMPATIBLE_SERVER_VERSION`). A login with `version` unset works on a server with
default settings.

## Compatibility rules

M-Files evolves the gRPC contract by these rules. They describe current practice and what the
product aims for, not a guarantee:

* **Methods are bound by name** (`/MFiles.<Service>/<Method>`). New methods are added; existing
  ones keep their names. Calling a method that the server does not have fails with
  `UNIMPLEMENTED`, so a client built from a newer bundle generally works against an older server
  as long as it does not call newer methods.
* **Fields are bound by number.** New fields get new numbers. Field numbers are not reused, and
  fields keep their names (the mf-http-grpc gateway binds by name; see
  [HTTP access](https://developer.m-files.com/APIs/gRPC-API/runtime/http-access/index.md)).
* **Unknown fields are ignored.** Protobuf skips fields it does not know, so an older server
  ignores a newer field you set, and your client ignores fields a newer server adds.
* **Missing fields have default values**: empty string, zero, false, the enum's zero value, or an
  unset message. New fields are defined so that the default keeps the old behavior. Where a
  difference matters, a capability flag tells the two sides apart.
* **Enums can grow.** Handle enum values your code does not know (proto3 keeps them as numbers).
* **A changed method keeps its name.** When a method needs new parameters, its request message
  gets new fields under the rules above. Where that is not enough, a new method is added and the
  old one is marked as superseded. Superseded methods are left out of the published bundle and
  can later be removed from the server.

## The published bundle and server versions

The bundle is generated from the server's interface definitions and is named after the server
version it comes from (for example `26.11`). Its wire contract is identical to what that server
serves. Against an older server, the methods and fields added after that server's version are
missing: methods answer `UNIMPLEMENTED`, fields are ignored or arrive with default values. Check
`server_version` or the capability flags before using a recent feature on a server you do not
control, such as an on-premises installation.
