MDL Overview

Use MDL (Metadata Definition Language) to manage Vault configuration. Like DDL (Data Definition Language) in databases, you can use MDL to create, describe (read), update, and drop (delete) Vault components that make up its configuration.

Although MDL is a powerful tool used for manipulating components programmatically, its primary use is in cases where certain tasks need to be automated. While MDL mimics the behavior of Vault’s UI, it is not intended to use as a de-facto way for basic configuration tasks or maintenance on an ongoing basis. To manage most standard configuration tasks, use the Admin UI.

MDL Commands

MDL uses CRUD-like commands to manage components for vault. You can use the CREATE, RECREATE, RENAME, ALTER, and DROP commands to manage Vault configuration components in a similar way that Vault’s REST API manages data objects. Learn more in the MDL Commands documentation.

Vault Components

MDL provides access to component types, which are the configuration elements of a vault. Vault groups component types by either metadata types (Picklist, Object, Docfield, etc.) which manage the configuration of a vault, and code types (Recordtrigger, Documentaction, Recordaction, and Userdefinedclass) which extend the functional behavior of a vault.

See Component Type References for details of each MDL supported Vault component type.

Localization

By default, MDL executes in the context of Vault’s base language. Vault Admins manage localizable attributes, including Java SDK custom Messages, using Vault’s translation tools.

Getting Started

While Vault’s REST APIs allow developers to manage Vault data, you can use Vault’s MDL API to modify metadata and manage configurations for Vault.

This tutorial walks through the process of using MDL to modify configuration in Vault. You’ll use MDL to do the following:

To use and test out MDL, we recommend downloading our Postman collection and using a sandbox vault, which is a copy of your production vault. Learn more about Vault Sandboxes in Vault Help.

This collection allows you to execute the basic commands laid out in the steps below and verify the results in your vault. Click the button below to import the collection into Postman.

Run in Postman

Execute MDL Commands

To execute a MDL command, send a POST request to the Execute MDL Script endpoint.

$ curl -X POST -H "Authorization: {SESSION_ID}" \
-H "Content-Type: application/json" \
--data-binary @"mdl.txt" \
https://myvault.veevavault.com/api/mdl/execute

You can execute MDL commands one at a time or in a script. When executed as a script, MDL executes each command sequentially.

Note: Even when executing MDL commands in a script, MDL does not support transactionality.

Step 1: Create a Picklist

You’ll first need to create a Picklist for your vault. The following example creates a single Picklistentry in the Picklist component. Learn more about the MDL Picklist component.

  1. To create a picklist named vMDL Options, enter the following RECREATE command:

    RECREATE Picklist vmdl_options__c (
    label('vMDL Options'),
    active(true),
    Picklistentry hello_world__c(
      value('hello world'),
      order(0),
      active(true)
    )
    );
    
  2. Navigate to Admin > Business Admin > Picklists to confirm that the vMDL Options picklist exists in your Vault.

Step 2: Create an Object

Now that you’ve creted a Picklist, you’re ready to create a Vault Object that uses the picklist. Learn more about the MDL Object component.

  1. Enter the following RECREATE command:

    RECREATE Object vmdl_hello_world__c (
    label('vMDL Hello World'),
    label_plural('vMDL Hello World'),
    active(true),
    description("This is sample object created for the MDL 'Getting Started' guide."),
    help_content(),
    in_menu(true),
    allow_attachments(false),
    enable_esignatures(false),
    audit(false),
    order(0),
    dynamic_security(false),
    system_managed(false),
    available_lifecycles(),
    object_class('base'),
    allow_types(false),
    user_role_setup_object(),
    Field option__c(
      label('Option'),
      type('Picklist'),
      active(true),
      required(false),
      unique(false),
      list_column(false),
      order(14),
      multi_value(false),
      picklist('Picklist.vmdl_options__c'))
    );
    
  2. Log in to your vault.

  3. Navigate to Admin > Business Admin to confirm that the vMDL Hello World object exists in your Vault.

Step 3: Create an Object Record

