REST API

Getting Started

This tutorial talks about how to set up a Vault user account that has API access and walks through the basics of uploading a document to Vault.

Authentication

To make API calls against Vault, you need a Vault user account with API access. Once you have this, you can authenticate to get a session ID.

Vault User Account & Permissions

Your security profile and permission set may grant the following permissions:

Insufficient Access

If you do not have API access, your authentication request will succeed, but any other API calls you make will return the following error:

INSUFFICIENT_ACCESS: User [ID] not licensed for permission [VaultActions_API_Access].

If you do not have API access, contact your Vault administrator to adjust your security profile and permission set.

Structuring the Endpoint

As we talk about API calls, you’ll need the following variables in every endpoint:

https://{vaultDNS}/api/{version}

For example:

https://promo-vee.veevavault.com/api/v24.1

Versioning

The only version of the Vault REST API subject to change is the newest version, labelled as Beta. The newest version of the API which is not subject to change is the General Availability version, labelled as GA. All older versions of the API (all versions besides Beta) do not change, which ensures your integration will continue to work. However, this means many new APIs and API features are not backwards compatible, and you will need to use a newer version of the API to access new functionality. To view the new APIs, features, and fixed issues for each API version, you can check the Release Notes.

Naming

Veeva Vault releases three new API versions each year, coinciding with Vault General Releases. As of 2017, REST API versions follow the pattern YY.1, YY.2, YY.3 where YY is the last two digits of the current year. For example, the first Vault General Release of 2017 is 17R1. The API version which coincides with this release is API v17.1. The third Vault General Release of 2018 is 18R3, which coincides with REST API v18.3.

Prior to 2017, Vault versions and API versions do not coincide with the current year. For example, REST API v12.0 includes features from Vault 11.5.2, 11.5.3, and 12.0.0, all of which released in 2015. Each General Release is made up of multiple limited releases. For example, Vault release 18R1 includes all features released in 17R3.2, 17R3.3, 17R3.4, and 17R3.5. The REST API versioning does not have limited release numbering. Instead, the latest version (in this example, v18.1) is labelled as Beta and all limited release features are added to the Beta API. For example, REST API v18.1 contains all features released in 17R3.2, 17R3.3, 17R3.4, and 17R3.5.

Get a Session ID

Your first API call will be an authentication request, which provides your session ID for other API calls. To do this, call the auth endpoint.

The auth endpoint (/api/{version}/auth) expects two URL-encoded form parameters (x-www-form-urlencoded): username and password.

Request

curl -X POST -H "Content-Type: application/x-www-form-urlencoded" \
-d 'username={username}&password={password}' \
"https://{server}/api/{version}/auth"

This call returns a JSON response that contains the session ID.

Response

{
  "responseStatus": "SUCCESS",
  "sessionId": "3B3C45FD240E26F0C3DB4F82BBB0C15C7EFE4B29EF9916AF41AF7E44B170BAA01F232B462BE5C2BE2ACB82F6704FDA216EBDD69996EB23A6050723D1EFE6FA2B",
  "userId": 12021,
  "vaultIds": [
    {
      "id": 1776,
      "name": "PromoMats",
      "url": "https://promo-vee.veevavault.com/api"
    },
    {
      "id": 1782,
      "name": "Platform",
      "url": "https://platform-vee.veevavault.com/api"
    }
  ],
  "vaultId": 1776
}

A session ID expires if it has not been used for a Vault’s Session Duration. For example, a session ID with a timeout of 20 minutes expires 20 minutes after the last request finishes executing. Session duration length is set by your Vault Admin. Note that even if you keep your session active, the maximum session duration is 48 hours. Learn more about configuring Session Duration in Vault Help, or learn more about best practices for session management.

Upload a Document

Now that you have a session ID, you can upload a document to your Vault using the Documents API. In this example, you will create an unclassified document.

Assign the session ID to the header parameter Authorization. Specify the source file in the file body parameter. Since you will upload the document as unclassified, assign the values Unclassified and Inbox to the body parameters type__v and lifecycle__v respectively.

Prior to 21R1.3 (API v21.2), the Unclassified document type and Inbox lifecycle were known as the Undefined document type and Unclassified lifecycle. We recommend updating existing configurations with these new labels in Vaults created before 21R1.3.

Request

curl -X POST -H "Authorization: {SESSION_ID}" \
-H "Content-Type: multipart/form-data" \
-F file=@document.txt \
-F "name__v=myDocument" \
-F "type__v=Unclassified" \
-F "lifecycle__v=Inbox" \
https://{server}/api/{version}/objects/documents

If your request contains all the required metadata and your session ID is valid, the response includes a unique document ID. Note, the file document.txt resides in the directory from which the curl command is being executed.

Response

{
    "responseStatus": "SUCCESS",
    "responseMessage": "successfully created document",
    "id": 776
}

Next Steps

Congratulations! You’ve successfully created your first document using Vault’s APIs. Once you’re ready, you can move on to the next tutorial where you’ll learn about document and object fields.

Understanding Metadata of Document & Object Fields

This tutorial covers how document and object fields work and how to use them when making API calls. We’ll also take a close look at some example fields and explain the semantics of their metadata attributes.

Vault Documents & Vault Objects

In Vault, “document” refers to both the files (source file, renditions, etc.) and the set of fields. An “object” is a kind of data entity, which also has a set of fields. Individual “object records” are instances of that data entity type with values assigned to the various fields. If you think of an object as a database table, each field is a column and each object record is a table row.

Learn more about Vault objects and documents.

Document & Object Fields

When creating a document or an object record, there are some fields that you must specify and others that Vault itself populates. For example, you must specify a value for the Name field (name__v), but Vault itself generates a value for the id field. There are also fields that are editable and not required: you can create documents or object records without populating these.

Fields like id are known as “system-managed” fields and are often hidden in the UI. The id field is particularly important when using the API because you’ll use it to identify documents, object records, and other resources.

You can use the API to find all available fields on objects, for example:

