OAuth Quickstart Guide

Before you get started

Before you can start using OAuth with HubSpot, you'll need to have:

*You must be a Super Admin to install an app in a HubSpot account


How it works

HubSpot supports the OAuth 2.0 Authorization Code grant type, which can be broken down into four basic steps:

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

In this guide

Note: All code examples in this guide are written in JavaScript (Node.js)

 

Quickstart app

If this is your first time using OAuth authentication with HubSpot's APIs, we strongly recommend checking out the OAuth 2.0 Quickstart App, written in Node.js. This sample app is designed to get you started using OAuth 2.0 as quickly as possible by demonstrating all the steps outlined below in Getting OAuth 2.0 tokens

Getting OAuth 2.0 tokens

Step 1: Create the authorization URL and direct the user to HubSpot's OAuth 2.0 server

When sending a user to HubSpot's OAuth 2.0 server, the first step is creating the authorization URL. This will identify your app and define the resources (scopes) it's requesting access to on behalf of the user. The query parameters you can pass as part of an authorization URL are shown below. For more detailed information on this step, read the reference doc.

Authorization URL query parameters
Parameter Required? Description Example
client_id Yes The client ID identifies your app. Find it on your app's settings page.

7fff1e36-2d40-4ae1-bbb1-5266d59564fb

scope Yes The scopes 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

Once you've created your URL, start the OAuth 2.0 process by sending the user to it.

Examples

Using a server-side redirect:

JavaScript
// 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:

HTML
<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 showing the name of your app and a short description of the HubSpot API services it's requesting permission to access. The user can then grant access to your app.

oauth_2_grant_prompt

Note: The user installing the app must have access to all requested scopes. If they don't 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'll need to have a Super Admin install the app.

Your application doesn't do anything at this stage. Once access is 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 2, 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 be returned with a code query parameter attached. If the user doesn't grant access, no request will be sent.

Example:
JavaScript
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 receives an authorization code from the OAuth 2.0 server, it can exchange that 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, take a minute to read this 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 from 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:
JavaScript
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:

JSON
{"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 (six hours). For information on getting a new access token, see Refreshing OAuth 2.0 tokens.

Using OAuth 2.0 tokens

Once the authorization code flow is completed, your app is 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:
JavaScript
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 expire periodically. This is to make sure that if they're compromised, attackers will only have access for a short time. The token's lifespan (six hours by default) is specified in the expires_in field when an authorization code is exchanged for an 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 values below. 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 from 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:
JavaScript
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:

JSON
// Sample response
{
  "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.