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.

By the end of this quickstart you’ll have a private integration that pushes user accounts and custom resources into your Vanta tenant, with a Custom Test turning that data into pass/fail compliance evidence.

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).
Building a public integration to publish in the Vanta marketplace? Private integrations are single-tenant and use the simpler client_credentials grant. If you need per-customer OAuth, refresh tokens, and a marketplace listing, follow the Build a Public Integration quickstart instead.
1

Create a Private Integration

Vanta Dashboard — sign in to Vanta app, open Settings → Developer Console, and click Create.Choose Build Integrations as the app type, then select Private for the distribution. Fill in:
  • Application nameDemo Private Integration (or enter a name of your choosing).
  • Application descriptionVanta quickstart demo integration Vanta Developer Console showing the Build Integrations app creation form with Private distribution selected
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 without invalidating data you’ve already pushed.
2

Get an access token

From your terminal, exchange your client credentials for an access token. This quickstart requests two scopes: connectors.self:write-resource to push data and connectors.self:read-resource to read it back for verification.
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": "connectors.self:write-resource connectors.self:read-resource",
    "grant_type": "client_credentials"
  }'
Expected response:
{
  "access_token": "vat_your_token",
  "expires_in": 3599,
  "token_type": "Bearer"
}
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, so most integrations request a fresh token at the top of each sync run.
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.
You requested a scope that isn’t available to Build Integrations apps. Private integrations can request connectors.self:write-resource, connectors.self:read-resource, self:write-document, and self:read-document. Request only what your tool needs.
3

Push your first resource

Most private integrations start with UserAccount — Vanta’s representation of a person in an external system, used for access reviews. PUT is idempotent on uniqueId, so it’s safe to retry on network errors.
  1. Vanta Dashboard — in your private app’s Resources tab, click Add resource, choose the User Account base type, save, and copy the generated Resource ID. Every PUT references this ID so Vanta knows which resource configuration the records belong to. Resources tab in the Vanta app showing the Add resource flow with the User Account base type selected
  2. Terminal — replace your_token_here with the access_token from Step 2 and your_resource_id with the Resource ID you just copied, then push a record:
curl --request PUT 'https://api.vanta.com/v1/resources/user_account' \
  --header 'Authorization: Bearer your_token_here' \
  --header 'Content-Type: application/json' \
  --data '{
    "resourceId": "your_resource_id",
    "resources": [
      {
        "uniqueId": "user_123",
        "displayName": "Jane Doe",
        "fullName": "Jane Doe",
        "accountName": "jane.doe",
        "email": "developers@vanta.com",
        "status": "ACTIVE",
        "mfaEnabled": true,
        "mfaMethods": ["SMS", "EMAIL"],
        "authMethod": "SSO",
        "permissionLevel": "ADMIN",
        "externalUrl": "https://app.example.com/users/user_123",
        "createdTimestamp": "2026-05-05T00:00:00Z",
        "updatedTimestamp": "2026-05-05T00:00:00Z"
      }
    ]
  }'
Expected response (200 OK):
{
  "results": {
    "accepted": 1,
    "rejected": 0
  }
}
Each PUT represents the full state of resources you own. Any uniqueId you previously pushed but omit from a later PUT is marked as no longer existing in Vanta. Sync the complete set on every run.
Your access token has expired (tokens last one hour) or your app wasn’t granted the connectors.self:write-resource scope. Re-run Step 2 with the scopes shown above.
4

Sync custom resources

Use a custom resource to define your own schema and push data Vanta doesn’t model out of the box — homegrown app objects, on-prem servers, internal review records, and the like.
  1. Vanta Dashboard — open your private app’s Resources tab and create a new resource using the Custom Resource base type. Give it a name (e.g. Internal Server) and define the custom fields you want to sync to Vanta using JSON Type Definition.
    {
      "properties": {
        "name":        { "type": "string" },
        "active":      { "type": "boolean" },
        "memory":      { "type": "int32" },
        "lastUpdated": { "type": "timestamp" }
      }
    }
    
    Save and copy the generated Resource ID — you’ll reference it on every push.
  2. Terminal — push records to the custom-resource endpoint. Replace your_token_here with your access_token and your_custom_resource_id with the Resource ID you just copied. Each record includes the base fields (displayName, uniqueId, externalUrl) at the top level and your schema fields nested inside customProperties.
curl --request PUT 'https://api.vanta.com/v1/resources/custom_resource' \
  --header 'Authorization: Bearer your_token_here' \
  --header 'Content-Type: application/json' \
  --data '{
    "resourceId": "your_custom_resource_id",
    "resources": [
      {
        "displayName": "auth-prod-1",
        "uniqueId": "srv_001",
        "externalUrl": "https://app.example.com/servers/srv_001",
        "customProperties": {
          "name": "auth-prod-1",
          "active": true,
          "memory": 16384,
          "lastUpdated": "2026-05-05T00:00:00Z"
        }
      }
    ]
  }'
Custom resources don’t have built-in compliance tests — Vanta doesn’t know what “compliant” means for your schema yet. Step 5 walks through authoring a Custom Test to define that pass/fail logic.
The resourceId in your PUT body must match the ID Vanta generated when you created the custom resource in the Dashboard. Open the resource definition in the Resources tab and copy the ID exactly — it’s case-sensitive.
5

