Skip to main content

Documentation Index

Fetch the complete documentation index at: https://vanta.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Before you begin

This guide is for Vanta admins managing data inside their own Vanta account. You’ll need:
  • A Manage Vanta API token.
  • The token must have scopes vanta-api.all:read, vanta-api.all:write, vanta-api.documents:upload.
  • The evidence file you want to upload (PDF, image, etc.) saved locally.
Re-uploading evidence on a recurring schedule (e.g. quarterly access reviews)? Wire this flow into a cron job or CI step using the same three calls below.
1

Find the document

Your terminal — call GET /v1/documents and pick the document you want to attach a file to.
Terminal
curl 'https://api.vanta.com/v1/documents?pageSize=100&frameworkMatchesAny=soc2' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Response
{
  "results": {
    "data": [
      {
        "id": "access-requests",
        "title": "Access request ticket and history",
        "category": "Account setup",
        "overallStatus": "Needs document",
        "url": "https://app.vanta.com/documents/access-requests"
      }
    ],
    "pageInfo": { "hasNextPage": true, "endCursor": "..." }
  }
}
Copy the id field — you’ll send it as the path parameter in the next step.
Token is expired (one-hour lifetime), missing, or lacks vanta-api.all:read. Mint a fresh one — see Authentication → Tokens expire after one hour.
Filter the response client-side by title or category, paginate with pageCursor if hasNextPage is true, or copy the ID directly from the Documents page URL.
Add statusMatchesAny=Needs%20document (or Needs%20update) to narrow the response to documents that still require an upload.
2

Upload the file

Your terminalPOST /v1/documents/{documentId}/uploads as multipart/form-data with the file in the file field.
import fs from "node:fs";

const DOCUMENT_ID = "YOUR_DOCUMENT_ID"; // id from Step 1
const FILE_PATH = "./access-requests.pdf";

const form = new FormData();
form.append(
  "file",
  new Blob([fs.readFileSync(FILE_PATH)], { type: "application/pdf" }),
  "access-requests.pdf",
);
form.append("description", "Q3 access review evidence");

const res = await fetch(
  `https://api.vanta.com/v1/documents/${DOCUMENT_ID}/uploads`,
  {
    method: "POST",
    headers: { Authorization: "Bearer YOUR_TOKEN" },
    body: form,
  },
);
console.log(await res.json());
Expected response (200) — the uploaded file metadata:
{
  "id": "66a935ff0dfddd9e7c568558",
  "creationDate": "2024-07-30T18:50:39.419Z",
  "updatedDate": "2024-07-30T18:50:39.419Z",
  "deletionDate": null,
  "description": "Q3 access review evidence",
  "effectiveDate": "2024-07-30T18:50:39.177Z",
  "fileName": "access-requests.pdf",
  "title": "Manual Evidence",
  "mimeType": "application/pdf",
  "url": "https://app.vanta.com/noprobllama/doc/Manual%20Evidence-5l14b5mljzt50h3uoo82sk",
  "uploadedByUserId": null
}
The upload lands in a draft state. It won’t satisfy the document until you submit it in Step 3.
The document ID is wrong. Re-run Step 1 and copy id exactly — IDs may be human-readable (e.g. access-requests) or a Mongo-style hash (e.g. 6596e2a8f62c73fb64960581).
The request must be multipart/form-data — don’t set Content-Type manually, let your HTTP client add the boundary. Pass the file with -F (curl), files= (requests), or a FormData body (fetch).
Your token is missing vanta-api.documents:upload. This is a separate scope from vanta-api.all:write — uploads require it explicitly. Mint a new token that includes all three scopes (vanta-api.all:read, vanta-api.all:write, vanta-api.documents:upload).
3

Submit the document

Your terminalPOST /v1/documents/{documentId}/submit to move the document from draft to OK. Until you do this, auditors won’t see the new evidence.
const DOCUMENT_ID = "YOUR_DOCUMENT_ID"; // id from Step 1

const res = await fetch(
  `https://api.vanta.com/v1/documents/${DOCUMENT_ID}/submit`,
  {
    method: "POST",
    headers: { Authorization: "Bearer YOUR_TOKEN" },
  },
);
console.log(res.status);
A 200 response means the document’s overallStatus has flipped to OK and the upload is visible to auditors.
Same root cause as Step 2 — re-check the documentId you copied from Step 1.
The document has no draft uploads to submit. Re-run Step 2, then submit. You can also confirm the upload exists with GET /v1/documents/{documentId}/uploads.
Replacing stale evidence? Repeat Step 2 with the new file, then Step 3 — the latest submitted upload becomes the canonical evidence for the document.

Congratulations

You’ve attached an evidence file to a Vanta document and submitted it for review. The document’s status is now OK, the upload is captured in your audit log, and auditors can pull the file directly from Vanta.

Next steps

Assign a control owner

Make a specific user accountable for the controls this document supports.

Subscribe to webhooks

React in real time when document status or uploads change.

Try it in Postman

Import the collection and run uploads + submit against a sandbox in seconds.

Manage Vanta API reference

Browse every Manage Vanta endpoint — controls, tests, documents, people.