Now that you’ve created the necessary components, you’ll want to create a vMDL Hello World object record in your vault.

You can do this with the Postman collection or manually in the Admin UI.

  1. Log into your vault.

  2. Navigate to Admin > Business Admin > vMDL Hello World.

  3. Click Create.

  4. Enter a Name for the object record.

  5. Select hello world from the Option picklist.

  6. Click Save.

Step 4: Alter the Object and Picklist

Next, you’ll use a single statement to modify both the Object and Picklist simultaneously.

  1. Enter an ALTER command to add a second picklist entry and modify the initial entry. You should manually enter a value before running the MDL command for the new picklist entry’s value.

    ALTER Picklist vmdl_options__c (
    label('vMDL Options'),
    MODIFY Picklistentry hello_world__c(
      value('Hello World.'),
      order(0)
    ),
    ADD Picklistentry hello_worldv2__c(
      value('ENTER ANY VALUE'),
      order(1),
      active(true)
    )
    );
    


  2. Use the ALTER command to add four new object fields.

    ALTER Object vmdl_hello_world__c (
    ADD Field hello1__c(
      label('Hello 1'),
      type('String'),
      active(true),
      required(false),
      list_column(false),
      unique(false),
      order(0)),
    ADD Field hello2__c(
      label('Hello 2'),
      type('String'),
      active(true),
      required(false),
      list_column(false),
      unique(false),
      order(0)),
    ADD Field hello3__c(
      label('Hello 3'),
      type('String'),
      active(true),
      required(false),
      list_column(false),
      unique(false),
      order(0)),
    ADD Field hello4__c(
      label('Hello 4'),
      type('String'),
      active(true),
      required(false),
      list_column(false),
      unique(false),
      order(0))
    );
    

Step 5: Create an Object Record with New Fields

Return to your vault to create a new vMDL Hello World record. You will see the new picklist entry options as well as the four new fields on the object record.

You can do this with the Postman collection or manually in the Admin UI.

  1. Log into your vault.

  2. Navigate to Admin > Business Admin > vMDL Hello World.

  3. Click Create.

  4. Fill in the record information: Name, Hello 1 - 4, and Options fields.

  5. Click Save.

Step 6: Delete the Object Records

Now that you have created vMDL Hello World records with the original and altered fields, you can delete the object records.

  1. Log in to your vault.

  2. Navigate to Admin > Business Admin > vMDL Hello World.

  3. From the Actions menu, click Delete.

Step 7: Drop Picklist and Object Components

To delete both the object and picklist components, use the DROP command. Note that you must delete the object records to delete the components.

DROP Object vmdl_hello_world__c;
DROP Picklist vmdl_options__c;

Common Uses

Use MDL when Vault requires configuration changes across multiple components. Since you can implement MDL commands in a script, you can either execute multiple commands sequentially or within a single script.

See some of the common use cases below:

Project Description
Alter multiple components Use the ALTER command to manipulate multiple components such as Object field values, Picklist values, Docfields, or Notificationtemplates
Migrate Component Configuration Automate migration or synchronization of specific components programmatically.
Access Control Use the the MDL commands to automatically manage security related components such as Atomicsecurityand Sharingrule.

Alter Multiple Components

This example walks through updating the subject attribute on multiple Notification Templates. The Notificationtemplate MDL components contain the subject attribute. We can update it across multiple components at once by executing the following MDL commands:

Request

curl -X POST \
  https://test.veevavault.com/api/mdl/execute \
  -H 'Accept: application/json' \
  -H 'Authorization: {vaultSessionId}' \
  -d 'ALTER Notificationtemplate my_template1__c (
   subject('\''Subject 1"'\'')
);