Author a Custom Test on your custom resource

The custom resource from Step 4 is now syncing data, but Vanta doesn’t yet know what “compliant” means for your schema — until you author a Custom Test, the records won’t contribute to any framework. Custom Tests are authored in the Vanta Dashboard; there is no API to create them.
Custom Tests may require a plan upgrade or add-on. See Vanta Plans and Pricing or contact your Customer Success team if the + Create custom test button isn’t visible on the Tests page.
  1. Vanta Dashboard — open Vanta app, navigate to the Tests page, and click + Create custom test.
  2. Fill in the test metadata:
    • Test name — e.g. Internal servers have ≥ 8 GiB RAM and are active.
    • Description — what the test verifies, in business terms (this is what auditors read).
    • How to fix / remediate — instructions for whoever owns a failing resource.
    • Integration — select the private integration you created in Step 1. The resource picker will then show every resource type that app syncs, including the custom resource from Step 4.
  3. Pick the resource type — choose the custom resource you defined in Step 4 (e.g. Internal Server).
  4. Use the logic builder to define the pass/fail rule for each record. Define the resource outcome as follows:
    active equals true
    AND memory >= 8192
    
    Each record you PUT is evaluated against this rule independently. If any record fails, the test fails for that resource and contributes to your framework gap. Custom Test builder in the Vanta app showing the resource picker, pass/fail logic, and evaluation preview
  5. Review the evaluation preview. Vanta runs the test against the records you’ve already synced and shows pass/fail counts plus a per-resource breakdown. If nothing appears, confirm Step 4’s PUT returned accepted: 1 (or higher).
  6. Click Create to save the test.
  7. Finalize the test so it counts toward your compliance program:
    • Map it to controls. Open the test, go to the Controls tab, click Add control, and select the controls (and therefore frameworks) the test should satisfy.
    • Assign an SLA category so failing resources have a remediation deadline.
    • Assign a test owner so failures route to the right person.
Custom Tests are immutable after creation. If you need to change the logic, name, or description later, copy the test and edit the copy — Vanta keeps the original for audit trail purposes. Lock in your rule before mapping to controls.
The Custom Test builder only shows resource types that have at least one record synced. Re-run the PUT from Step 4 to push at least one record, then refresh the + Create custom test flow. If it still doesn’t appear, confirm you selected the correct integration (Step 1’s private app) — custom resources are scoped per-app.
Either no records have been synced yet, or your scoping conditions filter them all out. Remove scoping conditions temporarily to confirm records exist, then re-add them one at a time to find the offending filter.
Custom Test logic is evaluated per record with an implicit “all records must pass” reducer (single-resource tests). One failing record fails the whole test. Open the per-resource breakdown in the test view to see which records are flagged and why.
6

Verify it worked

From your terminal, read back the resource you pushed in Step 3 to confirm you completed everything correctly.
Terminal
curl 'https://api.vanta.com/v1/resources/user_account?resourceId=your_resource_id&pageSize=10' \
  --header 'Authorization: Bearer your_token_here' \
  --header 'Accept: application/json'
Then open Vanta app:
  • Navigate to the Access page. The user you PUT should appear with the same displayName and email.
  • Open Tests → Custom, find the test you authored in Step 5, and confirm it shows the pass/fail outcome you expected for each record.
ScenarioTest inputExpected result
SuccessValid access_token after the PUT in Step 3200 OK, response data includes user_123; the user appears in the Vanta dashboard
Custom Test successCustom resource records pushed in Step 4 that satisfy the rule from Step 5Test result page shows Passing with each record listed under “Passing resources”
Auth failureExpired access_token (older than one hour)401 Unauthorized — re-run Step 2 for a fresh token
Edge caseA uniqueId you previously pushed but omitted from the latest PUTThe resource is marked as no longer existing in Vanta and disappears from the Custom Test’s evaluated set — confirms the full-state replacement model from Step 3

Congratulations

You have a working private integration — authenticating with client_credentials, pushing both built-in and custom resources into your own Vanta tenant, and evaluating that data against compliance criteria you define via Custom Tests. From here you can:
  • Schedule it. Run the sync hourly from cron, a Lambda, or your CI runner. Always request a fresh token at the start of the run.
  • Expand resource coverage. Push additional supported types (Computer, Vulnerability, BackgroundCheck, TrainingRecord, etc.) from the same app.
  • Add more Custom Tests. Layer additional pass/fail rules on the same custom resource, or copy an existing test to create a variant for a different scope.
  • Map tests to frameworks. Wire each Custom Test to the controls it satisfies so failing resources surface as gaps in SOC 2, ISO 27001, HIPAA, and any other framework you’re tracking.

Next steps

Supported resource types

Full reference of every resource type Vanta accepts out of the box.

Create a custom resource

Deep dive on defining a custom schema and pushing records.

Author a Custom Test

Turn the data you sync into compliance evidence with pass/fail logic.

Build Integrations API reference

Every endpoint available to Build Integrations apps.