Vault and metadata structure
An M-Files vault is not a file system. It is a database of objects (documents, customers, projects, ...) described by metadata. Folders are views computed from metadata, files belong to objects, and the meaning of every number in a request depends on which ID space it belongs to. Read this page before writing code that creates, searches or updates objects.
All calls run inside one vault: the vault is chosen at login (LoginData.vault_guid in
LogIn) and the session carries it.
The building blocks
Vault
|-- Object types and value lists one ID space; read with GetObjectTypes / GetValueLists
| |-- 0 Document, 136 Customer, ... real object types: objects with versions
| '-- 1 Classes, 6 Users, 154 Countries value lists: items without versions
|-- Classes items of value list 1; each belongs to one object type
| '-- associated property definitions (required or optional), default workflow
|-- Property definitions 0 Name or title, 100 Class, 1002 Document date, ...
'-- Workflows (value list 7) -> states (value list 8) -> state transitions (value list 17)
Object = object type + ID; each version has a class (property 100) and property values
- Object types are the kinds of things the vault stores. Read them with
GetObjectTypes. Each is a
ValueList message with
is_real_object_typetrue.options(OBJTYPEFLAGS) says, for example, whether its objects can have files (can_have_files, true for documents). - Value lists are lists of simple items, such as Countries or Users. Read them with GetValueLists. It returns the real object types too, because object types and value lists are the same kind of thing and share one ID space: an object type is a value list whose items are full objects.
- Owners. A value list or object type can have an owner (
owner_object_type): in the Sample Vault, Contact person (149) is owned by Customer (136), and Workflow States (8) are owned by Workflows (7). - Classes subdivide an object type. Every object version has exactly one class, stored in
property 100 (Class), a lookup to value list 1. Read them with
GetObjectClassesAndGroups. An
ObjectClass names its
object_type, itsassociated_property_defs(each withis_required), thename_property_defthat supplies the object's title, and itsdefault_workflow(force_workflowmakes it mandatory). - Class groups (value list 2) group classes for display only. Property 101 lists them.
- Property definitions define the fields. Read them with
GetPropertyDefs. A
PropertyDef has a
data_type(Datatype); a lookup property also hasvalue_list, the value list or object type it points to.update_typeUPDATE_TYPE_SET_BY_SERVERmarks values that the server maintains and callers do not set. See Properties and values. - Workflows and states are metadata too: an object's workflow and state are lookup properties 38 and 39. See Workflows.
The ID spaces
Most IDs in the API are plain int32 values, and the same number means different things in
different spaces. Mixing them up is the most common mistake.
| ID space | Where it appears | Example in the Sample Vault |
|---|---|---|
| Object type / value list ID | ObjID.type, ValueList.id, PropertyDef.value_list |
136 = Customer |
| Object ID, per object type | ObjID.item_id.internal_id |
customer 142, document 142 |
| Value list item ID, per value list | ItemInfo.obj_id.item_id in lookups |
country 1 = USA |
| Class ID (items of value list 1) | property 100, ObjectVersion.class_id |
78 = Customer |
| Property definition ID | PropertyValue.property_def, search expressions |
1079 = Customer |
| Workflow, state, transition IDs | items of value lists 7, 8 and 17 | workflow 106, state 135 |
| User and user group IDs | items of value lists 6 and 16 | group 1 = All internal users |
| Version number, per object | ObjVerVersion.internal_version |
version 3 |
Two traps from the table:
- "Customer" is three different IDs. In the Sample Vault, object type Customer is 136, the class Customer is 78, and the property definition Customer (a multi-select lookup to object type 136) is 1079. A search for documents of a customer uses property 1079 with a lookup to object 141 of type 136.
- Object IDs are unique only within an object type. A search for object ID 142 without an object type returns both document 142 and customer 142. Always carry the full ObjID (type and ID).
Built-in IDs
These IDs are the same in every vault. Everything else, including every ID of 1000 or more seen in the Sample Vault, is assigned when the item is created and can differ between vaults: resolve it by alias or GUID (below) instead of hard-coding it.
| Object type / value list | ID |
|---|---|
| Document (object type) | 0 |
| Classes | 1 |
| Class groups | 2 |
| Users | 6 |
| Workflows / Workflow states / State transitions | 7 / 8 / 17 |
| Document collection / Assignment / Report (object types) | 9 / 10 / 15 |
| User groups | 16 |
| Property definition | ID | Data type |
|---|---|---|
| Name or title | 0 | text |
| Created / Last modified | 20 / 21 | timestamp, set by the server |
| Single file | 22 | Boolean |
| Last modified by / Created by | 23 / 25 | lookup to Users |
| Deleted / Deleted by | 27 / 28 | set by the server |
| Comment (version comment) | 33 | multi-line text |
| Workflow / Workflow State | 38 / 39 | lookup to value list 7 / 8 |
| Moved into current state | 40 | timestamp, set by the server |
| Assigned to | 44 | multi-select lookup to Users |
| State transition | 99 | lookup to value list 17 |
| Class / Class groups | 100 / 101 | lookup to value list 1 / 2 |
Built-in classes include 0 (Document, the unclassified document), 1 (Other Document), -100 (Assignment) and -101 (Report). Built-in named ACL -1 is "Full control for all internal users"; user group 1 is "All internal users".
Aliases and GUIDs
Code that must work in more than one vault identifies structure items by alias or GUID and resolves them to IDs at run time.
- GUIDs. Every object type, property definition and value list item has a GUID (
guidin ValueList, PropertyDef and ItemInfo). GetMetadataStructureItemIdByGUID resolves one:item_typeMETADATA_STRUCTURE_ITEM_OBJECT_TYPEwith the Customer GUID returnsis_foundtrue andid136. - Aliases are names an administrator gives to structure items, for example
MyCompany.Property.InvoiceNumber. They are stored as a semicolon-separated list in the admin structures, such asPropertyDefAdmin.aliases.- GetMetadataStructureItemIdByAlias
resolves one alias of one MetadataStructureItem type.
Matching ignores case and surrounding spaces. It returns
id-1 when no item, or more than one item, has the alias; for named ACLs it returns -1000 instead, because -1 is a real named ACL. - GetAllMetadataStructureItemIdswithAliases
returns all alias-to-ID mappings in one call (
METADATA_STRUCTURE_ITEM_ALLfor every type). Setunambiguous_aliases_onlyto true: false fails with "Not implemented." - The Sample Vault defines no aliases; both methods return nothing there.
- GetMetadataStructureItemIdByAlias
resolves one alias of one MetadataStructureItem type.
Matching ignores case and surrounding spaces. It returns
Resolve aliases and GUIDs once, and cache the IDs as described in Metadata structure version and caching.
Reading the structure
| To get | Call |
|---|---|
| Object types | GetObjectTypes |
| Value lists and object types | GetValueLists |
| Items of a value list | GetValueListItemsWithPermissions |
| Property definitions | GetPropertyDefs |
| Classes and class groups | GetObjectClassesAndGroups |
| Workflows, states, transitions | GetWorkflowsForClient, GetWorkflowStatesAndTransitions |
| Named ACLs | GetNamedACLs |
Some of these responses depend on the caller: they carry the caller's permissions, for example
ObjectClass.current_user_permissions.