ALTER Notificationtemplate my_template2__c (
   subject('\''Subject 2"'\'')
);'

Response

{
    "responseStatus": "SUCCESS",
    "script_execution": {
        "code": "GEN-S-0",
        "message": "OK",
        "warnings": 0,
        "failures": 0,
        "exceptions": 0,
        "components_affected": 1,
        "execution_time": 0.065
    },
    "statement_execution": [
        {
            "vault": "test.veevavault.com",
            "statement": 1,
            "command": "ALTER",
            "component": "Notificationtemplate.my_template1__c",
            "message": "[SUCCESS] ALTER Notificationtemplate my_template1__c",
            "response": "SUCCESS"
        },
        {
            "vault": "test.veevavault.com",
            "statement": 2,
            "command": "ALTER",
            "component": "Notificationtemplate.my_template2__c",
            "message": "[SUCCESS] ALTER Notificationtemplate my_template2__c",
            "response": "SUCCESS"
        }
    ]
}

The execution response produces both script level execution details as well as statement level details. If an error occurs, the detailed report of errors will also appear in the result. Everything before the error will have succeeded and be available in the vault; everything after will not run.

Migrate Component Configuration

Vault’s Admin UI provides a very robust way for configuration migration using VPK packages. However, it may be necessary to automate migration or synchronization of certain components programmatically. For successful migration, it is necessary to first describe the component on the source vault and generate a RECREATE command. You can execute this command on the target vault.

Let’s again use Notification Template as an example. We will migrate my_template1__c from a source vault to a target vault.

First generate a RECREATE command on a source vault. Ensure that the session ID used to authenticate the API call is generated by authenticating to the source vault.

Request

curl -X GET \
  https://{sourceVault}.veevavault.com/api/mdl/components/Notificationtemplate.my_template_1__c \
  -H 'Accept: application/json' \
  -H 'Authorization: {sourceVaultSessionId}' 

This generates a RECREATE command for Notificationtemplate.my_template_1__c

RECREATE Notificationtemplate my_template_1__c (
   label('My Template 1'),
   active(true),
   description(),
   referenced_component(),
   subject('My Subject'),
   notification('My notification test'),
   email_body('My email body'),
   entity_type('document')
);

You can then execute this command on the target vault using the session ID generated from authenticating to the target vault.

curl -X POST \
  https://{targetVault}.veevavault.com/api/mdl/execute \
  -H 'Accept: application/json' \
  -H 'Authorization: {sourceVaultSessionId}' \
  -d 'RECREATE Notificationtemplate my_template_1__c (
   label('My Template 1'),
   active(true),
   description(),
   referenced_component(),
   subject('My Subject'),
   notification('My notification test'),
   email_body('My email body'),
   entity_type('document')
);'

Access Control

For access control, you can automatically create, update, and delete various security related components. You can use the MDL to configure this programmatically by writing code to retrieve information from a vault and apply the changes.

This is useful when it’s necessary to generate or manage a large number of security components within a vault or between vaults. If you only need to modify a single object or document’s security, use the Admin UI functionality. This example walks through managing the Atomicsecurity component to hide system fields, such as Created Date and Last Modified Date, from users in the Viewer role while granting Read access on system fields for all other roles. We will configure this same behavior across all objects and lifecycle states and modify the following on a single object:

RECREATE Atomicsecurity component_name__c (
   label('Test Object 1-Test Object Lifecy-Active'),
   active(true),
   object('Object.test_object_1__c'),
   object_lifecycle('Objectlifecycle.test_object_lifecycle_lifecycle__c'),
   state('Objectlifecyclestate.active_state__c'),
   Fieldsecurity viewer__v.hide__v.field_security__c(
      label('Viewer-Hide'),
      active(true),
      role('Objectlifecyclerole.viewer__v'),
      type('hide__v'),
      fields('Field.created_by__v',
         'Field.created_date__v',
         'Field.modified_by__v',
         'Field.modified_date__v')
   )
);

RECREATE Atomicsecurity component_name (
   label('Test Object 1-Test Object Lifecy-Inactive'),
   active(true),
   object('Object.test_object_1__c'),
   object_lifecycle('Objectlifecycle.test_object_lifecycle_lifecycle__c'),
   state('Objectlifecyclestate.inactive_state__c'),
   Fieldsecurity viewer__v.hide__v.field_security__c(
      label('Viewer-Hide'),
      active(true),
      role('Objectlifecyclerole.viewer__v'),
      type('hide__v'),
      fields('Field.created_by__v',
         'Field.created_date__v',
         'Field.modified_by__v',
         'Field.modified_date__v')
   )
);

