HubSpot returns 401 Unauthorized when it doesn't accept the credentials on a request, and 403 Forbidden when it accepts them but the token isn't allowed to reach that URL. Common reasons for a 401 are a missing or malformed header, a rotated token that has expired, a token from a deleted app, or an old API key. For a 403, start by checking the app's scopes.
The first thing to check is how the token is sent. HubSpot expects it in the Authorization header as Authorization: Bearer YOUR_TOKEN, whether it comes from a legacy private app, an app with static auth, a service key or OAuth. Then open the app's call logs and filter by response code to see which endpoints fail.
Why HubSpot rejects your token
The integration still uses an old API key
Older integrations may still use an account API key. In 2022 HubSpot told developers to move these integrations to private apps before API keys stopped being supported (HubSpot developer blog). HubSpot's old help page about API keys now redirects to its authentication overview, which has no account API keys at all. The developer API key mentioned there is for certain app features and settings. If an integration that reads or writes CRM data still sends an API key, rebuild it on one of the token types below.
The token was rotated or the app was deleted
When a super admin rotates a legacy private app token, the old one stops working, at once with Rotate and expire now, or after 7 days with Rotate and expire later. Super admins get emails about rotations, including one 24 hours before a token expires, so search the inbox before you search the code. Deleting a private app revokes its token for good. If an old copy of the token is still in a workflow secret or a config file, calls that use it fail once it expires.
OAuth access tokens are meant to expire. Each token comes with an expires_in value, and your app should use the refresh token before then. HubSpot's usage guidelines say a 401 isn't a valid sign that you need a new token, so track the expiry yourself.
The app is missing a scope
Each endpoint lists its required scopes on its API reference page or guide. HubSpot's own example is an OAuth token with only the content scope getting a 403 from the deals API, which needs crm.objects.deals.read (error handling). For a legacy private app, click Edit app on its details page and add the scope. For an app on the new developer platform with a static token, scopes live in the app's config file, and after you change them you have to reinstall the app with the Reinstall URL on its Distribution tab before they apply.
Scopes changed recently too. From September 8, 2026, HubSpot split the four remaining broad scopes, hubdb, tickets, timeline and files, into narrower ones, such as separate read and write scopes. Existing installs keep working, and HubSpot applies the update itself on each app's Auto rollout date. Turning off backward compatibility before your install URLs and scope checks use the new scopes can break live integrations (granular scopes).
The account doesn't have the feature
Which scopes an app can use depends on the account's subscription. HubSpot's example is custom object data, which only Enterprise accounts have. When an account is downgraded, a private app loses the scopes for features the account no longer has. The token string stays the same, so nothing looks different until calls start failing.
The user who created the app was removed
If the user who created a legacy private app is removed from HubSpot, some calls with its token fail with USER_DOES_NOT_HAVE_PERMISSIONS. HubSpot's fix is to rotate the token, or to add the user back if they were removed by mistake.
Which kind of token to use now
As of October 2026, these are HubSpot's options for calling its API.
| Option | Where you find it | Use it for |
|---|---|---|
| Legacy private app | Development, then Legacy apps, Auth tab | Existing integrations. Still supported, with no new app features. Super admins only |
| App with static auth | A developer project, token on the Distribution tab | New integrations installed in one account |
| Service key | Development, then Keys, then Service keys | Plain REST API calls with scopes. No webhooks or UI extensions |
| OAuth app | A developer project with your own OAuth backend | Apps installed in more than one account |
Super admins and users with the Developer tools access permission can create service keys. A static token can be viewed or rotated by a super admin or a user with a developer seat in that account.
How to fix a 401 or 403
- Confirm the request sends the token in the Authorization header with the Bearer prefix, and that no old API key is still being sent.
- Filter the app's logs by response code to see which calls fail and since when.
- For a legacy private app, send the token to
POST /oauth/v2/private-apps/get/access-token-info. The answer shows its Hub ID, creating user and scopes. - If the token was rotated, copy the current one and update every place that stores it.
- For a 403, look up the endpoint's required scopes, add any that are missing, and reinstall if it's a static auth app.
- If the app's creator was removed, rotate the token.
- If the app has the scope and the 403 continues, HubSpot says to contact its support team.
How to stop it happening again
Keep a list of each app, its owner, its scopes and every place its token is stored. HubSpot recommends rotating tokens every six months, and emails super admins about a private app token that hasn't been rotated in over 180 days. Use Rotate and expire later, so you have 7 days to update every copy. Before you remove a HubSpot user, check whether they created any private apps. If the token feeds a workflow, update the secret as well, as covered in custom code action errors. For 429 errors once the token works, read HubSpot API rate limits.
From client work
For Freedom and Glory Flags I built the NetSuite sync with NetSuite SuiteScript on one side and a HubSpot private app on the other. When I build NetSuite syncs, the private app gets access only to what the sync needs, and the code runs in the client's own accounts with no connector subscription.
If an old integration still runs on an API key, or nobody knows which app owns which token, book a free 30-minute call and I'll help you sort it out.
Questions
Are HubSpot API keys still supported?
HubSpot's usage guidelines say apps must use OAuth, or a static auth token for an app installed in a single account, and the authentication docs no longer describe account API keys.
Do I have to migrate my legacy private app?
Not right now. HubSpot still supports legacy private apps, but they don't get the latest app features, and HubSpot highly recommends building on version 2026.03 of its developer platform or migrating existing legacy apps to it.
Do I need to change my API URLs too?
HubSpot's REST APIs moved to date-based versions in 2026, such as /crm/objects/2026-09/contacts. HubSpot's legacy API migration guide says the v1 to v4 endpoints stop being supported in September 2027.
Did this fix it?
Good to hear. If something else in the portal looks off, the help centre has more fixes.
Some problems need someone to look inside the portal. Book a free 30-minute call and show me what's happening. If it needs work, you get a written scope and one fixed price.