Build Integrations API — push resource data and evidence into Vanta tenants. For partner built integrations and private integrations.
The Build Integrations API is for applications that send data into Vanta on behalf of a customer. It powers Vanta’s marketplace integrations and any private integration you build for your own tenant. Use it to ingest user accounts, devices, vulnerabilities, training records, background checks, and arbitrary custom resources.
This API is the only Vanta API available to partners and is the right choice for any app that ships data into Vanta.
You are…
Use this API to…
A partner / ISV building a marketplace integration
Push your product’s data (user accounts, devices, vulnerabilities, etc.) into your customers’ Vanta tenants. This is the only API partners can use — partners cannot access the Manage Vanta API.
A Vanta customer building a private integration
Connect a homegrown app, on-prem system, or unsupported SaaS tool to your own Vanta tenant.
A Vanta customer syncing data Vanta doesn’t natively cover
Automating workflows inside your own Vanta tenant — assigning control owners, querying tests, managing vendors and personnel? Use the Manage Vanta API instead. (Note: the Manage Vanta API is not available to partners.)
All Build Integrations apps authenticate with OAuth 2.0 at the same token endpoint. The grant type depends on how your app is distributed:
Private integration — single-tenant, used only inside your own Vanta account. Uses client_credentials. Start here if you’re building for your own tenant.
Public integration — listed in the Vanta marketplace, installable by any customer. Uses authorization_code with refresh tokens, one set per customer authorization.
Grant Type: client_credentialsYour server holds the client_id / client_secret and exchanges them directly for an access_token scoped to your own Vanta tenant.Request body
No refresh_token is issued. Requesting a new token with the same client_id / client_secret immediately revokes the previous one — re-mint just before each sync run.To revoke access, rotate the client_secret in the Developer Console (this invalidates active tokens immediately) or delete the application. For the full step-by-step setup, see the Build a Private Integration quickstart.
Grant Type: authorization_codeA customer authorizes your app in the browser at https://app.vanta.com/oauth/authorize, and Vanta redirects back to your redirect_uri with a short-lived code (valid for 30 seconds). Your server then exchanges the code for a per-customer access_token + refresh_token pair.
The authorize redirect is the only flow that touches app.vanta.com — all token exchanges and API calls go to api.vanta.com. For Vanta Gov, use app.vanta-gov.com and api.vanta-gov.com. For the full authorize-redirect flow (including state validation and source_id semantics), see the Build a Public Integration quickstart.
Request body
Field
Type
Required
Description
client_id
string
yes
OAuth client ID from your public app.
client_secret
string
yes
OAuth client secret from your application.
code
string
yes
Authorization code from the redirect callback. Expires 30 seconds after issuance.
source_id
string
yes
Must match the source_id you sent on the initial authorize redirect — your internal account identifier for the user.
redirect_uri
string
yes
Must exactly match the redirect_uri you sent on the initial authorize redirect, and must be registered in the Developer Console.
Store both tokens encrypted at rest, keyed on your internal customer identifier (the same value you used as source_id). Each customer authorization is independent — re-running the flow for the same source_id revokes that customer’s previous tokens, but different customers get separate, isolated token pairs.
When the access token expires (1 hour), exchange the refresh_token for a new pair. Every refresh rotates the refresh_token; the previous one stays valid for 3 hours to tolerate transient failures — persist the new one immediately.
Returns the same 200 OK response shape as the initial exchange (new access_token + new refresh_token).
Configure automatic retries on 5xx responses and network errors during refresh. If your refresh handler crashes after issuing the request but before saving the new refresh_token, the old one still works for up to 3 hours — but only if you actually retry.
Returns 200 OK with an empty body {}. Idempotent — calling it on an already-revoked token still returns 200. Returns 401 if the token doesn’t belong to this client_id.For grant-type tradeoffs, credential hygiene, and the rest of the foot-guns, see Authentication concepts.
Build Integrations endpoints follow a resource_type pattern:
Method
Endpoint
Use
PUT
/v1/resources/<type>
Idempotent upsert by uniqueId. Push the full set of resources you own on a periodic schedule (typically hourly).
GET
/v1/resources/<type>
Read back resources you previously pushed. See Pagination for response shape.
PUT is a “state of the world” sync — any resource you previously pushed but omit from a later PUT is treated as deleted. There is no separate DELETE endpoint. PUT is safe to retry on network errors; to sync a large dataset, batch resources into multiple PUT calls.See the resource endpoints in the sidebar for the full list of supported types and their schemas. For anything not natively supported, use the custom resource type.
Build Integrations GET /v1/resources/<type> endpoints are not paginated. Each request returns the full list of resources for the given type in a single resources array:
{ "resources": [ /* ... */ ]}
There are no pageSize, pageCursor, or pageInfo fields. To sync a large dataset, use the corresponding PUT /v1/resources/<type> endpoint to push resources to Vanta in batches.
Each PUT /v1/resources/<type> request is capped at:
Limit
Value
Maximum resources per PUT
10,000
Maximum request body size
10 MB
Because PUT is a “state of the world” sync, every resource you want Vanta to retain for a given resource_type must arrive in a single request — a follow-up PUT to the same type replaces the previous payload rather than appending to it. You can split work across resource types (a separate PUT per type), but not within one.If a payload approaches either cap, scope the sync down to fewer resources to avoid the payload limit.s
Sync only the records you need to act on. This is most relevant for vulnerability resource types (PackageVulnerabilityConnectors, ApiEndpointVulnerabilityConnectors, StaticAnalysisCodeVulnerabilityConnectors), where scanners often emit thousands of findings spanning Critical, High, Medium, and Low CVEs alongside Known malware and Protestware / potentially unwanted behavior alerts. Customers overwhelmingly take action on Critical and High in Vanta, and those are the severities that drive compliance monitoring. Sending only Critical and High keeps payloads well under the limit and matches what Vanta’s own native scanner integrations do.
Let customers pick severities at install time. For public integrations, expose a severity selector in your install or settings UI so customers opt into what they want synced. Defaulting to Critical and High covers the common case; customers with specific framework requirements can broaden the set themselves.
The same scope-down pattern applies to Computer resources when devices carry large installed-application inventories — sync only the security-relevant applications (password managers, antivirus, etc.) rather than the full list.