RECREATE Atomicsecurity component_name (
   label('Test Object 1-Test Object Lifecy-Test'),
   active(true),
   object('Object.test_object_1__c'),
   object_lifecycle('Objectlifecycle.test_object_lifecycle_lifecycle__c'),
   state('Objectlifecyclestate.test_state__c'),
   Fieldsecurity viewer__v.hide__v.field_security__c(
      label('Viewer-Hide'),
      active(true),
      role('Objectlifecyclerole.viewer__v'),
      type('hide__v'),
      fields('Field.created_by__v',
         'Field.created_date__v',
         'Field.modified_by__v',
         'Field.modified_date__v')
   )
);

MDL Commands

If you’re familiar with commands used in DDL (Data Definition Language), you should recognize MDL commands since they share some of the same imperative verb commands: CREATE, DROP, ALTER, etc. With DDL, you typically use these commands to manage database tables. With MDL, the same general idea applies for adding, changing, or deleting components to modify Vault’s configuration metadata.

CREATE

create_statement = 
  "CREATE" component_type_name component_name "("
    [ { create_definition "," } ] create_definition   
    [ { sub_component_create_statement "," } ] sub_component_create_statement
");";

sub_component_create_statement = 
  sub_component_type_name [ component_name "."] sub_component_name "("
    [ { create_definition "," } ] create_definition
  ")";

create_definition =
  attrbitute_name "(" attribute_value ")";

The CREATE command creates an MDL component in Vault. The name must be unique and the command fails if the another record in that component already exists with the same name.

If a component type allows for sub-components, you can create the sub-components as part of the same command.

CREATE Mycomponent my_comp__c (
  my_bool_attribute(true),
  my_num_attribute(5),

  Mysubcomponent my_subcomp__c (
    my_bool_attribute(true),
    my_num_attribute(5)
  ) 
);

RECREATE

recreate_statement =
    "RECREATE" component_type_name component_name "("
        [ { create_definition "," } ] create_definition     
        [ { sub_component_create_statement "," } ] sub_component_create_statement
");";

sub_component_create_statement =
    sub_component_type_name [ component_name "."] sub_component_name "("
        [ { create_definition "," } ] create_definition
    ")";

create_definition =
    attrbitute_name "(" attribute_value ")";  

The RECREATE is an upsert command that either creates or alters an MDL component in Vault. RECREATE will create a new component if it doesn’t already exist or will alter a component if the component with the same name already exists.

If a component type allows for sub-components, the sub-components can be recreated as part of the same command.

RECREATE Mycomponent my_comp__c (
  my_bool_attribute(true),
  my_num_attribute(5),

  Mysubcomponent my_subcomp__c (
    my_bool_attribute(true),
    my_num_attribute(5)
  ) 
);

Upon any failure, Vault returns detailed error messages.

DROP

drop_statement = 
  "DROP" component_type_name component_name ";";

The DROP command deletes the component type from vault.

DROP Mycomponent my_comp__c;

Upon any failure, Vault returns detailed error messages.

RENAME

rename_statement = 
  "RENAME" component_type_name from_component_name "TO" to_component_name ";";

The RENAME command renames the component. You can only rename custom components, component with a in a __c, namespace such as my_product__c. The command returns an error if a component with the same name already exists.

RENAME Mycomponent my_comp__c TO my_new_comp__c;

Upon any failure, Vault returns detailed error messages.

ALTER

alter_statement = 
  "ALTER" component_type_name component_name "("
    alter_body | 
rename_subcomponent_body | 
modify_subcomponent_body | 
add_subcomponent_body | 
drop_subcomponent_body      
");";

alter_body =
[ { add_drop_attribute_definition "," } ] add_drop_attribute_definition;

