OAuth 2.0 Quickstart Guide

HubSpot supports the OAuth 2.0 Authorization Code grant type, which involves several steps:

  1. The application opens a browser to send the user to the HubSpot OAuth 2.0 server
  2. The user reviews the requested permissions, and grants access to the application
  3. The user is redirected back to the application with an authorization code in the query string
  4. The application sends a request to the OAuth 2.0 server to exchange the authorization code for an access token

The sections listed below detail the usage of OAuth 2.0 with HubSpot:

Note: The code examples in this section are written in JavaScript (Node.js)

Quickstart

If this is your first time using OAuth authentication with the HubSpot API, we strongly recommend checking out the OAuth 2.0 Quickstart App, written in Node.js. We've designed the app to get you started using OAuth 2.0 as quickly as possible: It demonstrates all of the steps outlined below in Getting OAuth 2.0 tokens. For a more detailed look at each step of the OAuth 2.0 process, please check out the reference docs for each step.

Get the OAuth 2.0 Quickstart App here

Getting OAuth 2.0 tokens

Prerequisites

Before beginning the steps for using OAuth 2.0 with HubSpot, you should first:

  1. Create a free HubSpot Developer Account
  2. Create an app

Step 1: Direct to HubSpot's OAuth 2.0 Server

When sending the user to HubSpot's OAuth 2.0 server, first step is to create the authorization URL. This will identify your app, and define the resources that it's requesting access to on behalf of the user. The query parameters that you can pass as part of an authorization URL are shown below; for more detailed information on this step, check out the reference doc.

Parameter Required? Description Example
client_id Yes The Client ID, which identifies your app. It can be found in the settings page for your app. 7fff1e36-2d40-4ae1-bbb1-5266d59564fb
scope Yes The scopes that your application is requesting, separated by URL-encoded spaces contacts%20social
redirect_uri Yes The URL that the user will be redirected to after they authorize your app for the requested scopes. For production applications, https is required https://www.example.com/auth-callback
optional_scope No The scopes that are optional for your app, and will be dropped if the selected HubSpot portal does not have access to those products automation

To start the OAuth 2.0 process, send the user to the authorization URL.

Example:

Using a server-side redirect:

// Build the auth URL
const authUrl =
  'https://app.hubspot.com/oauth/authorize' +
  `?client_id=${encodeURIComponent(CLIENT_ID)}` +
  `&scope=${encodeURIComponent(SCOPES)}` +
  `&redirect_uri=${encodeURIComponent(REDIRECT_URI)}`;

// Redirect the user
return res.redirect(authUrl);

Using an HTML link:

<a href="https://app.hubspot.com/oauth/authorize?scope=contacts%20social&redirect_uri=https://www.example.com/auth-callback&client_id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">Install</a>

Step 2: HubSpot prompts user for consent

HubSpot displays a consent window to the user that shows the name of your app and a short description of each of the HubSpot API services that it's requesting permission to access. The user can then grant access to your app.

oauth_2_grant_prompt

Note: The user who installs the app must have access to all scopes that are being requested in their hub. If they do not have the required access, the installation will fail and they will be directed to an error page. If a user sees this permissions error page, they will need to work with a super admin user, and have a super admin install the app.

Your application doesn't do anything at this stage. When access has been granted, the HubSpot OAuth 2.0 server will send a request to the callback URI defined in the authorization URL.

Step 3: Handle the OAuth 2.0 server response

When the user has completed the consent prompt from step 3, the OAuth 2.0 server sends a GET request to the redirect URI specified in your authentication URL. If there are no issues and the user approves the access request, the request to the redirect URI will have a code query parameter attached when it's returned. If the user doesn't grant access, no request will be sent.

Example:

app.get('/oauth-callback', async (req, res) => {
  if (req.query.code) {
    // Handle the received code
  }
});

Step 4: Exchange authorization code for tokens

After your app has received an authorization code from the OAuth 2.0 server, it can exchange the code for an access and refresh token by sending a URL-form encoded POST request to https://api.hubapi.com/oauth/v1/token with the values shown below; for more detailed information on this step, check out the reference doc.