Note these APIs will return blank values, but not null values. For example, when retrieving users, you may notice the last login field: "last_login__v": "2015-02-02T16:52:21.000Z". However, if a user never logged in, this field would be null and would not show up in the response at all. Fields with blank values, for example "office_phone__v": "", do appear in the response, showing the user has entered nothing for their office phone number.

When creating documents or object records through the API, the same field requirements and validation rules apply as when working through the UI.

Configuration Differences & Field Naming

Many fields defined on documents and objects for a given Vault are unique to that Vault’s configuration, meaning that the set of fields can be different between Vaults. Some standard fields like name__v and id are common across all Vaults. API requests use the field names, not labels. For example, the standard Product document field would be product__v.

The suffix on a field name indicates whether it’s standard or custom:

Rich Text fields on Objects

As of v21.1, Rich Text fields are special text fields that allow users to apply common formatting options such as bold and italic. Rich Text fields support up to 32,000 plaintext characters, with an additional 32,000 characters reserved for HTML markup. For example, <b>Hello</b> is 5 plaintext characters and 7 HTML markup characters.

You can also convert an existing long text field to a rich text field with MDL.

Supported HTML

Vault does not support all HTML tags and attributes. In the Vault UI, users can only enter HTML markup through the buttons in the Rich Text Editor. Manually entered HTML in the Vault UI is not supported. When entering values for Rich Text fields in the API, the Rich Text Editor is not available, so manual HTML is supported.

In addition to HTML, Vault supports all Unicode characters which can be stored with UTF-8 encoding.

Download Supported HTML for Rich Text

Unsupported HTML

When adding or editing a Rich Text field from the API, Vault stores the value exactly as entered by the user. HTML validation occurs on read in the Vault UI. Reading a Rich Text value with the API or VQL will return the unvalidated value as entered by the user.

On read in the Vault UI, validation occurs as follows:

Body & Head Tags

As a best practice, do not include <body> or <head> tags in Rich Text fields.

Every Rich Text value is implicitly within a <body> tag, even though you do not see this <body> tag when retrieving a Rich Text value. If an additional <body> tag is manually entered into a Rich Text field value, Vault will render the contents within this tag only, ignoring any other text in the field.

If included, the <head> tag and any information within it will be removed when rendering Rich Text fields.

Metadata API

When using the APIs to create documents, query objects, etc., fields often serve as API parameters. Depending on the API, you may need to know the name of a field and if it’s queryable, editable, and/or required. All of this can be determined using the metadata APIs.

Metadata APIs define the shape of the fields on different document types, objects, or other resources. Below we’ll look at some key metadata properties to understand how Vault defines fields.

Document Metadata API

Let’s make an API call to get the fields defined on our documents.

Request

$ curl -X GET -H "Authorization: {SESSION_ID}" \
https://{server}/api/{version}/metadata/objects/documents/properties

Response

{
  "responseStatus": "SUCCESS",
  "properties": [
    {
      "name": "id",
      "type": "id",
      "required": true,
      "maxLength": 20,
      "minValue": 0,
      "maxValue": 9223372036854775807,
      "repeating": false,
      "systemAttribute": true,
      "editable": false,
      "setOnCreateOnly": true,
      "disabled": false,
      "hidden": true,
      "queryable": true
    },
    {
      "name": "version_id",
      "scope": "DocumentVersion",
      "type": "id",
      "required": true,
      "maxLength": 20,
      "minValue": 0,
      "maxValue": 9223372036854775807,
      "repeating": false,
      "systemAttribute": true,
      "editable": false,
      "setOnCreateOnly": true,
      "disabled": false,
      "hidden": true,
      "queryable": true
    }
  ]
}

The API call above returns the entire list of fields defined on documents, across all document types. Each field itself has a list of metadata attributes that define its behavior and shape. The example shows only a short excerpt. A real response might include hundreds of fields.

Metadata of Document Fields

We’ll look at a few document fields to understand what the various metadata attributes mean.

id

The id is a special document field that Vault automatically assigns to uniquely identify each document.

 {
      "name": "id",
      "type": "id",
      "required": true,
      "maxLength": 20,
      "minValue": 0,
      "maxValue": 9223372036854775807,
      "repeating": false,
      "systemAttribute": true,
      "editable": false,
      "setOnCreateOnly": true,
      "disabled": false,
      "hidden": true,
      "queryable": true
 }

Name

{
      "name": "name__v",
      "scope": "DocumentVersion",
      "type": "String",
      "required": true,
      "maxLength": 100,
      "repeating": false,
      "systemAttribute": true,
      "editable": true,
      "setOnCreateOnly": false,
      "disabled": false,
      "label": "Name",
      "section": "generalProperties",
      "sectionPosition": 0,
      "hidden": false,
      "queryable": true,
      "shared": false,
      "helpContent": "Displayed throughout application for the document, including in Library, Reporting, Notifications and Workflows.",
      "definedInType": "type",
      "definedIn": "base_document__v"
}

Although it doesn’t need to be unique like id, name__v must also be populated for every document (required:true). This metadata attribute has a few interesting properties that didn’t appear on id.

Product

 {
      "name": "product__v",
      "scope": "DocumentVersion",
      "type": "ObjectReference",
      "required": false,
      "repeating": true,
      "systemAttribute": true,
      "editable": true,
      "setOnCreateOnly": false,
      "disabled": false,
      "objectType": "product__v",
      "label": "Product",
      "section": "productInformation",
      "sectionPosition": 1,
      "hidden": false,
      "queryable": true,
      "shared": false,
      "definedInType": "type",
      "definedIn": "base_document__v",
      "relationshipType": "reference",
      "relationshipName": "document_product__vr"
}

Some metadata attributes reference a specific object from the same Vault. These attributes have the property type:ObjectReference. In this case, the product__v attribute references the product__v object. (The attribute name and the object name will not always be identical.) The values that you can assign to this attribute are the records within the Product object.

Object reference attributes have special properties:

Object Metadata API