rename_subcomponent_body =
  "RENAME" subcomponent_type_name [ component_name "."] from_subcomponent_name 
"TO" [ component_name "."] to_subcomponent_name ";";

modify_subcomponent_body =
  "MODIFY" subcomponent_type_name [ component_name "."] subcomponent_name "("
    [ { add_drop_attribute_definition "," } ] add_drop_attribute_definition     
");";

add_subcomponent_body =
  "ADD" subcomponent_type_name [ component_name "."] subcomponent_name "("
    [ { attribute_definition "," } ] attribute_definition     
");";

drop_subcomponent_body =
  "DROP" subcomponent_type_name [ component_name "."] subcomponent_name ";";

add_drop_attribute_definition =
  attrbitute_name [ADD | DROP] "(" attribute_value ")";

attribute_definition =
  attrbitute_name "(" attribute_value ")";

The ALTER command modifies an MDL component in Vault.

If a component allows for sub-components, you can ADD, MODIFY, or DROP the sub-components as part of the same command.

ALTER Mycomponent my_comp__c (
  my_bool_attribute(true),
  my_num_attribute(5),
  my_multi_value_attribute ADD (5, 6),
  my_multi_value_attribute DROP (8),

  ADD Mysubcomponent my_subcomp__c (
    my_bool_attribute(true),
    my_num_attribute(5)
  ),
  DROP Mysubcomponent my_subcomp2__c;

MODIFY Mysubcomponent my_subcomp3__c (
    my_bool_attribute(true),
    my_num_attribute(7)
  ),

  RENAME Mysubcomponent my_subcomp4__c TO my_subcomp5__c;
);

You can call multiple sub-commands as part of the ALTER command.

For multi-value attributes, you can use the ADD command to add a new set of values, and use the DROP command to remove a subset of values. If assigning a multi-value attribute to a value or set of values without an ADD or DROP command, MDL replaces all values in the attribute with the specified list.

Upon any failure, Vault returns detailed error messages.

Multi-Value Attributes

Some components require that a list of values can be set for certain attributes. Values should be separated by a comma (,) for example:

RECREATE Docfieldlayout general__c (
   label('General Section'),
   active(true),
   icon('VEEVA'),
   order(0),
   fields('Docfield.document_number__v',
      'Docfield.major_version_number__v',
      'Docfield.minor_version_number__v'
   )
);

These attributes will have multi_value set to true and a value set for ordered in the metadata for the component type. If ordered is true then the order of items in the list has an impact to the behavior of the component.

About Vault Components

MDL Components are instances of MDL Component Types and contain specific configuration details. For example a Component Type Docfield has a Component instance Docfield.country__v.

Metadata Component Types

Metadata component types represent specific elements of Vault’s configuration. For example, the Docfield metadata component type relates to the Documents object.

You cannot delete a component with a standard namespace and can only make certain changes, for example, updating the label.

Code Component Types

Code components, such as Recordtrigger, contain JavaSDK code which extends functional behavior of Vault.

Component Type Names

Component type names are case-sensitive and follow a convention of a capitalized first letter with no spaces or special characters. For example, Objectlifecycle is the component type name for Object Lifecycle.

Component Names

Every component has a name which must be unique within the context of that component type.

Subcomponents must have a name which is unique within context of the parent component and the subcomponent type.

Names are lower-case, snake_cased and are suffixed by a double underscore (__) followed by a namespace.

Namespace

The namespace of a component determines the owner of the component, for example, the namespace of country__v is __v which is the Veeva standard namespace. Custom components have the __c suffix. Learn about Namespace in Vault Help.

You cannot delete a component with a standard namespace and can only make certain changes such as updating the label.

Code Component Namespace

Code component names are defined by their fully-qualified Java class name. A fully-qualified Java class name includes the class name prefixed by the package name. In Vault, the package name can be com.veeva.vault.custom.{} for custom Java SDK code or com.veeva.vault.{AppName} for standard system Java SDK code.

