> ## Documentation Index
> Fetch the complete documentation index at: https://developer.vanta.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Make your first API call to Vanta

> Get an access token and use it to list documents, policies, and evidence in your Vanta tenant, filtered by compliance framework.

export const EstimatedTime = ({time, icon = "clock"}) => <div className="vanta-estimated-time" style={{
  display: "inline-flex",
  alignItems: "center",
  gap: "0.5rem",
  padding: "0.35rem 0.75rem",
  marginBottom: "1rem",
  borderRadius: "9999px",
  background: "color-mix(in srgb, #5E05C4 10%, transparent)",
  border: "1px solid color-mix(in srgb, #5E05C4 25%, transparent)",
  fontSize: "0.8125rem",
  fontWeight: 500,
  lineHeight: 1,
  color: "#5E05C4",
  whiteSpace: "nowrap"
}}>
    <Icon icon={icon} iconType="regular" size={14} color="#5E05C4" />
    <span>Estimated time: {time}</span>
  </div>;

<EstimatedTime time="10 minutes" />

By the end of this quickstart you'll have a working access token and you'll have used it to list the documents stored in your Vanta instance, filtered by compliance framework.

## Before you begin

Make sure you have:

* A Vanta account with admin access.
* A terminal or HTTP client (cURL, Postman, or your language of choice).

<Info>
  This quickstart is for **security engineers and admins** automating their own Vanta account. If you're a partner building a public integration, see the [Build an Integration quickstart](/docs/quickstart/build-integration). If you're a Vanta audit partner, see the [Conduct an Audit quickstart](/docs/quickstart/conduct-audit).
</Info>