Let’s make some API calls to get object metadata. First, we’ll get the list of objects defined in our Vault.

Request

$ curl -X GET -H "Authorization: {SESSION_ID}" \
https://{server}/api/{version}/metadata/vobjects

Response

{
  "responseStatus": "SUCCESS",
  "objects": [
    {
      "url": "/api/v17.1/metadata/vobjects/product__v",
      "label": "Product",
      "name": "product__v",
      "label_plural": "Products",
      "prefix": "00P",
      "order": 2,
      "in_menu": true,
      "source": "standard",
      "status": [
        "active__v"
      ]
    },
    {
      "url": "/api/v17.1/metadata/vobjects/country__v",
      "label": "Country",
      "name": "country__v",
      "label_plural": "Countries",
      "prefix": "00C",
      "order": 4,
      "in_menu": true,
      "source": "standard",
      "status": [
        "active__v"
      ]
    }
  ]
}

From this response, we can see that there’s a Product object configured. Let’s call the metadata API for this object to see its fields. For this, we add the object name product__v to the request.

Request

$ curl -X GET -H "Authorization: {SESSION_ID}" \
https://{server}/api/{version}/metadata/vobjects/product__v

Response

{
  "responseStatus": "SUCCESS",
  "object": {
     "fields": [
      {
        "help_content": null,
        "editable": false,
        "lookup_relationship_name": null,
        "label": "ID",
        "source": "standard",
        "type": "ID",
        "modified_date": "2015-10-26T18:26:53.000Z",
        "created_by": 1,
        "required": false,
        "no_copy": true,
        "name": "id",
        "list_column": false,
        "modified_by": 1,
        "created_date": "2015-10-26T18:26:53.000Z",
        "lookup_source_field": null,
        "status": [
          "active__v"
        ],
        "order": 0
      },
      {
        "help_content": null,
        "editable": true,
        "lookup_relationship_name": null,
        "start_number": null,
        "label": "Product Name",
        "source": "standard",
        "type": "String",
        "modified_date": "2015-10-26T18:26:53.000Z",
        "created_by": 1,
        "required": true,
        "no_copy": false,
        "system_managed_name": false,
        "value_format": null,
        "unique": true,
        "name": "name__v",
        "list_column": true,
        "modified_by": 1,
        "created_date": "2015-10-26T18:26:53.000Z",
        "lookup_source_field": null,
        "status": [
          "active__v"
        ],
        "max_length": 128,
        "order": 1
      },
    ]
  }
}

Next Steps

Now that you understand how to read metadata attributes in your response, you’re ready to check out these tutorials:

Creating & Downloading Documents in Bulk

In this tutorial we’ll discover two ways of creating documents in batch: using Bulk Document Create API and using the Vault Loader Command Line Interface. We’ll also look at how to download documents in batch.

Vault Loader CLI

You can download Vault Loader CLI from the Vault UI, as shown below. Learn more about Vault Loader CLI in Vault Help.

Vault Loader CLI Download

Document Creation Overview

Creating multiple documents is a two-step process. First, upload the source files to the staging server via FTP. Then, make the API call to set the metadata attributes (field values) of the documents. This API call also begins the process of copying files from the staging server to your Vault.

Create Documents

In the API call, you must provide values for all required attributes, for each document that you’re creating. See Understanding Metadata to learn about retrieving the required attributes.

The request below creates three documents from source files doc1.txt, doc2.txt, and doc3.txt. The required metadata attributes for these documents are name__v, type__v and lifecycle__v.

The file column and suppressRendition are not required:

CSV Input

Both of the requests below use the create_documents.csv input file.

file,name__v,type__v,lifecycle__v,suppressRendition
doc1.txt,doc1,type,eTMF Lifecycle,true
doc2.txt,doc2,type,eTMF Lifecycle,true
doc3.txt,doc3,type,eTMF Lifecycle,true

Request

Using curl:

curl -X POST -H "Authorization: {SESSION_ID}" \
-H "Content-Type: text/csv" \
-H "Accept: text/csv" \
--data-binary @"C:\Vault\Documents\create_documents.csv" \
https://myvault.veevavault.com/api/v15.0/objects/documents/batch

Using the command line interface:

java -jar VaultDataLoader.jar -createdocuments -csv create_documents.csv

Response

You can see from the response that all documents were successfully created. The id column returns the system ID generated for each document and row_id maps each row back to the original input.

responseStatus,id,name__v,type__v,lifecycle__v,errors,row_id
SUCCESS,1634,,,,,1
SUCCESS,1635,,,,,2
SUCCESS,1636,,,,,3

CLI Async Mode

You can run the CLI asynchronously and free up the command prompt. The CLI gives you a job ID that you can use to track the job status. When the job is complete, you can use -jobresults to download the results, which are similar to the CSV above. In async mode, these don’t download automatically.

Example: CLI Async

These examples show the same document creation process as above, but using the CLI in asynchronous mode:

>> java -jar VaultDataLoader.jar -createdocuments -csv createdoc.csv -async
Job 10479 submitted.

>> java -jar VaultDataLoader.jar -jobstatus 10479
ID         Type                      Status          Progress        Start Time      End Time        Expiration Date
10479      create-documents          Success         3 / 0           2016-11-28      2016-11-28      2016-12-14
                                                                     02:23:49AM GMT  02:23:53AM GMT  02:23:53AM GMT

>> java -jar VaultDataLoader.jar -jobresults 10479

Downloading Documents

Vault Loader (UI or CLI) provides the most efficient way to download source files and renditions. This section describes how to accomplish this from the CLI.

Download Location

Vault Loader downloads source files and renditions to the Vault’s FTP staging server, not your local machine. Once the process is complete, you can download the files via FTP. The results output will indicate where the files reside on the server and which versions were included in the extract.

Vault uses the following directory structure for downloaded files: {job_id}/{doc_id}/{major_version_number__v}/{minor_version_number__v}/

Download Limits

The FTP server automatically removes downloaded files after the job’s Expiration Date.

