Help centre / Integrations and tracking

HubSpot API 401 unauthorized or 403 forbidden: private app tokens, scopes and old API keys

Fix HubSpot API 401 and 403 errors: the token header, rotation, missing scopes, removed app creators and moving off old API keys.

By Abdur Rahim Mostafa, HubSpot consultant · Updated 26 October 2026 · 5 min read

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.

OptionWhere you find itUse it for
Legacy private appDevelopment, then Legacy apps, Auth tabExisting integrations. Still supported, with no new app features. Super admins only
App with static authA developer project, token on the Distribution tabNew integrations installed in one account
Service keyDevelopment, then Keys, then Service keysPlain REST API calls with scopes. No webhooks or UI extensions
OAuth appA developer project with your own OAuth backendApps 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

  1. Confirm the request sends the token in the Authorization header with the Bearer prefix, and that no old API key is still being sent.
  2. Filter the app's logs by response code to see which calls fail and since when.
  3. 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.
  4. If the token was rotated, copy the current one and update every place that stores it.
  5. For a 403, look up the endpoint's required scopes, add any that are missing, and reinstall if it's a static auth app.
  6. If the app's creator was removed, rotate the token.
  7. 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?

Written by Abdur Rahim Mostafa. I'm an independent HubSpot consultant with 12 years of HubSpot work. I fix and build HubSpot portals, integrations and automation for teams in the US, UK and Australia. See my case studies or find me on LinkedIn.

Can't find your fix?

Book a free 30-minute call and show me what's happening in your portal. If it needs work, you get a written scope and one fixed price.

Book a free 30-minute call