Implement OAuth

Connectors uses OAuth to let users authorize your application to send data on their behalf.

To get started, copy your OAuth Client ID and client secret from the application details page. Make sure to store these in a safe place.

Register a redirect URI

To implement OAuth, you’ll need to register one or more redirect URIs. When a user authorizes your application, they will be redirected to your redirect URI, from which your application can obtain an OAuth access token.


URI format

All redirect URIs:

  • Must be valid HTTPS URLs. The only exception is HTTP urls for localhost and, which we allow for ease of development. (These two hostnames also accept custom ports.)
  • Can contain query parameters, but must not contain URL fragments (e.g. ‘#’).

Example allowed redirect URIs:

You can configure redirect URIs on the developer console. Ensure your app is listening for requests on this URI before moving onto the next step.

Initiate the OAuth flow

When linking, your end user will need to authorize you to access their Vanta account. To do this, redirect your user’s browser to the following URL with all query parameters described below:


This is the only request to All subsequent requests are to

  • client_id: this can be found on the developer console.
  • scope: a space-separated list of scopes. See Scopes below.
  • state: An opaque string that identifies this OAuth request in your system. This is primarily used to prevent CSRF attacks. Learn more about the state parameter here.
  • redirect_uri: Where Vanta should redirect your user after they authorize your application. This must match a redirect_uri registered in the developer console. (See Registering redirect URIs .
  • source_id: A string unique identifier for the user’s account within your application. An example might be an accountId or a companyId. We use this information to allow multiple accounts within your application to be connected to the same Vanta account - each provisioned access token is scoped to the source_id provided here. We strongly recommend making this human readable, as it can be used to display to users to understand which account data is coming from.
  • response_type: This should always be set to "code".



Scopes define the set of permissions your application can request. We support the following scopes:

  • connectors.self:write-resource - Allows your application to send resources to Vanta on behalf of your users.
  • connectors.self:read-resource - Allows your application to read the resources you previously sent to Vanta. Useful for debugging.
  • self:write-document- Allows your application to upload documents to Vanta on behalf of your users.
  • self:read-document- Allows your application query users' evidence requests including documents you previously uploaded.

See Send data to determine which scopes to pick. We recommend requesting the latter two scopes if your application will use the GraphQL API to upload documents; otherwise, use the first two scopes.

A full authorization URL might look like this:

Once the user is redirected to the URL, they'll see a page like this:

After clicking Allow, they will be sent to the specified redirect_uri, with the following query parameters added:

  • code: An authorization code that you can use to exchange for an access token associated with this user.
  • state: The same value that you provided in the initial request. You must check this value matches the value provided on the initial redirect.

Exchange an authorization code for an access token

Once the user is redirected back to the specified redirect_uri, you must exchange the code for an access token. This access token will be used for future requests to access Vanta on behalf of the user.


You must complete the exchange within 30 seconds of the code being issued. After that point, the code will become invalid and the user will have to reauthorize your application.

To perform this token exchange, submit a POST request to the following URL with the information below in the body:

  • client_id: this can be found on the developer console.
  • client_secret: this was copied when you first created your application. (Ensure this is stored securely on your server.)
  • code: The code you received earlier
  • redirect_uri: The same redirect_uri from the original authorization request.
  • source_id: The same source_id from the original authorization request.
  • grant_type: This should always be set to "authorization_code".

An example curl command:

curl -X POST -H 'Content-Type: application/json' -d \
  "client_id": "vci_ed029fd113f5b842566696a09f4708b75c61b26eaa936920",
  "client_secret": "vcs_my_client_secret",
  "code": "vac_authorization_code",
  "source_id": "acct1234",
  "redirect_uri": "",
  "grant_type": "authorization_code"

You’ll receive the following response:

  "access_token": "[some_access_token]"`,
  "refresh_token": "[some_refresh_token]",
  "expires_in": 3600,
  "token_type": "Bearer"
  • access_token is used in future requests to send data to Vanta on behalf of this specific user.
  • refresh_token is used to request new access tokens.
  • expires_in is in seconds and describes when the generated access token will expire (currently 1 hour).

Both access_token and refresh_token are sensitive and should be stored securely in your database.

Refresh access tokens

After an access token expires, it will no longer function and a new access token will need to be generated via a refresh request using the refresh_token above.

To perform this refresh, submit a POST request to the following URL with the information below in the body:

  • client_id: this can be found on the developer console.
  • client_secret: this was copied when you first created your application. (Ensure this is stored securely on your server.)
  • refresh_token: The refresh token.
  • grant_type: This should always be set to "refresh_token".
curl -X POST -H 'Content-Type: application/json' -d \
  "client_id": "vci_ed029fd113f5b842566696a09f4708b75c61b26eaa936920",
  "client_secret": "vcs_my_client_secret",
  "refresh_token": "vrt_some_refresh_token",
  "grant_type": "refresh_token"

You'll receive an identical response to the token exchange response. Ensure you store the new refresh_token as that will be used for the next token refresh.

Disconnecting integrations via the Suspend API

If a user wants to disconnect your integration within your app, you can use the suspend API endpoint to ensure Vanta cleans up on our end. This will disconnect your integration in the user's Vanta account, and revoke the provided access or refresh token for a specific user.

To do so, send a POST request to the following URL with the arguments below:

  • client_id:: the client id of the specific application for which you wish to revoke the token.
  • client_secret: the client secret for this application.
  • token: the access or refresh token you wish to revoke for the specified user.

Upon completion of the request, the application will return a 200 response. This for both cases where the token is successfully revoked and the case where the token is not found. If the token is not associated with the provided clientId/secret, a 401 Unauthorized will be returned.

Example request:

  "token": "sample", // REQUIRED
  "client_id": "id", // REQUIRED
  "client_secret": "secret" // REQUIRED


Status: 200

Error codes

We show error codes in case there are errors during OAuth linking. This helps you debug issues during the authentication flow in development and production, without showing inscrutable error messages to our shared customers.

1The initial redirect to Vanta does not have the required query parameters specified.
2Invalid scopes defined.
3Invalid responseType code passed.
4There was an error loading the registered application.
5The registered application could not be found. This could be due to an incorrect client_id.
6Invalid redirect URI - the passed in redirect URI has not been specified as an allowed redirect URI in the application's console page.

What’s Next