Vault Loader cannot extract more than 2,000 files (source files and renditions) in a single job.

Example: Downloading with CLI

>> java -jar VaultDataLoader.jar -exportdocument -source -where "id contains (1634, 1635, 1636)" -async

>> java -jar VaultDataLoader.jar -jobstatus 10381
ID         Type                      Status          Progress        Start Time      End Time        Expiration Date
10381      export-documents          Success         3 / 0           2016-11-28      2016-11-28      2016-12-14
                                                                     04:24:25AM GMT  04:24:25AM GMT  04:24:25AM GMT
>> java -jar VaultDataLoader.jar -jobresults 10381
file,id,external_id__v,rendition_type__v,major_version_number__v,minor_version_number__v
/10381/1636/0_1/doc3.txt,1636,,,0,1
/10381/1634/0_1/doc1.txt,1634,,,0,1
/10381/1635/0_1/doc2.txt,1635,,,0,1

Next Steps

Now that you know how to create and download documents, check out our tutorial on querying document metadata attributes using VQL.

Session Management

When you log into Vault through the UI or the Authentication endpoint, you generate a session for that user. While a session is active, the authenticated user can perform actions in the UI, make REST API calls, and so on.

Session Duration

A session is considered “active” as long as some activity (either through the UI or API) happens within the maximum inactive session duration. This maximum inactive session duration varies by Vault, and is configured by your Vault Admin. For example, a Vault configured with a session duration of 10 minutes means a session will expire 10 minutes after the last API request finishes executing. As long as an API request is active, the session that made that API call will continue to be valid until the request finishes executing. If you are a Vault Admin, learn more about configuring Session Duration in Vault Help.

The maximum session duration is 48 hours, which is not configurable. This means that even if you keep your session active through activity, it cannot remain active for longer than 48 hours. To keep sessions valid in a long-running integration, see our best practices.

In addition, a session could be invalidated based on major security changes. For example, a password change or account deactivation.

Best Practices

We recommend reusing the sessionId obtained after login to execute as many API requests as possible. To keep your session active, use the Session Keep Alive endpoint. This avoids unnecessary auth calls, which helps your integration stay within the API rate limits.

Make sure your integration catches invalid session exceptions and obtains a new session as needed. Your integration should also include a hard expiration at 48 hours, which is the maximum session duration.

API Rate Limits

API rate limits are a common way to guarantee a high quality service by preventing servers from becoming overloaded and the web service itself from becoming unusable. Web services are a fundamental resource to any developer application or integration. We enforce rate limits to ensure that each application or integration gets its fair share of this resource. Learn more about API rate limits in Help.

What Are Rate Limits?

Rate limits constrain the number of API calls a user can make during a given time period. Once you reach your API quota, the server will throttle, or delay, your API requests until the next window.

Calls to /api/{version}/auth are calculated separately. After reaching the Auth API Burst Limit, any further requests will fail until the next window.

How Does Vault Calculate Limits?

Vault enforces multiple types of rate limits:

For example, a Vault might allow 2,000 API requests within a 5-minute window. Between 4:00 and 4:03, your Vault has received 2,000 requests. On request 2,001 at 4:04, the server slows down all requests until the next window begins at 4:05.

As of v21.1, Vault no longer enforces daily API limits, includes the daily_limit_remaing in API usage logs, or sends notifications to users when API transaction limits are partially reached or exceeded.

API Rate Limit Headers

Vault APIs return rate limiting headers to help you monitor how many API calls you have remaining as well as possible response throttling.

As of v21.1, Vault APIs no longer return the X-VaultAPI-DailyLimit or X-VaultAPI-DailyLimitRemaining headers. To ensure backwards compatibility, Vault APIs v20.3 and below still return the headers with a value of 999,999. Vault does not deduct from this value with each request.

These headers are not relevant when the Job Status endpoint returns the API_LIMIT_EXCEEDED error when requested more than once in 10 seconds.

Authentication API Rate Limit Headers

As of v20.1, calls to /api/{version}/auth return two rate limit headers in every response showing you the total limits allowed for your Vault and how many /api/{version}/auth calls you have remaining. These calls also count towards your burst and daily limits.

Developing with Rate Limits

Here are some best practices for reducing the number of API requests:

  1. Avoid unnecessary auth calls. A session ID with a timeout of 20 minutes only expires if it is not used within 20 minutes after the last request finishes executing.

  2. Cache configuration data. Configuration data does not change often. Retrieve it once and store it locally in a database like SQLite or serialized in a file.

  3. Optimize your code to eliminate unnecessary API requests. Are you retrieving data that isn’t being used in your application? Are you updating data that hasn’t changed? Eliminate these calls.

  4. Regulate the API request rate. If you are frequently approaching or reaching the API rate limit, consider implementing a throttling process in your application to distribute your requests more uniformly over time. For example, observe the above mentioned response headers and monitor your request rate. Throttle requests when your rate reaches a certain threshold.

  5. Use the bulk/batch APIs. You can drastically reduce your API request count if you take advantage of the many bulk APIs available. For example, a single API request can create 500 object records using the Create Multiple Object Records API. Find opportunities to replace single API calls with their bulk counterparts. Note that bulk APIs are not currently available on all resources.

Response Headers

Each response from the Vault REST API includes read-only response headers. These headers contain various metrics to aid developers in monitoring performance, limits, and more.

The following headers are returned for all Vault REST API calls unless otherwise noted:

Response Header Name Description
X-VaultAPI-ExecutionId The unique ID associated with this API request. Include this value with any Support ticket regarding the Vault REST API.
X-VaultAPI-BurstLimit The maximum number of calls allowed in a burst window before throttling is enforced. Learn more about API rate limit headers.
X-VaultAPI-BurstLimitRemaining The number of API calls remaining for the current 5-minute burst window. Learn more about API rate limit headers.
X-VaultAPI-VaultId The ID of the Vault where this request was initiated.
X-VaultAPI-UserId The ID of the authenticated user who made the request. Returned for all requests which include a SESSION_ID.
X-VaultAPI-TruncatedSessionId A shortened version of the SESSION_ID. Returned for all requests which include a SESSION_ID. This value can identify a group of API requests, but cannot be used to make new API requests.
X-VaultAPI-Status API v23.2+: The responseStatus of the API request.

