Step-by-step HubSpot OAuth guide: create a public app, exchange code for tokens, refresh access, and handle errors.
To create a HubSpot public app with OAuth 2.0 you need a HubSpot developer account, a public app with Client ID/Secret, a secure HTTPS server, and an exact redirect URL. Use the authorization code flow to exchange the code for access/refresh tokens, then refresh tokens when the access token expires.
HubSpot public apps authenticate with OAuth 2.0 Authorization Code flow.
code
.access_token
(short-lived) and a refresh_token
(long-lived).Before you start, you need:
?code=...
to it.Reference: HubSpot OAuth Guide
client_id
, redirect_uri
, scope
, and optional state
.https://yourapp.com
./oauth-callback
.Set these variables on your server or in your hosting provider secrets panel.
HUBSPOT_CLIENT_ID=your_client_id
HUBSPOT_CLIENT_SECRET=your_client_secret
HUBSPOT_SCOPES="crm.objects.contacts.read crm.objects.contacts.write"
HUBSPOT_REDIRECT_URI="https://yourapp.com/oauth-callback"
HUBSPOT_AUTH_URL="https://app.hubspot.com/oauth/authorize"
HUBSPOT_TOKEN_URL="https://api.hubapi.com/oauth/v1/token"
Send the user to HubSpot to install your app.
https://app.hubspot.com/oauth/authorize
?client_id=HUBSPOT_CLIENT_ID
&redirect_uri=https%3A%2F%2Fyourapp.com%2Foauth-callback
&scope=crm.objects.contacts.read%20crm.objects.contacts.write
&state=opaqueCsrfOrAccountHint
After consent, HubSpot redirects with ?code=...
.
Use the code once to get the first access_token and refresh_token.
curl --request POST \
--url https://api.hubapi.com/oauth/v1/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'grant_type=authorization_code' \
--data 'code=AUTH_CODE' \
--data 'redirect_uri=https://yourapp.com/oauth-callback' \
--data 'client_id=CLIENT_ID' \
--data 'client_secret=CLIENT_SECRET'
{
"access_token": "ACCESS_TOKEN",
"refresh_token": "REFRESH_TOKEN",
"expires_in": 1800,
"token_type": "bearer"
}
Store the refresh_token securely. The access token expires after expires_in seconds.
When the access token expires, refresh it.
curl --request POST \
--url https://api.hubapi.com/oauth/v1/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'grant_type=refresh_token' \
--data 'refresh_token=REFRESH_TOKEN' \
--data 'client_id=CLIENT_ID' \
--data 'client_secret=CLIENT_SECRET'
Replace REFRESH_TOKEN, CLIENT_ID, and CLIENT_Secret with your real values. This request returns a new access token. Continue using the same refresh token unless HubSpot issues a new one.
https://app.hubspot.com/oauth/authorize
with client_id, redirect_uri, scope.https://api.hubapi.com/oauth/v1/token
for both initial exchange and refresh.Q: How long does a HubSpot access token last?
A: Typically 30 minutes (expires_in: 1800
).
Q: Do refresh tokens expire?
A: They can be revoked if scopes change or the app is uninstalled. Otherwise, they are long-lived.
Q: Can I use one refresh token for multiple accounts?
A: No. Each HubSpot account generates a unique refresh token.