
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.