Additional headers returned by the API vary by request. For example, Vault Java SDK performance metrics are only returned when the request invokes custom Vault Java SDK code.

The following headers may be returned by Vault REST API calls:

Response Header Name Description
X-VaultAPI-DowntimeExpectedDurationMinutes Returned during scheduled Vault upgrades. Indicates the expected duration of downtime in minutes. Learn more about Vault Releases in Vault Help.
X-VaultAPI-ResponseDelay The length of delay, in milliseconds, for a throttled response. Returned for requests which have exceeded the burst limit. Learn more about API rate limit headers.
X-VaultAPI-SdkCount A Vault Java SDK performance metric. Returned for requests which invoke custom Vaut Java SDK code.
X-VaultAPI-SdkCpuTime A Vault Java SDK performance metric. Returned for requests which invoke custom Vaut Java SDK code. Values returned in nanoseconds.
X-VaultAPI-SdkElapsedTime A Vault Java SDK performance metric. Returned for requests which invoke custom Vaut Java SDK code. Values returned in milliseconds.
X-VaultAPI-SdkGrossMemory A Vault Java SDK performance metric. Returned for requests which invoke custom Vaut Java SDK code. Values returned in bytes.
X-VaultAPI-Connection If the request has an associated Connection record, this header returns the api_name__sys for the associated connection.
X-VaultAPI-ReferenceId The reference ID for the request, which is specified in the X-VaultAPI-ReferenceId request header. If included, this value appears in the reference_id column of the API Usage Log.
X-VaultAPI-DailyLimit Deprecated. May appear in v20.3 and below.
X-VaultAPI-DailyLimitRemaining Deprecated. May appear in v20.3 and below.

Vault Java SDK Performance Metrics Response Headers

In v22.1+, the Vault REST API includes metrics in the response header which allow developers to inspect Vault Java SDK performance during API execution. These response headers are returned with any Vault REST API request which invokes custom Vault Java SDK code. If the request does not invoke custom code, the response will not include these headers.

These Vault Java SDK performance metrics are also included in the API Usage Log, which is available for download with the REST API or in the Vault UI.

Response Header Name Description
X-VaultAPI-SdkCount The total number of SDK entry points executed in this request.
X-VaultAPI-SdkCpuTime The total CPU processing time required for this request, in nanoseconds.
X-VaultAPI-SdkElapsedTime The total elapsed time for this request, in milliseconds.
X-VaultAPI-SdkGrossMemory The total gross memory required for this request, in bytes.

Reference ID

For additional tracking purposes, every Vault REST API call will accept an optional string-based reference ID. You can provide this data inside the X-VaultAPI-ReferenceID HTTP request header.

The Vault REST API will record the reference ID value for each API call. This ID appears in the API Usage Logs, which you can download through the UI and API. If an API request does not include a reference ID, the value will appear blank in the API Usage Log. The API Usage Log is only available in v18.1+, but reference ID can be included in requests for v23.3+ of the API.

Client ID

For additional tracking purposes, every Vault REST API call will accept an optional client ID to represent an external integration client. You can provide this data inside a query parameter called client_id or HTTP header called X-VaultAPI-ClientID. If a client ID is included as both a HTTP header and query parameter, Vault ignores the HTTP Header.

The Vault REST API will record the client ID value for each API call. This ID appears in the API Usage Logs, which you can download through the UI and API. If an API request does not include a client ID, the value will appear as unknown in the API Usage Log. The API Usage Log is only available in v18.1+, but client ID can be included in requests for all versions of the API.

Client ID Filtering

When configuring inbound External Connections, we recommend Vault Admins enable Client ID Filtering to allow only known, trusted client IDs to connect to Vault through an external connection. Admins can enable this setting in the Vault UI from Admin > Settings > General Settings.

Once Client ID Filtering is enabled, Vault will reject API requests originating with a client ID that does not match an active Connection in the Vault. A Vault Admin can configure each connection with multiple client IDs. By default, each connection has a client ID in the format veeva-vault-{connection api_name__sys}, but this ID may vary by organization if reconfigured by your Vault Admin. If an API request is associated with an external connection, you can retrieve the connection’s api_name__sys from the X-VaultAPI-Connection header.

Format

A valid client ID must be an alphanumeric string with a maximum of 100 characters. A client ID can be mixed-case and the only special characters allowed are periods ., underscores _, and hyphens -. If an API request includes an invalid client ID, the value will appear as invalid_client_id in the API Usage Log.

To avoid clashing with other integrations or client applications running on Vault, we recommend that you format your client ID as follows:

{company}-{organization}-{component/team}-{server | client}-{program}

For example, the Vault Loader team client ID could be:

veeva-vault-tools-server-loader

Authentication Defaulting

When authenticating to Vault through the API, Vault authenticates the user to the Vault specified in the POST URI {vaultDNS}. For example:

https://{vaultDNS}/api/{version}/auth

You can also override the {vaultDNS} URI parameter with the optional vaultDNS body parameter, which instead generates a session for the DNS specified in vaultDNS. When the optional vaultDNS body parameter is present, the {vaultDNS} URI parameter is ignored.

If the specified DNS is invalid or inactive, Vault executes logic to authenticate the user to their most relevant available Vault. A DNS is considered invalid if the given user cannot access any Vaults in that DNS, for example, if the user does not exist in that DNS or if all Vaults in that DNS are inactive.

The most relevant available Vault is calculated with the following steps:

  1. Where the user last logged in.
  2. If the user has never logged in, or if the last logged-in Vault is inactive, the oldest active Vault where that user is a member.
  3. If the user is not a member of any active Vaults, the user receives an error message and cannot authenticate.