For example, a Recordtrigger HelloWorld Java SDK class exists in the com.veeva.vault.custom.triggers package. This would be described with MDL as Recordtrigger.com.veeva.vault.custom.triggers.HelloWorld.

Components with Content

Some components contain binary and significantly larger content which requires a separate process to migrate and reference. The following components include content:

To manage components with content, use a POST command to send a request to the api/mdl/files endpoint. See MDL API Reference.

Subcomponent Reference

This allows you to define subcomponent references in a standard way by reducing repeated effort and providing a consistent behavior.

Managing Subcomponent References

Provide valid references to subcomponents as values for component reference attributes with subcomponent types. Use the following format for the value for the attribute type with a subcomponent reference type:

{subcomponent_type}.{subcomponent_name}

Example

CREATE Checklistmapping example __c (

   label('Example'),
   active(true),
   target_record_object('Object.checklist__sys'),   
   target_record_field('Field.target_quality_event__v')
);

Component Directory

The component directory de-normalizes component records into a single queryable data object named vault_component__v. Each component in a vault will have a record in this object.

This enables Admins to use Vault Query Language (VQL) to query for all components or for specific components and to additionally verify when a component has been modified.

The vault_component__v object includes the following fields of interest:

Name Description
component_name__v The API name of the component.
component_type__v The component type of the component.
name__v The label of the component.
checksum__v The checksum of the component.
modified_date__v The date & time the component metadata was last modified.

You can retrieve all available fields using the api/{{version}}/metadata/vobjects/vault_component__v API endpoint.

Querying Components

To execute a VQL query, send a GET or POST request to the api/{version}/query endpoint. See Vault Query Language Reference

For example, to retrieve component records from a vault:

Query

$ curl -X POST -H "Authorization: {SESSION_ID}" \
-d ‘q=SELECT name__v, component_name__v, component_type__v,modified_date__v,checksum__v from vault_component__v
https://myvault.veevavault.com/api/v19.1/query

Response

{
    "responseStatus": "SUCCESS",
    "responseDetails": {
        "limit": 1000,
        "offset": 0,
        "size": 847,
        "total": 847
    },
    "data": [
        {
            "name__v": "Binder Section with Document",
            "component_name__v": "binder_section_with_document__v",
            "component_type__v": "Reporttype",
            "modified_date__v": "2018-11-13T18:28:02.000Z",
            "checksum__v": "b5f5bfc400fbce76824b5ff1ec574891"
        },
        {
            "name__v": "My Formatted Output",
            "component_name__v": "my_formatted_output__c",
            "component_type__v": "Formattedoutput",
            "modified_date__v": "2019-03-22T19:58:16.000Z",
            "checksum__v": "a89e4dad5d4b2dada2868fe35d561e81"
        }
    ]
}        

The following example query retrieves Object components only:

Query

$ curl -X POST -H "Authorization: {SESSION_ID}" \
-d ‘q=SELECT name__v, component_name__v, component_type__v,modified_date__v,checksum__v from vault_component__v where component_type__v = 'Object'
https://myvault.veevavault.com/api/v19.1/query

Response

{
    "responseStatus": "SUCCESS",
    "responseDetails": {
        "limit": 1000,
        "offset": 0,
        "size": 70,
        "total": 70
    },
    "data": [
        {
            "name__v": "Campaign",
            "component_name__v": "campaign__c",
            "component_type__v": "Object",
            "modified_date__v": "2019-02-04T12:15:34.000Z",
            "checksum__v": "6a7ccf0b3b4a17afb9d2036c7be9fdaf"
        },
        {
            "name__v": "vMDL Hello World",
            "component_name__v": "vmdl_hello_world__c",
            "component_type__v": "Object",
            "modified_date__v": "2019-03-18T15:47:25.000Z",
            "checksum__v": "d587ae806ce06ca42dfa0207137099d6"
        }
    ]
}

Attributes Data Types

Vault components and subcomponents use attribute values for their configuration.

MDL attributes use the following data types:

