Upload a document

Upload a file for a document using Vanta API

Uploading a File for a Document

In this guide we'll walkthrough how to upload a document to Vanta. In order to do this, we'll need to get the evidence Id of document. You can find the document Id of your Document in the URL while viewing the Document in Vanta, Or you can list and filter your existing Documents via the List Documents Endpoint.

Steps:



List Documents Endpoint - Get a Document Id

We'll be using the List Documents endpoint to return a list of filtered documents, and acquire the Id of the Document we want to upload a new file to.

Endpoint:

/documents

Query Parameters:

  • pageSize (<number>): An integer value that specifies the number of resources to return per page. This parameter controls the size of each page in paginated responses.

  • pageCursor (<string>): A string value used to navigate through pages of results. This parameter holds the cursor for the current page, allowing the API to fetch the next set of results.

  • frameworkMatchesAny (<string>): Includes all documents that match the provided framework ID in frameworkMatchesAny. This parameter is used to filter documents based on specified frameworks. Use multiple frameworkMatchesAny parameters to filter by multiple frameworks.

  • statusMatchesAny (<string>): Includes all documents that match the status value in statusMatchesAny. Possible values: Needs document, Needs update, Not relevant, OK. This parameter is used to filter documents based on specified statuses. Use multiple statusMatchesAny parameters to filter multiple statuses.


List Documents - Code Example

curl --location 'https://api.vanta.com/v1/documents?pageSize=10&pageCursor=%3Cstring%3E&frameworkMatchesAny=soc2' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer vat_YOUR_TOKEN'
const myHeaders = new Headers();
myHeaders.append("Accept", "application/json");
myHeaders.append("Authorization", "Bearer vat_YOUR_TOKEN");

const requestOptions = {
  method: "GET",
  headers: myHeaders,
  redirect: "follow"
};

fetch("https://api.vanta.com/v1/documents?pageSize=10&pageCursor=<string>&frameworkMatchesAny=soc2", requestOptions)
  .then((response) => response.text())
  .then((result) => console.log(result))
  .catch((error) => console.error(error));
const axios = require('axios');

let config = {
  method: 'get',
  maxBodyLength: Infinity,
  url: 'https://api.vanta.com/v1/documents?pageSize=10&pageCursor=<string>&frameworkMatchesAny=soc2',
  headers: { 
    'Accept': 'application/json', 
    'Authorization': 'Bearer vat_YOUR_TOKEN'
  }
};

axios.request(config)
.then((response) => {
  console.log(JSON.stringify(response.data));
})
.catch((error) => {
  console.log(error);
});

import requests

url = "https://api.vanta.com/v1/documents?pageSize=10&pageCursor=<string>&frameworkMatchesAny=soc2"

payload = {}
headers = {
  'Accept': 'application/json',
  'Authorization': 'Bearer vat_YOUR_TOKEN'
}

response = requests.request("GET", url, headers=headers, data=payload)

print(response.text)


List Documents- Example Response

{
    "results": {
        "pageInfo": {
            "endCursor": "NjYzZDMxZWNmM2E1NjVmYTJkMWNmNGVi",
            "hasNextPage": true,
            "hasPreviousPage": false,
            "startCursor": "NjU5NmUyYThmNjJjNzNmYjY0OTYwNTgx"
        },
        "data": [
            {
                "id": "6596e2a8f62c73fb64960581",
                "title": "123",
                "description": "123456789",
                "category": "Custom",
                "isSensitive": false,
                "ownerId": null,
                "overallStatus": "Needs document",
                "uploadStatusDate": "2024-01-31T22:44:31.612Z",
                "url": "https://app.vanta.com/documents/6596e2a8f62c73fb64960581"
            },
            {
                "id": "access-requests",
                "title": "Access request ticket and history",
                "description": "Provide two examples of a recent access request and approval (ticket, email etc) to grant employee access to a critical or privileged system. An example of a system would be any system vital to the functioning of internal and external business, such as your HRIS (e.g., BambooHR), your infrastructure cloud platform (e.g., AWS), or CI/CD platform (e.g., Jenkins) and requires an additional level of role-based access control to operate various functionality within the system itself (e.g., regular user, editor, admin, super admin).\n \nGuidance: The best practice is to track and document approvals through tickets. However, if tickets aren't being utilized, email threads and/or a manual access request form may also be acceptable. Here's a sample access request form: [Google docs template](https://docs.google.com/document/d/1FGyQmCxa25SEUM0-HrZmIUqhwIUr-uJEX7hSps5QvJ4/copy?usp=sharing) / [Docx template](https://docs.google.com/document/d/1FGyQmCxa25SEUM0-HrZmIUqhwIUr-uJEX7hSps5QvJ4/export?format=docx).",
                "category": "Account setup",
                "isSensitive": false,
                "ownerId": "635325e060e08536d83d79d9",
                "overallStatus": "OK",
                "uploadStatusDate": "2024-07-30T19:12:46.567Z",
                "url": "https://app.vanta.com/documents/access-requests"
            },
            {
                "id": "62d789cf52ee2e7d66cea339",
                "title": "Alex New Document",
                "description": "this is a new document",
                "category": "Custom",
                "isSensitive": false,
                "ownerId": "63290abcd8cb38df28c4c738",
                "overallStatus": "Needs document",
                "uploadStatusDate": "2024-06-29T16:29:25.550Z",
                "url": "https://app.vanta.com/documents/62d789cf52ee2e7d66cea339"
            },
            {
                "id": "anonymous-communication-channel",
                "title": "Anonymous whistleblower channel",
                "description": "Provide a screenshot or link from your anonymous whistleblower channel.\n \nGuidance: For additional information on how to implement an anonymous whistleblower channel, see this guiding document: [Google docs template](https://docs.google.com/document/d/1GnP0X6uGxIefFtNpyn-d1SagZ6mazc7LGTY_-GIONNw/copy?usp=sharing) / [Docx template](https://docs.google.com/document/d/1GnP0X6uGxIefFtNpyn-d1SagZ6mazc7LGTY_-GIONNw/export?format=docx).",
                "category": "Policies",
                "isSensitive": false,
                "ownerId": null,
                "overallStatus": "Needs document",
                "uploadStatusDate": null,
                "url": "https://app.vanta.com/documents/anonymous-communication-channel"
            }
        ]
    }
}