This is also known as authentication defaulting or session defaulting. Authentication defaulting means that authenticating to the Vault REST API could return a sessionId for any Vault to which the user has access, which may not be the Vault specified in vaultDNS. For this reason, it is best practice to inspect the response, compare the desired Vault ID with the list of returned Vault IDs, and confirm the DNS matches the expected login.

Authentication Defaulting Example

As an example demonstrating authentication defaulting, Miyah is cross-domain user with access to the following Vaults in her home domain:

  1. An inactive Vault created in 2019, where she last logged in: my2019vault.veevavault.com
  2. An inactive Vault created in 2020: my2020vault.veevavault.com
  3. An active Vault created in 2018: my2018vault.veevavault.com
  4. An active Vault created in 2016: my2016vault.veevavault.com

Miyah executes the following authentication call:

$ curl -X POST https://my2020vault.veevavault.com/api/v24.1/auth \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Accept: application/json" \
-d "username=miyah.miller@veepharm.com&password={password}"
-d "vaultDNS=my2050vault.veevavault.com"

Because the optional vaultDNS body parameter is present, Vault ignores the {vaultDNS} URI parameter.

Then, Vault attempts to generate a valid sessionId for Miyah in the following order:

  1. The Vault specified in the optional vaultDNS body parameter: my2050vault.veevavault.com
    • Miyah does not have access to this Vault, so this Vault is invalid. Vault begins the process of authenticating Miyah to her most relevant available Vault.
  2. Where Miyah last logged in: my2019vault.veevavault.com
    • This Vault is inactive, so this Vault is invalid. Vault continues the process of authenticating Miyah to her most relevant available Vault.
  3. The oldest active Vault where Miyah is a member: my2016vault.veevavault.com
    • This Vault is valid, so Vault generates a session for this Vault and returns SUCCESS.

Miyah’s authentication call returns the following response:

{
  "responseStatus": "SUCCESS",
  "sessionId": "C7EFE4B29EF9914B170BAA01F232B462BE5ACB82F6704FDA2162B",
  "userId": 12021,
  "vaultIds": [
    {
      "id": 1776,
      "name": "PromoMats",
      "url": "https://my2016vault.veevavault.com/api"
    },
    {
      "id": 1777,
      "name": "eTMF",
      "url": "https://my2019vault.veevavault.com/api"
    },
    {
      "id": 1779,
      "name": "QualityDocs",
      "url": "https://qualitydocs-veevapharm.veevavault.com/api"
    }
  ],
  "vaultId": 1776
}

After authenticating, Miyah compares the returned vaultId with the Vault ID where she expected to authenticate. Because this ID does not match, she understands her user must not have access to any Vaults in the specified vaultDNS and she instead authenticated to her most relevant available Vault: "vaultId": 1776.

Cross-Origin Requests

Cross-Origin Resource Sharing (CORS) and JSONP are currently unsupported. If you want to integrate your web application directly with the Vault API, you must route API requests through your own backend and not directly from the browser via AJAX.

CSV Format Deviations from RFC

When comminicating with the Vault API, CSV formatting is compliant with RFC 4180 with the following exceptions:

TLS Supported Cipher Suites

Vault supports the following TLS cipher suites:

All other ciphers are unsupported. You must use a supported cipher to connect to Vault.

Vault External Document Viewer

Overview

You can embed the external document viewer into a website or use it as a standalone viewer for documents in your Vault. Vault ensures that only the latest steady state version of the document will be accessible through the viewer at all times.

The External Viewer has the following unique properties:

The Token API generates document access tokens needed by the external viewer:

Setting up the External Viewer

You can include the following snippet of JavaScript code into your website to display a specific Vault document.

<!DOCTYPE html>
<html>
 <body>
   <!-- 1. The <iframe> (and Vault viewer) will replace this <div> tag. -->
   <div id="viewer"></div>

   <script>
     // 2. This code loads the IFrame Viewer API code asynchronously.
     var tag = document.createElement('script');

     tag.src = 'https://js.veevavault.com/vault.js';
     var firstScriptTag = document.getElementsByTagName('script')[0];
     firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

     // 3. This function creates an <iframe> (and Vault viewer) after the API code downloads.
     var viewer;
     function onVeevaVaultIframeAPIReady() {
       viewer = new VV.Viewer('viewer', {
         height: '600',
         width: '600',
         error: 'We\'re sorry. The document you are trying to view is not available.'
       });
     }
   </script>
 </body>
</html>

Once the viewer is embedded, a Vault Document Token generated for the desired document needs to be provided in the URL parameters, as well as a DNS parameter to pass the source Vault’s DNS.

Generating Tokens for Vault Documents

Generate tokens with the Document Tokens endpoint.

POST /api/{VERSION}/objects/documents/tokens

How to Create the URL

When sharing your documents in an embedded viewer, users must navigate to a URL that includes both the anonymous viewing token and your Vault’s DNS:

https://{PAGE_WITH_EMBED_SCRIPT}?token={VIEWING_TOKEN}&dns={CUSTOMER}.veevavault.com

For example, a URL for information for the CholeCap product might be:

https://cholecap.com/about.html?token=3003-cb6e5c3b-4df9-411c-abc2-6e7ae120ede7&dns=myvault.veevavault.com

If you want to display multiple documents in the viewer, use the tokenGroup parameter when requesting tokens and use any of the tokens from the response within the URL. Vault will determine whether a token belongs to a group and will automatically show all documents within the group. The token in the URL corresponds to the document that displays when the viewer loads.

Sending Session IDs with Post Message

A technology called postMessage is a secure method of sending data. There are several Vault configurations which may send data using postMessage. For more information about postMessage, you can visit Mozilla’s documentation.

When the Post Session credentials via Post Message checkbox is selected in a custom web tab, Vault sends the user’s session ID using postMessage rather than as a URL parameter. Learn more about custom web tabs in Vault Help.

When the Post Session Credentials via Form Data with Key “Session.id” checkbox is selected when configuring an external URL call job, Vault sends the user’s session ID using postMessage. Learn more about configuring external URL jobs in Vault Help.

