# Vault and metadata structure

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

HTML version: https://developer.m-files.com/APIs/gRPC-API/concepts/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](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCLogin/LogIn/index.md)) and the session carries it.

## The building blocks

```text
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](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCObjectTypes/GetObjectTypes/index.md). Each is a
  [ValueList](https://developer.m-files.com/APIs/gRPC-API/Reference/Messages/MFiles.ValueList/index.md) message with `is_real_object_type` true. `options`
  ([OBJTYPEFLAGS](https://developer.m-files.com/APIs/gRPC-API/Reference/Messages/MFiles.OBJTYPEFLAGS/index.md)) 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](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCValueLists/GetValueLists/index.md). 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](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCPropertyDefs/GetObjectClassesAndGroups/index.md). An
  [ObjectClass](https://developer.m-files.com/APIs/gRPC-API/Reference/Messages/MFiles.ObjectClass/index.md) names its `object_type`, its
  `associated_property_defs` (each with `is_required`), the `name_property_def` that supplies
  the object's title, and its `default_workflow` (`force_workflow` makes 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](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCPropertyDefs/GetPropertyDefs/index.md). A
  [PropertyDef](https://developer.m-files.com/APIs/gRPC-API/Reference/Messages/MFiles.PropertyDef/index.md) has a `data_type`
  ([Datatype](https://developer.m-files.com/APIs/gRPC-API/Reference/Enums/MFiles.Datatype/index.md)); a lookup property also has `value_list`, the value list
  or object type it points to. `update_type` `UPDATE_TYPE_SET_BY_SERVER` marks values that the
  server maintains and callers do not set. See [Properties and values](https://developer.m-files.com/APIs/gRPC-API/concepts/properties-and-values/index.md).
- **Workflows and states** are metadata too: an object's workflow and state are lookup
  properties 38 and 39. See [Workflows](https://developer.m-files.com/APIs/gRPC-API/concepts/workflows/index.md).

## 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](https://developer.m-files.com/APIs/gRPC-API/Reference/Messages/MFiles.ObjID/index.md) (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 (`guid` in
  [ValueList](https://developer.m-files.com/APIs/gRPC-API/Reference/Messages/MFiles.ValueList/index.md), [PropertyDef](https://developer.m-files.com/APIs/gRPC-API/Reference/Messages/MFiles.PropertyDef/index.md) and
  [ItemInfo](https://developer.m-files.com/APIs/gRPC-API/Reference/Messages/MFiles.ItemInfo/index.md)).
  [GetMetadataStructureItemIdByGUID](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCVault/GetMetadataStructureItemIdByGUID/index.md)
  resolves one: `item_type` `METADATA_STRUCTURE_ITEM_OBJECT_TYPE` with the Customer GUID returns
  `is_found` true and `id` 136.
- **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 as `PropertyDefAdmin.aliases`.
  - [GetMetadataStructureItemIdByAlias](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCVault/GetMetadataStructureItemIdByAlias/index.md)
    resolves one alias of one [MetadataStructureItem](https://developer.m-files.com/APIs/gRPC-API/Reference/Enums/MFiles.MetadataStructureItem/index.md) 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](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCVault/GetAllMetadataStructureItemIdswithAliases/index.md)
    returns all alias-to-ID mappings in one call (`METADATA_STRUCTURE_ITEM_ALL` for every type).
    Set `unambiguous_aliases_only` to true: false fails with "Not implemented."
  - The Sample Vault defines no aliases; both methods return nothing there.

Resolve aliases and GUIDs once, and cache the IDs as described in
[Metadata structure version and caching](https://developer.m-files.com/APIs/gRPC-API/concepts/metadata-structure-version-and-caching/index.md).

## Reading the structure

| To get | Call |
| --- | --- |
| Object types | [GetObjectTypes](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCObjectTypes/GetObjectTypes/index.md) |
| Value lists and object types | [GetValueLists](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCValueLists/GetValueLists/index.md) |
| Items of a value list | [GetValueListItemsWithPermissions](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCValueLists/GetValueListItemsWithPermissions/index.md) |
| Property definitions | [GetPropertyDefs](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCPropertyDefs/GetPropertyDefs/index.md) |
| Classes and class groups | [GetObjectClassesAndGroups](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCPropertyDefs/GetObjectClassesAndGroups/index.md) |
| Workflows, states, transitions | [GetWorkflowsForClient](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCObjectOperations/GetWorkflowsForClient/index.md), [GetWorkflowStatesAndTransitions](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCObjectOperations/GetWorkflowStatesAndTransitions/index.md) |
| Named ACLs | [GetNamedACLs](https://developer.m-files.com/APIs/gRPC-API/Reference/MFiles.IRPCNamedACLs/GetNamedACLs/index.md) |

Some of these responses depend on the caller: they carry the caller's permissions, for example
`ObjectClass.current_user_permissions`.