We'll be using the access-requests Document for this example.


List Documents - Response Schema

Below is a bullet list explaining each property in the List Documents response body:

results: Contains the main result data.

  • pageInfo: Information about pagination.
    • endCursor: The cursor for the end of the current page.
    • hasNextPage: Boolean indicating if there are more pages.
    • hasPreviousPage: Boolean indicating if there are previous pages.
    • startCursor: The cursor for the start of the current page.

data: An array of document objects.

  • Document Object:
    • id: A unique identifier for the document.
    • title: The title of the document.
    • description: A brief description of the document.
    • category: The category of the document.
    • isSensitive: Boolean indicating if the document is sensitive.
    • ownerId: The unique identifier for the owner of the document (null if no owner).
    • overallStatus: The current status of the document (e.g., "Needs document").
    • uploadStatusDate: The date and time when the document's upload status was last updated.
    • url: The URL to access the document.



Upload File for Document Endpoint - Upload Document

Now that we have the Id of the document we wish to upload a file to, We'll make a request to the Upload file for Document endpoint using the document Id in the Query Parameters.

Endpoint:

/documents/:id/uploads

Path Variables:

  • id (<string> - Required): The unique identifier for the Document.

Request Body:

  • file (<Base64string> - Required): The base64 encoded file sent in the multipart/form-data.
{'file': '<Base64string>'}

Upload Document - Code Example

curl --location 'https://api.vanta.com/v1/documents/access-requests/uploads' \
--header 'Content-Type: multipart/form-data' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer vat_YOUR_TOKEN' \
--form 'file="<Base64string>"'
const fetch = require('node-fetch');
const FormData = require('form-data');
const fs = require('fs');

const url = "https://api.vanta.com/v1/documents/access-requests/uploads";

const form = new FormData();
const filePath = './test-file.pdf';
form.append('file', fs.createReadStream(filePath), {
    filename: 'test-file.pdf',
    contentType: 'application/pdf'
});

const headers = {
    "Accept": "application/json",
    "Authorization": "Bearer vat_YOUR_TOKEN"
};

// Merge headers from form-data
const formHeaders = form.getHeaders();
const combinedHeaders = { ...headers, ...formHeaders };

fetch(url, {
    method: 'POST',
    body: form,
    headers: combinedHeaders
})
.then(response => response.text())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
const axios = require('axios');
const FormData = require('form-data');
let data = new FormData();
data.append('file', '<base64-string>');

let config = {
  method: 'post',
  maxBodyLength: Infinity,
  url: 'https://api.vanta.com/v1/documents/access-requests/uploads',
  headers: { 
    'Content-Type': 'multipart/form-data', 
    'Accept': 'application/json', 
    'Authorization': 'Bearer vat_YOUR_TOKEN', 
    ...data.getHeaders()
  },
  data : data
};

axios.request(config)
.then((response) => {
  console.log(JSON.stringify(response.data));
})
.catch((error) => {
  console.log(error);
});

import requests

url = "https://api.vanta.com/v1/documents/access-requests/uploads"

payload = {}  
getFiles = open("./test-file.pdf", "rb")
files = {
    "file": ("test-file.pdf", getFiles, "application/pdf")
} # file path, file handler, file type

headers = {
    "Accept": "application/json",
    "Authorization": "Bearer vat_YOUR_TOKEN",
}

response = requests.request("POST", url, headers=headers, data=payload, files=files)

print(response.text)

getFiles.close()


Upload Document- Example Response

{
    "id": "66a935ff0dfddd9e7c568558",
    "creationDate": "2024-07-30T18:50:39.419Z",
    "updatedDate": "2024-07-30T18:50:39.419Z",
    "deletionDate": null,
    "description": "",
    "effectiveDate": "2024-07-30T18:50:39.177Z",
    "fileName": "test-file.pdf",
    "title": "Manual Evidence",
    "mimeType": "application/pdf",
    "url": "https://app.vanta.com/noprobllama/doc/Manual%20Evidence-5l14b5mljzt50h3uoo82sk",
    "uploadedByUserId": null
}

To confirm the file was uploaded successfully, we can view the document in Vanta:

Upload Document - Response Schema

Below is a bullet list explaining each property in the Upload Document response body:

  • id: The unique identifier for the document.
  • creationDate: The date and time when the document was created.
  • updatedDate: The date and time when the document was last updated.
  • deletionDate: The date and time when the document was deleted, if applicable (null if not deleted).
  • description: A brief description of the document.
  • effectiveDate: The date and time when the document became effective.
  • fileName: The name of the file associated with the document.
  • title: The title of the document.
  • mimeType: The MIME type of the document, indicating its file format.
  • url: The URL to access the document.
  • uploadedByUserId: The unique identifier for the user who uploaded the document (null if not specified).

We can view the document itself by following the url returned in the Upload Document response body: