Call metadata

View as Markdown

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:

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:

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.