<Steps titleSize="h3">
  <Step title="Create a Manage Vanta application">
    **Vanta Dashboard** — sign in to Vanta, open [Settings → Developer Console](https://app.vanta.com/settings/developer-console), and click **Create**.

    Choose **Manage Vanta** as the app type, then fill in:

    * **Application name** — `Demo Manage Vanta App` (or enter a name of your choosing).
    * **Application description** — `Vanta quickstart demo app`

          <img src="https://mintcdn.com/vanta/WstAJ2TKBLS7hAXq/images/52311a3-Screenshot_2024-07-31_at_6.37.37_PM.png?fit=max&auto=format&n=WstAJ2TKBLS7hAXq&q=85&s=2095ed5d81a3044f26a1ca9fa588c659" alt="Vanta Developer Console showing the Create application form with app type, name, and description fields" width="500" height="551" data-path="images/52311a3-Screenshot_2024-07-31_at_6.37.37_PM.png" />

    The OAuth `client_id` is auto-generated. Click **Generate client secret** to create the secret. Store both values securely. You can rotate the secret at any time.
  </Step>

  <Step title="Get an access token">
    From your **terminal**, exchange your client credentials for an access token. This quickstart only makes read calls, so request the minimum scope: `vanta-api.all:read`.

    <CodeGroup>
      ```bash Terminal theme={"system"}
      curl --location 'https://api.vanta.com/oauth/token' \
        --header 'Content-Type: application/json' \
        --data '{
          "client_id": "your_client_id",
          "client_secret": "your_client_secret",
          "scope": "vanta-api.all:read",
          "grant_type": "client_credentials"
        }'
      ```

      ```javascript Node.js theme={"system"}
      const response = await fetch("https://api.vanta.com/oauth/token", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          client_id: "your_client_id",
          client_secret: "your_client_secret",
          scope: "vanta-api.all:read",
          grant_type: "client_credentials",
        }),
      });
      const { access_token } = await response.json();
      ```

      ```python Python theme={"system"}
      import requests

      response = requests.post(
          "https://api.vanta.com/oauth/token",
          json={
              "client_id": "your_client_id",
              "client_secret": "your_client_secret",
              "scope": "vanta-api.all:read",
              "grant_type": "client_credentials",
          },
      )
      access_token = response.json()["access_token"]
      ```
    </CodeGroup>

    Expected response:

    ```json theme={"system"}
    {
      "access_token": "vat_your_token",
      "expires_in": 3600,
      "token_type": "Bearer"
    }
    ```

    <Info>
      **One token at a time.** Vanta only allows one active access token per application — requesting a new token immediately revokes the previous one. Tokens expire after one hour.
    </Info>

    <AccordionGroup>
      <Accordion title="Got a 401 or invalid_client?">
        Double-check the `client_id` and `client_secret` from the Developer Console. If you rotated the secret, the old one is no longer valid. Make sure your `Content-Type` header is `application/json` — Vanta's `/oauth/token` does not accept form-encoded bodies.
      </Accordion>

      <Accordion title="Got an invalid_scope error?">
        You requested a scope that isn't available to **Manage Vanta** apps. For this quickstart, request only `vanta-api.all:read`.
      </Accordion>
    </AccordionGroup>
  </Step>

  <Step title="List your frameworks">
    From your **terminal**, call `GET /v1/frameworks` to see which compliance frameworks are active in your Vanta instance, and grab a `frameworkId` to use in the next step. Replace `your_token_here` with the `access_token` from Step 2.

    <CodeGroup>
      ```bash Terminal theme={"system"}
      curl --location 'https://api.vanta.com/v1/frameworks?pageSize=10' \
        --header 'Accept: application/json' \
        --header 'Authorization: Bearer your_token_here'
      ```

      ```javascript Node.js theme={"system"}
      const response = await fetch(
        "https://api.vanta.com/v1/frameworks?pageSize=10",
        {
          headers: {
            Accept: "application/json",
            Authorization: `Bearer ${access_token}`,
          },
        }
      );
      const { results } = await response.json();
      const frameworkId = results.data[0].id;
      ```

      ```python Python theme={"system"}
      import requests

      response = requests.get(
          "https://api.vanta.com/v1/frameworks",
          params={"pageSize": 10},
          headers={
              "Accept": "application/json",
              "Authorization": f"Bearer {access_token}",
          },
      )
      framework_id = response.json()["results"]["data"][0]["id"]
      ```
    </CodeGroup>

    Expected response — note the `id` field on each framework (e.g. `soc2`, `iso27001_2022`):

    ```json theme={"system"}
    {
      "results": {
        "data": [
          {
            "id": "soc2",
            "displayName": "SOC 2",
            "shorthandName": "SOC 2",
            "description": "AICPA standardized framework...",
            "numControlsCompleted": 43,
            "numControlsTotal": 86,
            "numDocumentsPassing": 7,
            "numDocumentsTotal": 16,
            "numTestsPassing": 21,
            "numTestsTotal": 46
          }
        ],
        "pageInfo": {
          "hasNextPage": false,
          "hasPreviousPage": false,
          "startCursor": "c29jMg==",
          "endCursor": "c29jMg=="
        }
      }
    }
    ```
  </Step>

  <Step title="List documents for that framework">
    From your **terminal**, call `GET /v1/documents` and filter by the `frameworkId` you just got with the `frameworkMatchesAny` query parameter. Reuse the `access_token` from Step 2.

    <CodeGroup>
      ```bash Terminal theme={"system"}
      curl --location 'https://api.vanta.com/v1/documents?frameworkMatchesAny=soc2&pageSize=10' \
        --header 'Accept: application/json' \
        --header 'Authorization: Bearer your_token_here'
      ```

      ```javascript Node.js theme={"system"}
      const response = await fetch(
        `https://api.vanta.com/v1/documents?frameworkMatchesAny=${frameworkId}&pageSize=10`,
        {
          headers: {
            Accept: "application/json",
            Authorization: `Bearer ${access_token}`,
          },
        }
      );
      const { results } = await response.json();
      console.log(`${results.data.length} documents for ${frameworkId}`);
      ```

      ```python Python theme={"system"}
      import requests

      response = requests.get(
          "https://api.vanta.com/v1/documents",
          params={"frameworkMatchesAny": framework_id, "pageSize": 10},
          headers={
              "Accept": "application/json",
              "Authorization": f"Bearer {access_token}",
          },
      )
      documents = response.json()["results"]["data"]
      print(f"{len(documents)} documents for {framework_id}")
      ```
    </CodeGroup>

    Expected response:

    ```json theme={"system"}
    {
      "results": {
        "data": [
          {
            "id": "access-requests",
            "ownerId": "2",
            "category": "Account setup",
            "description": "Provide two examples of a recent access request and approval",
            "isSensitive": false,
            "title": "Access request ticket and history",
            "uploadStatus": "Needs document",
            "uploadStatusDate": "2024-03-17T00:00:00.000Z",
            "url": "https://example.com"
          }
        ],
        "pageInfo": {
          "hasNextPage": false,
          "hasPreviousPage": false,
          "startCursor": "YWNjZXNzLXJlcXVlc3Rz",
          "endCursor": "YWNjZXNzLXJlcXVlc3Rz"
        }
      }
    }
    ```

    <AccordionGroup>
      <Accordion title="Empty `data` array?">
        Either the framework has no documents yet, or the `frameworkId` doesn't match a framework in your instance. Re-run Step 3 and copy the `id` exactly — it's case-sensitive (e.g. `soc2`, not `SOC2`).
      </Accordion>
    </AccordionGroup>
  </Step>

  <Step title="Verify it worked">
    Pick a document from the response, copy its `url` field, and open it in your browser. The `url` is a deep link to that document's page in the Vanta dashboard, so you'll land on the same record the API just returned to you.

    Confirm that on the dashboard page:

    * The **title**, **category**, and **document** match what the API returned.
    * Open or download the document and verify it's the file your team expected to see for this evidence request.

    | Scenario       | Test input                                             | Expected result                                                                                                               |
    | -------------- | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- |
    | Success        | A document with `uploadStatus: "OK"` from the response | `url` opens the document page in Vanta; `title` / `category` match; the attached file matches what was uploaded               |
    | Common failure | Expired `access_token` (older than one hour)           | API returns `401 Unauthorized` — re-run Step 2 for a fresh token                                                              |
    | Edge case      | A document with `uploadStatus: "Needs document"`       | `url` opens the document page, but no file is attached yet — expected when no evidence has been uploaded for this requirement |
  </Step>
</Steps>

## Congratulations

You have a working Manage Vanta token and you've used it to read documents out of your Vanta instance. From here you can:

* **Create a document** with `POST /v1/documents` to track new evidence.
* **Filter further** by combining `frameworkMatchesAny` with `statusMatchesAny` to find documents that need attention.
* **Upload evidence** to an existing document via the document upload endpoint (requires the `vanta-api.documents:upload` scope).

## Next steps

<CardGroup cols={2}>
  <Card title="Create a document" href="/api-reference/documents/create-a-custom-document">
    Use the same token to add a new document to your Vanta instance.
  </Card>

  <Card title="Upload evidence to a document" href="/docs/guides/upload-a-document">
    Attach a file to an existing document in three steps.
  </Card>

  <Card title="Browse the Manage Vanta API" href="/reference/manage-vanta/overview">
    Every endpoint available to Manage Vanta apps.
  </Card>

  <Card title="Set up Postman" href="/docs/postman-setup">
    Import the Vanta collection and start testing requests in seconds.
  </Card>
</CardGroup>
