Call metadata
Part of the M-Files call contract is not in any message: it travels in gRPC metadata (HTTP/2
headers and trailers). In short: send mfiles-session-id-bin (the session ID from LogIn),
mfiles-activity-id-bin (16 random bytes) and mfiles-is-remote-call: true on every call, keep
cookies on M-Files Cloud, and read the error and metadata structure version trailers from the responses.
This page lists every key.
Binary keys
Keys that end in -bin carry bytes. gRPC libraries base64-encode them on the wire and decode them
for you, so pass and read raw bytes:
| Language | Sending mfiles-session-id-bin |
|---|---|
| Python | metadata=[("mfiles-session-id-bin", session_id_bytes)] |
| Go | metadata.Pairs("mfiles-session-id-bin", string(sessionID)) |
| C# | new Metadata { { "mfiles-session-id-bin", sessionIdBytes } } |
The server reads a key only when it occurs exactly once in the call. A key sent twice counts as missing.
Request metadata
| Key | Value | When to send |
|---|---|---|
mfiles-session-id-bin |
The 48 bytes of session_data.session_id from LogIn, unchanged |
Every call that needs a session. See Authentication and sessions. |
mfiles-activity-id-bin |
16 bytes, a new random GUID per call | Recommended on every call. |
mfiles-is-remote-call |
true |
Always. |
cookie |
The cookies the server set, name=value; name2=value2 |
Every call, once the server has set any. See below. |
x-mf-session-assertion |
A session assertion | Not for third-party callers; see Authentication. |
mfiles-session-id-bin. Missing, unknown or expired: UNAUTHENTICATED. A value that is not
48 bytes long is rejected: on a plain endpoint with UNKNOWN and E_INVALIDARG ("The parameter
is incorrect."), on a TLS endpoint with UNAUTHENTICATED. Methods that need no session ignore it.
mfiles-activity-id-bin. Identifies the call in the server's logs and traces, so support can
find it. The server reads it only from calls that carry a session ID. Optional, but if you send it,
it must be exactly 16 bytes: other lengths fail with E_INVALIDARG. M-Files' clients send a new
GUID for every call; log it on your side to correlate.
mfiles-is-remote-call. Tells the server that the caller is not one of its own local
processes. Send true on every call; the server checks only that the key is present.
Not read. MFServer reads no other request metadata. In particular, W3C trace context
(traceparent) is not used; correlate with mfiles-activity-id-bin.
Response metadata
| Key | Where | Value |
|---|---|---|
mfiles-metadata-version-bin |
Trailer, successful calls of methods that report it | The vault's metadata structure version: 4 bytes, little-endian signed 32-bit integer |
mfiles-error-text-bin |
Trailer, failed calls | UTF-8 text of the server-side error stack. See Errors. |
mfiles-error-serialized-bin |
Trailer, failed calls | A serialized RPCErrorInfoArray. See Errors. |
set-cookie |
Header, M-Files Cloud | For example mfilesmsm=69621a771a22b419; Path=/; Max-Age=172800; Secure; SameSite=None |
mfiles-metadata-version-bin. Methods marked returns_metadata_structure_version in the reference
(for example GetObjectTypes) return it on success.
The bytes 00 04 00 00 are version 1024. The version changes when the vault's metadata structure
(object types, value list definitions, classes, property definitions and so on) changes; it does
not change when objects or value list items change. A failed call has no such trailer.
Metadata structure version and caching lists which results
are safe to cache by this version.
An on-premises server sends no response headers of its own; everything else is in trailers.
Cookies and stickiness
M-Files Cloud puts a front end in front of the server, and a vault can be served by more than one
server instance. The front end sets the cookie mfilesmsm on its responses to pin a client to
one instance:
- A new connection without the cookie gets one; different connections can get different values.
- A call that sends a valid
mfilesmsmback gets no newset-cookie. - An unknown value is replaced with a new cookie.
Keep cookies like a browser: store set-cookie values from response headers and send them in a
cookie header on every later call of the same session. M-Files' own clients do this for every
call. Multi-step file transfers depend on it, because their upload and download sessions exist only
in the server process that created them (see Files). The cookie lasts 48 hours
(Max-Age=172800).
gRPC libraries do not keep cookies themselves; add an interceptor that reads the response headers
and adds the cookie header.
Deadlines and cancellation
Set a deadline (timeout) on every call; without one, a call to a stalled connection waits forever.
The server does not stop a unary call when its deadline passes or the client cancels it: the call
runs to completion and only its result is lost. Verified: an AddObjectWithFiles call with a
5 ms deadline returned DEADLINE_EXCEEDED to the client, and the object was created anyway.
Therefore:
- After
DEADLINE_EXCEEDEDorCANCELLEDon a call that changes data, the outcome is unknown. Read the current state before you retry. - Methods marked
idempotency_level = IDEMPOTENTin the.protocan be retried as they are.
Call importance
Some request messages have a CallImportance field (callimp or
call_importance). Leave it at CALL_IMPORTANCE_DEFAULT or set CALL_IMPORTANCE_NORMAL: such
calls are never rejected for load. With CALL_IMPORTANCE_CAN_BE_REJECTED the server refuses the
call with E_MFILES_CALL_REJECTED ("The server is too busy to process the request at this time.")
while it is serving more requests than its limit (by default the number of logical processors of
the server machine). Use it for background work such as prefetching, and try again later when it
is rejected.