Data Type Description Validation Example
String Can contain letters, numbers, and spaces. Must be wrapped in single quotes ('). Maximum number of characters allowed is defined as max_length on the attribute metadata attribute('This is a String')
Boolean Can have two values: true and false attribute(true)
Number Contains digits. Maximum value defined as max_value on the attribute metadata. Minimum value defined as min_value on the attribute metadata. Max number of decimal places defined as scale on the attribute metadata attribute(1234)
Component A reference to a component in the vault. Component type is defined as component on the attribute metadata attribute('Doctype.my_special_doctype__c')
Enum A value from a list of predefined values sorted in the order you entered them. Allowed values list defined as enums on the attribute metadata attribute('Red')
XMLString Complex data in XML format The specified values bust be wrapped in curly brackets ({}). The framework validates XML structure only (not the content). Vault returns the GEN-F***-II-1056 error code if invalid. Maximum number of characters allowed is defined as max_length on the attribute metadata attribute({<xml>Some XML</xml>})
LongString A Long Text field Maximum number of characters allowed is defined as max_length on the attribute metadata attribute('...')
SdkCode Some Java SDK source code. Must be wrapped in a <VeevaData> node. attribute(<VeevaData>...<VeevaData>)
Expression A formula. Maximum number of characters allowed is defined as max_length on the attribute metadata attribute([field__c='abc'])
File A reference to a binary configuration file. attribute('bc17a630e6493266d5f629460c91748c')

Errors

The response of every API call includes a field called responseStatus for the overall status of the request. In addition, the status of each statement is returned in the response field for each statement_execution item. Possible values are:

For a status other than SUCCESS, users can inspect the errors field of statement_execution in the response:

Example:

{
    "responseStatus": "FAILURE",
    "script_execution": {
        "code": "GEN-F-401",
        "message": "Script execution failed",
        "warnings": 0,
        "failures": 1,
        "exceptions": 0,
        "components_affected": 0,
        "execution_time": 0.1
    },
    "statement_execution": [
        {
            "vault": "z-team-promomats.veevavault.com",
            "statement": 1,
            "command": "CREATE",
            "component": "Picklist.color__c",
            "message": "[FAILURE] CREATE Picklist color__c",
            "response": "FAILURE",
            "errors": [
                {
                    "line": 1,
                    "message": "Component already exists with attribute [name], value [color__c]",
                    "context": "name",
                    "code": "GEN-FCRE-II-1007"
                }
            ]
        }
    ]
}

Security

The authenticated user must be granted access to the Vault API and have permission to perform the action requested.

Component Support Matrix

Component Type CREATE RECREATE ALTER DROP RENAME Describe Generate RECREATE
Accountmessage
Atomicsecurity
Checklisttype
Dashboard ✓** ✓** ✓**
Docfield
Docfielddependency
Docfieldlayout
Doclifecycle ✓** ✓** ✓**
Docmatchingrule
Docrelationshiptype ✓** ✓** ✓**
Docparticipantrule
Doctype
Documentstagegroup
Formattedoutput
Job
Layoutrule
Link
Matchingrule
Notificationtemplate
Object ***
Objectaction
Objectlifecycle ✓** ✓** ✓**
Objectlifecyclestageroup
Objecttype
Objectvalidation
Objectworkflow ✓** ✓** ✓**
Overlaytemplate
Pagelayout ✓** ✓** ✓** X
Pagelink
Permissionset X
Picklist
Qualityteam
Renditionprofile
Renditiontype
Report ✓** ✓** X
Reporttype ✓** ✓** ✓**
Savedview X X
Searchablefield
Securityprofile
Sharingrule
Signaturepage
Tab
Workflow X X X X X X X

Legend

Icon Description
MDL Operation is supported.
✓** MDL Operation is supported, but the Component Type contains field(s) that use proprietary XML. Direct modification of the XML is not supported or recommended. Instead, creating and/or updating the component is better suited through the Admin UI.
X MDL Operation is not supported.
*** Operation is supported through /api/{{version}}/metadata/vobjects endpoint only.