When these options are selected, you must adjust your application to receive information from postMessage:

  1. Request the session ID from Vault by sending a “ready” message on the window load of the custom web tab or external URL.
  2. Listen for a message event from Vault with the session ID. The postMessage happens after the initial page load, so your web application must listen for message events.

Vault will return JSON data with the session ID.

Here is an example using jQuery:

<script type="text/javascript">
  let sessionId = '';

  // 1. Request the session ID from Vault
  $(window).on('load', function() {
    var readyMessage = JSON.stringify({'message_id': 'ready', 'data': {}});
    window.parent.postMessage(readyMessage, '*');
  });

  // 2. Listen for a message event from Vault
  $(window).on('message', function(e) {
    var message = JSON.parse(e.originalEvent.data);
    if (message['message_id'] == 'session_id') {
      sessionId = message['data']['session_id'];
    }
  });

  // Use the sessionId variable in the integration header or body data
</script>

This example JSON output shows the session ID returned from Vault:

{"message_id":"session_id","data": {"session_id":"9DA3848FF39392020…"}}

Once you have the session_id, your web application can store it using cookies. You can also pass the data into a Vault REST API request.

Using the File Staging Server

Each Vault in your domain has its own file staging server. You can use this as a temporary storage area for files you’re loading. Vault also uses it to store extracted files. The URL of each staging server is the same as the corresponding Vault. Before loading any input that references a file, you must upload the file to the server via FTP. These files can include source files and renditions for documents or user images for user profiles.

Limitations: Vault does not support the ability for cross-domain users to log in to FTP servers on a cross-domain Vault. This applies even to members of cross-domain Vaults that can log in via the UI. In addition, while you can create folders on your FTP server, you cannot rename or move existing folders.

How to Connect

In versions 20.3+, use the Vault REST API to upload and manage files and folders on your Vault’s file staging server. See File Staging in the Vault REST API Reference for details.

To connect legacy implementations, see How to Connect Legacy Implementations via FTP.

Staging Server Permissions

Uploading to or downloading from the staging server requires a security profile with the File Staging: Access and API: Access API permissions. Only the standard Vault Owner and System Admin profiles include this by default, but Admins can add this permission to other profiles.

About Paths

Paths to files and folders are different for Admin and non-Admin users. Non-Admin users can only see their own files and folders. Admin users can see all files and folders on their Vault’s file staging server, including the root directory and individual user directories. User directories are always in the format u{user_id}. Admin users must include the full path from the staging server’s root directory, even for files and folders in their own user directory, while non-Admin users must include the full path from their user directory’s root. For example:

How to Use the Server for Inputs

To reference files:

Note that after creation, you cannot rename or move directories on your file staging server via FTP. To move or rename directories via API, see Update a File or Folder in the Vault REST API Reference.

How to Create Staged Documents

You can create Staged documents by uploading files to the Inbox directory on your Vault’s file staging server. Learn more about Staged documents in Vault Help.

How to Use the Server for Extracts

Scalable FTP

As of 19R1.3 (May 31st 2019), the Scalable FTP feature will upgrade the Vault FTP infrastructure to make it more robust, scalable and future-proof, by taking a greater advantage of AWS™. This article outlines the details and value of the Scalable FTP enhancements and its impact on the Vault FTP infrastructure.

Overview

Prior to this upgrade, the file staging server along with its staging area resided on the same hardware as the rest of the Vault. This created some challenges that we’ve addressed with the following updates:

Scalable FTP addresses these challenges and improves on a number of other areas.

Process and Document Artifact Creation

To understand the value of enhancements provided by the Scalable FTP, we’ll first review the typical process of migrating documents into Vault.

For users, this process simply involves uploading and creating documents. For managing migrations and implementations, the typical process consists of the following steps:

  1. FTP upload to a Sandbox or Test Vault environment.
  2. Author migration scripts, test, and validate document creation.
  3. Execute in a production Vault environment for final launch.

Step 1: FTP Upload

The upload phase allows users to upload files to their Vault using an FTP application or an integration written to transfer files over FTP protocol. During this process, Vault places the files in a staging area making them available for processing and for creating documents or document artifacts such as versions, renditions or attachments.

Step 2: Document Creation

Vault processes each uploaded file and performs a number of asynchronous tasks including placing files in the correct locations on AWS S3, encryption, checksum, calculation, MIME-type determination, rendition generation, etc.

To create documents or document artifacts such as versions, renditions and attachments in Vault, the user calls one of Vault Batch APIs or uses Vault Loader. Vault will use the files previously uploaded via FTP. As part of the document creation process, some tasks also execute synchronously. Upon completion of the synchronous tasks the user either receives IDs for the created artifacts or an error if the source files couldn’t be located in the file staging area.

Step 3: Finalization

For the documents to become fully usable and searchable, Vault must first complete the asynchronous tasks. In this final step, Vault indexes the document metadata and content, and finalizes the calculation of checksums and MIME-types.

Performance & Enhancements

Vault executes a series of tasks in the above steps with each having an impact on performance. Although these enhancements have increased the length of some of these individual tasks, other tasks perform better as a result.

Before Scalable FTP, Vault placed files on to a local file system upon upload. The process of uploading the files onto AWS S3 and file encryption was left to the asynchronous part of processing the process which impacted its overall performance.

With Scalable FTP, the files will be uploaded on to a robust AWS S3 file system immediately. The direct bypass on to the S3 file system does take additional time and the initial step of transferring files will take longer. However, placing the files on to S3 right away expedites most subsequent steps or eliminates them completely which ultimately improves overall performance. For example, because AWS S3 provides a robust, secured and encrypted storage mechanism and eliminates the need of file pre-encryption. The files will still be encrypted at rest.

Checksum Calculation