Parameter Description Example
grant_type Must be authorization_code authorization_code
client_id Your app's Client ID 7fff1e36-2d40-4ae1-bbb1-5266d59564fb
client_secret Your app's Client Secret 7c3ce02c-0f0c-4c9f-9700-92440c9bdf2d
redirect_uri The redirect URI that was used when the user authorized your app https://www.example.com/auth-callback
code The authorization code received from the OAuth 2.0 server 5771f587-2fe7-40e8-8784-042fb4bc2c31

Example:

const formData = {
  grant_type: 'authorization_code',
  client_id: CLIENT_ID,
  client_secret: CLIENT_SECRET,
  redirect_uri: REDIRECT_URI,
  code: req.query.code
};

request.post('https://api.hubapi.com/oauth/v1/token', { form: formData }, (err, data) => {
  // Handle the returned tokens
}

The body of the token response will be JSON data with the form:

{
  "refresh_token": "6f18f21e-a743-4509-b7fd-1a5e632fffa1",
  "access_token": "CN2zlYnmLBICAQIYgZXFLyCWp1Yoy_9GMhkAgddk-zDc-H_rOad1X2s6Qv3fmG1spSY0Og0ACgJBAAADAIADAAABQhkAgddk-03q2qdkwdXbYWCoB9g3LA97OJ9I",
  "expires_in": 21600
}

Note: The access token will expire after the number of seconds given in the expires_in field of the response (6 hours). For information on getting a new access token, see Refreshing OAuth 2.0 tokens

Now that you’ve completed the OAuth Authorization flow and retrieved an access token, you can make calls to HubSpot's API on behalf of the user. The next sections will go into detail on how to use the access token and how you can request a new one when it expires.

Using OAuth 2.0 tokens

Once the authorization code flow has been completed, your app is now authorized to make requests on behalf of the user. To do this, provide the token as a bearer token in the Authorization HTTP header. Specific details can be found in the reference doc.

Example

request.get('https://api.hubapi.com/contacts/v1/lists/all/contacts/all?count=1',
  {
    headers: {
      'Authorization': `Bearer ${ACCESS_TOKEN}`,
      'Content-Type': 'application/json'
    }
  },
  (err, data) => {
    // Handle the API response
  }
});

Refreshing OAuth 2.0 tokens

OAuth access tokens will expire after a certain period of time. This is to make sure that if they are compromised, attackers will only have access for a short period. The token's lifespan is specified in the expires_in field when an authorization code is exchanged for an access token, which is 6 hours by default. To get a new access token, your app can exchange the received refresh token for a new access token by sending a URL-form encoded POST request to https://api.hubapi.com/oauth/v1/token with the following values; for more detailed information on this step, check out the reference doc.

Parameter Description Example
grant_type Must be refresh_token refresh_token
client_id Your app's Client ID 7fff1e36-2d40-4ae1-bbb1-5266d59564fb
client_secret Your app's Client Secret 7c3ce02c-0f0c-4c9f-9700-92440c9bdf2d
redirect_uri The redirect URI that was used when the user authorized your app https://www.example.com/auth-callback
refresh_token The refresh token received when the user authorized your app b9443019-30fe-4df1-a67e-3d75cbd0f726

Example

const formData = {
  grant_type: 'refresh_token',
  client_id: CLIENT_ID,
  client_secret: CLIENT_SECRET,
  redirect_uri: REDIRECT_URI,
  refresh_token: REFRESH_TOKEN
};

request.post('https://api.hubapi.com/oauth/v1/token', { form: formData }, (err, data) => {
  // Handle the returned tokens
}

The body of the token response will be JSON data with the form:

{
  "refresh_token": "6f18f21e-a743-4509-b7fd-1a5e632fffa1",
  "access_token": "CN2zlYnmLBICAQIYgZXFLyCWp1Yoy_9GMhkAgddk-zDc-H_rOad1X2s6Qv3fmG1spSY0Og0ACgJBAAADAIADAAABQhkAgddk-03q2qdkwdXbYWCoB9g3LA97OJ9I",
  "expires_in": 21600
}

The new access token can then be used to make calls on behalf of the user. When the new token expires, you can follow the same steps again to retrieve a new one.

For more detail on any part of HubSpot's OAuth 2.0 process, check out the reference docs listed below: