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.
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.
Your security profile and permission set may grant the following permissions:
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.
As we talk about API calls, you’ll need the following variables in every endpoint:
https://
{vaultDNS}
/api/
{version}
{vaultDNS}
: The DNS of your Vault. You can find this by logging into your Vault via the UI. Once you log in, you’ll see a URL like this: https://promo-vee.veevavault.com/ui/
. In API calls, replace the {vaultDNS}
variable with the promo-vee.veevavault.com
portion of the URL. If you have access to multiple Vaults on a single domain, the domain name will be different for each Vault.{version}
: The Vault REST API version. Replace this with a version number, such as v24.1
. You can use an API call to retrieve the available Vault REST API versions.For example:
https://
promo-vee.veevavault.com
/api/
v24.1
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.
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.
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
.
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.
{
"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.
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.
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.
{
"responseStatus": "SUCCESS",
"responseMessage": "successfully created document",
"id": 776
}
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.
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.
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.
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.
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:
__v
is a standard field. Some standard fields have application-specific suffixes, for example __rim
.__c
is a custom field or a sample field delivered with the application. On older Vaults, some custom fields have the __vs
suffix.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.
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.
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>
and <head>
) are treated as plain text. For example: <Purchase_Order>12345</Purchase_Order>
displays as plain text<strong>12345</strong>
displays as plain text<body>
or <head>
tags. These are treated differently than other unsupported HTML.<p style="font-family:cursive">Cursive</p>
displays as Cursive
, in a paragraph with no other styling<p title="Purchase Order">Purchase Order</p>
renders as Purchase Order
, in a paragraph with no other styling<p purchaseOrderId="1234">Purchase Order</p>
renders as Purchase Order
, in a paragraph with no other stylingAs 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.
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.
Let’s make an API call to get the fields defined on our documents.
$ curl -X GET -H "Authorization: {SESSION_ID}" \
https://{server}/api/{version}/metadata/objects/documents/properties
{
"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.
We’ll look at a few document fields to understand what the various metadata attributes mean.
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
specifies the name to use as the parameter name for a given API. For instance, to update a set of documents you need to specify the document ids to update under the id
parameter of the document update API.required
means that a value is always assigned for this attributeminValue
and maxValue
indicate that it’s a numeric field, although it uses a special id
type rather than number
systemAttribute
indicates that Vault controls this field and the field values; this means that you don’t need to set the value when creating a documentsetOnCreateOnly
indicates that the value can only be set during document creationeditable:false
indicates that you cannot modify the valuequeryable
shows that the field is usable in VQL queries{
"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
.
scope
tells us that this field can be assigned a value for each document version, for example, the name on v0.1 could be different from the name on v1.2definedIn
indicates where the attribute is defined in the document type hierarchy; base_document__v
means that the attribute applies to every document type, subtype, and classificationsystemAttribute:true
means that this is a built-in part of Vault like id
, but editable:true
means that the value itself isn’t controlled by the Vault; because the attribute is both required and editable, you will have to specify values for it when creating a document. {
"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:
relationshipType
will always be reference
when the metadata attribute is on documentsrelationshipName
is a way of identifying the relationship between the document and the objectLet’s make some API calls to get object metadata. First, we’ll get the list of objects defined in our Vault.
$ curl -X GET -H "Authorization: {SESSION_ID}" \
https://{server}/api/{version}/metadata/vobjects
{
"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.
$ curl -X GET -H "Authorization: {SESSION_ID}" \
https://{server}/api/{version}/metadata/vobjects/product__v
{
"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
},
]
}
}
Now that you understand how to read metadata attributes in your response, you’re ready to check out these tutorials:
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.
You can download Vault Loader CLI from the Vault UI, as shown below. Learn more about Vault Loader CLI in Vault Help
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.
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:
file
attribute tells Vault where to look for the source file on the FTP server. Omitting this column or leaving the value blank would create document placeholders.suppressRendition
attribute tells Vault to delay generating a viewable rendition for the document until a user views the document from the UI. This setting reduces the load on your Vault by preventing unnecessary processing.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
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
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
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.
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
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.
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}/
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.
>> 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
Now that you know how to create and download documents, check out our tutorial on querying document metadata attributes using VQL.
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.
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.
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 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.
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.
Vault enforces multiple types of rate limits:
Burst Limit is the number of API calls that your Vault can receive within a fixed 5-minute period. When you reach the burst limit, the server delays responses for the remainder of the burst-limit period. To determine the length of delay for a throttled response, check the X-VaultAPI-ResponseDelay
response header or the API Usage Logs.
Auth API Burst Limit is the number of calls that your Vault can make to /api/{version}/auth
in a one (1) minute period. When you reach 50% of the burst limit, the server delays responses for the remainder of the burst-limit period. This limit is tracked by the username
and vaultDNS
parameters and does not apply to SAML/SSO or OAuth authentication. When you reach the Auth burst limit, any additional Auth requests will fail until the next window. To determine the burst limit for your Vault or the length of delay for a throttled response, check the response headers or the API Usage Logs.
Job Status API Rate Limit is the number of calls that your Vault can make to /api/{version}/services/jobs/{job_id}
, which is one (1) call every 10 seconds. When this limit is reached, Vault returns API_LIMIT_EXCEEDED
.
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.
Vault APIs return rate limiting headers to help you monitor how many API calls you have remaining as well as possible response throttling.
X-VaultAPI-BurstLimit
: Indicates the maximum number of calls allowed in a 5-minute burst window. For example, 2000. (Included in v19.2+)X-VaultAPI-BurstLimitRemaining
: Indicates the number of API calls remaining for the current 5-minute burst window. For example, 1945. (Included in v14.0+)X-VaultAPI-ResponseDelay
: Indicates the delay, in milliseconds, of a throttled response. Only included for delayed responses. For example, 500ms. See How Does Vault Calculate Limits?. (Included in v14.0+)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.
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.
X-VaultAPI-BurstLimitRemaining
: Indicates the number of API calls remaining for the current 1-minute burst window. For example, 19.
X-VaultAPI-BurstLimit
: Indicates the maximum number of calls allowed in a 1-minute burst window. For example, 20.
X-VaultAPI-ResponseDelay
: Indicates the length of delay for a throttled response in milliseconds. For example, 2000.
Here are some best practices for reducing the number of API requests:
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.
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.
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.
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.
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.
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. |
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. |
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.
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.
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.
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
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:
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.
As an example demonstrating authentication defaulting, Miyah is cross-domain user with access to the following Vaults in her home domain:
my2019vault.veevavault.com
my2020vault.veevavault.com
my2018vault.veevavault.com
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:
vaultDNS
body parameter: my2050vault.veevavault.com
my2019vault.veevavault.com
my2016vault.veevavault.com
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 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.
When comminicating with the Vault API, CSV formatting is compliant with RFC 4180 with the following exceptions:
u+000d
) character is not supported in valuesu+0009
) character is supported in valuesu+005c
) character must be duplicated in values to act as a single backslashVault supports the following TLS cipher suites:
TLSv1.2/ECDHE-RSA-AES256-GCM-SHA384
TLSv1.2/ECDHE-RSA-AES256-SHA384
TLSv1.2/ECDHE-RSA-AES128-GCM-SHA256
TLSv1.2/ECDHE-RSA-AES128-SHA256
All other ciphers are unsupported. You must use a supported cipher to connect to Vault.
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:
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.
Generate tokens with the Document Tokens endpoint.
POST /api/{VERSION}/objects/documents/tokens
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.
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
:
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.
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.
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.
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.
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:
To reference files:
file
column to your input and enter the path/name of each file relative to the root, for example, Feb-2016-Batch/Gludacta_Brochure.pdf
.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.
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.
file
column that shows filename and location, relative to the server root.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.
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.
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:
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.
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.
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.
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.
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.
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.
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.
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.
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.
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:
data
contains nested objects with data for a single case, such as case_contact__v
.structured
array: structured
is an array containing key-value pairs of structured field data for a particular object. Click the button below to download a sample JSON intake file with only structured data.
Safety supports the following standard objects, which are nested under data
for a single case:
detail
detail
under structured
: case_identifier__v
narrative
patient
case_product__v
case_product__v
under structured
: case_product_dosage__v
case_product_indication__v
case_product_substance__v
case_assessment__v
case_assessment__v
under structured
: case_assessment_result__v
case_adverse_event__v
case_contact__v
case_cause_of_death__v
case_medical_history__v
parental_case__v
) object type.case_drug_history__v
parental_case__v
) object type. case_drug_history__v
under structured
: case_drug_history_substance__v
case_test_result__v
case_relationship__v
case_study_registration__v
case_diagnosis__v
transmission__v
transmission__v
under structured
: destination__v
destination_transmission_id__v
first_sender__v
organization__v
origin__v
origin_transmission_id__v
reason_text_long_text__v
recipient_user__v
sender_person__v
sender_user__v
sender_comments__v
transmission_profile__v
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) |
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:
__v
for standard fields or __c
for custom fields.administration_facility_id
under a case_product_dosage__v
with the facility_id
under a case_contact__v
with "object_type__v": "facility__v"
rank__v
under a case_contact__v
with "object_type__v": "facility__v"
Vault Safety imposes the following default limits on intake JSON files for each API call:
case_product__v
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.
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.
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.
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.