With Scalable FTP, we’ve made the checksum calculation process asynchronous and moved it to the finalization step of the FTP process. When creating documents in bulk and uploading files to the file staging server, Vault no longer updates the Checksum field value immediately. Instead, Vault sets the checksum value to “pending” until the asynchronous finalization step completes. Users will see the “pending” value in the UI, when performing a query via the API or VQL, or when in the metadata when using the document export bulk action. This improves on overall performance and makes documents readily available in Vault much sooner.

MIME-Type Calculation

The final calculation and confirmation of the media type has also become an asynchronous process. Vault now initially determines the media type based on the file extension after uploading via FTP. This allows for an accurate calculation of over 90% of files uploaded. In the unlikely event where Vault cannot determine the media type based on the file extension during bulk document creation, Vault may assign an inaccurate media type. However, Vault quickly resolves this condition by providing a secondary recalculation for this subset of files. This change significantly increases the performance of bulk document creation.

Network Load Balancing

Vault infrastructure utilizes Network Load Balancers to improve network traffic and provide near zero downtime. The balancers, however, may adversely impact some FTP client applications and network proxies because the control connection IP addresses differ from those used for data connections. This difference may cause some FTP clients and proxies to experience connection errors. To mitigate these errors, we recommend setting Remove Verification to false in affected FTP client applications and proxies. For example, Java-based clients and integrations need to set ftpsClient.setRemoteVerificationEnabled to false. If this change is not possible, please contact Veeva Support.

File Staging Area Linking

Frequently during large migrations, it is necessary to re-link the file staging area from one Vault to another. For example, after uploading the files into Sandbox for testing, the subsequent production migration can use the same files from the staging area. However, there was a limitation where linking was only allowed as long as both Vaults were located on the same POD.

With Scalable FTP, Vault no longer utilizes the local POD file system as the staging area, but instead uses a highly scalable AWS S3. This enhancement allows the ability to easily link the staging area to Vaults across PODs.

Long Filename

The file name length limit has been increased. Now file name length is limited to 255 bytes while the complete path including the file name is limited to 955 bytes.

Safety

Intake JSON Syntax

Format JSON files properly to maximize the amount of data Safety can extract to import an Inbox Item from the Intake JSON endpoint.

The following list describes the basic structure of a Safety JSON intake file:

Sample JSON File

Click the button below to download a sample JSON intake file with only structured data.

Download Sample JSON

Objects

Safety supports the following standard objects, which are nested under data for a single case:

For each object, Vault Safety can map structured data from key-value pairs. Each JSON key must match a Vault field, which can be either a standard or custom field. Structured fields must be nested under the structured parameter and within the appropriate Safety object.

The following table outlines the supported field type formats that Safety can extract. In each object-type field, the value must exactly match the API Name for the Vault object record.

Field Type Accepted Value
Reason Omitted API Name of the Reason Omitted record, exactly as it appears in your Vault
Object (Controlled Vocabulary) API Name of the Controlled Vocabulary record, exactly as it appears in your Vault
Object (Country) 2 or 3-character abbreviation or full country name, exactly as it appears in your Vault
Object (Unit of Measurement) Name of the unit of measurement, exactly as it appears in your Vault
Object (Case Contact) Name of the Case Contact object type, exactly as it appears in your Vault. The following types are supported: reporter__v, facility__v, or base__v
Object (Case Cause of Death) Name of the Case Cause of Death object type, exactly as it appears in your Vault. The following types are supported: autopsy__v or reported__v
Date Date in the following format: yyyy-MM-dd'T'HH:mm:ss.SSSXXX.
For the New Info Date, the minimum level of precision required is the year, month, and day, yyyy-MM-dd. For example, 2012-02-26T03:45:12.123+03:30.
Number Number value
Picklist Comma-separated list of multi-value picklists, exactly as they appear in your Vault. For example, seriousness__v
Text Characters in the text string
Yes/No The boolean value (true or false)
Additional Fields (Pass-Through Fields)

The Intake JSON endpoint can ingest pass-through fields, which are fields that are present on the Case or Case-descendant objects but not on the Inbox Item object. This includes custom fields, which can be identified by an API Name ending in __c.

Pass through fields appear upon Case promotion. To be supported for pass-through, a field must be on one of the supported standard objects.

Consider the following requirements when formatting custom fields or pass-through fields for JSON intake:

JSON Limits and Restrictions

Vault Safety imposes the following default limits on intake JSON files for each API call:

Pass-Through Field Limits and Restrictions

Certain fields are not supported. If data is received for unsupported fields, the system will ignore and not process that data. Click the button below to download a file listing the fields that are not supported for structured data intake.

Download Pass-Through Fields Limits and Restrictions

Developer Resources

Developer Community

Developers are encouraged to join our Developer Community where they can interact with other developers and talk directly to our Developer Support team. Community users can post questions regarding the Vault REST API, Vault Java SDK, and any of our open-source solutions.

For more information, visit Vault for Developers on Veeva Connect.

Platform Postman™ Collection for the Vault API

In addition to the Vault REST API Reference, developers can download the official Vault Platform Postman Collection which includes all Platform APIs with matching API endpoint names and variables. This collection allows developers to test and analyze integration designs. A new version of the collection is made available with each GA Vault REST API release.

Collections represent the point in time when the API version became GA and may not receive additional updates. When versions do receive updates, the existing collection is replaced, which means links and forks to specific collections may become out of date. For the most up-to-date documentation, developers should re-import the newest version of the Postman Collection or visit the the Vault REST API Reference.

Download the Vault Platform Postman Collection from your applicable version of the Vault REST API Reference, or choose the version you need from the Veeva Vault Postman Team. Postman collections are available for API versions v20.2+.

Veeva also provides a sample Postman Environment from the download button below. Learn more about managing environments from the Postman Environment Documentation.

Vault API Library

The Vault API Library (VAPIL) is an open-source Java library for the Vault REST API that includes coverage for all Platform APIs. This library allows developers to quickly build and test API integrations that can be hosted on any Java-based external system. Support for VAPIL is available exclusively through our Developer Community.

For more information, see the VAPIL GitHub Repository or Javadoc.