Skip to content
Back to Blog
Integration

HubSpot API Key Management for Apps Your Customers Install

Jun 18, 2026
SCSunny Chauhan
HubSpot API Key Management for Apps Your Customers Install

If your SaaS product connects to your customers' HubSpot accounts, the only credential that fits is an OAuth access token from an app each customer installs. HubSpot's authentication overview puts it plainly: "OAuth is required for multiple accounts." Account API keys stopped being supported in 2022, legacy private apps can't be created after October 26, 2026, and the new service keys only work inside one account. So the real work is managing many short-lived tokens, one set per customer, without leaking them or letting them expire mid-sync.

That makes token handling part of a product decision, not a settings screen. A customer-facing integration means a token store, a refresh service and an uninstall path that you run for every account, for as long as the integration exists. Appnigma's integration infrastructure is built for that layer. Its page describes letting "each customer authorize their own account from your product, with their connection managed separately," and the ability to "monitor each customer's connections." If you only need a key for scripts in your own HubSpot account, skip to the service keys row in the table below.

Updated October 2026. Checked against HubSpot's developer docs, the developer changelog and the Marketplace certification requirements on October 24, 2026. This update corrects the access token lifetime (30 minutes, not 6 hours), the API key status, the uninstall flow and the private app advice. It adds service keys, the 2026-09 token endpoints and the 2027 deadlines, and it removes a certification questionnaire list and a customer scenario we could not source.

Which HubSpot credential fits each kind of integration

HubSpot now has five things people call an "API key," and only two of them let software read a customer's CRM. The table sorts them by the job you're doing.

Your situationCredentialWho creates itLifetime
Your product connects many customers' HubSpot accountsOAuth access and refresh tokens from a developer platform appEach customer, by approving your installAccess token 30 minutes, refresh token long-term
A script or internal tool in your own accountService key (public beta)A super admin or a user with Developer tools accessUntil you rotate or delete it
An app with webhooks or app cards in one accountStatic auth token from an app with private distributionThe app's installer in that accountUntil rotated, with rotation advised every 6 months
Running the HubSpot CLIPersonal access keyEach developerUntil deactivated or rotated
Configuring certain app featuresDeveloper API keyThe app developerUsed only where a guide says so

The first row is the only one that works for a SaaS product. A service key is scoped and logged, but HubSpot says you "cannot use service keys to authenticate webhooks, make calls within a UI extension," or use other platform features. A static auth app "can be installed in a single standard account at a time," per HubSpot's app management guide. Even an OAuth app on private distribution stops at "a maximum of 10 accounts at a time." Marketplace distribution removes that cap once you're listed.

One more setting changes how you store tokens. HubSpot's user-level apps became generally available in the Fall 2026 release. They enforce "that user's exact HubSpot permissions at runtime" and need OAuth. HubSpot also notes that "existing apps using account-level access cannot currently be migrated to user-level access" today. Decide before launch, because a user-level app holds tokens per user install, so your store is keyed on account and user, not account alone.

Do HubSpot API keys still work?

No, and nothing current in HubSpot's docs suggests otherwise. HubSpot's API key sunset changelog survives as an archived copy. It says "as of July 15, 2022, we no longer allowed new API keys to be created" in any account. After November 30, 2022, keys "will no longer be supported by HubSpot," and anyone still using them does so "at your own risk." The old knowledge base article on finding your API key now redirects to the authentication overview.

The confusion comes from a parameter name. The hapikey query parameter still appears in HubSpot's docs, but only for developer API keys, which configure features of your own app such as custom channels. A developer API key can't read a customer's contacts. If you find hapikey in an old integration's code that touches CRM records, it's an account API key and needs replacing.

The 2022 replacement has since moved on too. HubSpot's private app creation changelog says creation "is disabled on October 26, 2026" for accounts created before September 28, 2026, and that "all existing legacy private apps continue to work as-is." The Fall 2026 changelog calls service keys "the replacement for legacy private apps."

DateWhat changedSource
July 15, 2022New account API keys can't be createdAPI key sunset changelog (archived)
November 30, 2022Account API keys no longer supportedAPI key sunset changelog (archived)
October 26, 2026Legacy private app creation disabled for existing accountsPrivate app creation changelog
February 16, 2027OAuth v1 API deprecatedOAuth v1 guide
March 30, 2027v4 API support endsLegacy APIs and apps changelog
September 2027Legacy public and private apps and v1 to v3 APIs unsupportedLegacy APIs and apps changelog

The last row matters most to a listed app. HubSpot's legacy APIs changelog says an app using v1 to v4 APIs after September 2027 "loses its certification status," and one still on legacy app architecture "is eligible for delisting." A token service that still calls /oauth/v1/token is one of the places that clock shows up first.

Why asking customers to paste a token doesn't scale

Some teams start with a settings field where the customer pastes a private app token or service key. It feels faster than building OAuth, and for a single design partner it works. It stops working in three ways as soon as the integration becomes a product.

The first is listing. HubSpot's certification requirements say "asking users to copy and paste OAuth codes or tokens is prohibited," and that apps "must request, manage, and refresh access tokens without user involvement." The second is the clock. Private app creation is closed, and service keys are a public beta product built for in-account use. The third is support. Every pasted key depends on one admin in the customer's account, and HubSpot's legacy private app docs warn that removing the user who created the app makes "some API calls" fail. Your support team finds out when the sync breaks, not when the admin leaves.

OAuth moves all of that to your side. The customer clicks install, approves your scopes, and your backend gets tokens it refreshes on its own. The cost is the token service described next.

Storing HubSpot OAuth tokens for many customer accounts

Each install gives you a refresh token and a 30-minute access token tied to one HubSpot account. HubSpot's developer blog is direct about storage. It says "never store tokens in plain text," to encrypt them "using a strong encryption algorithm like AES-256," and that encryption keys "should live separately from the data." It also rules out environment variables for this job, since "you can't store different tokens for different users" in them.

A few details decide whether that store survives production.

Key it by account. Store tokens under the hub_id the token response returns, and add the user ID for user-level apps. Every call your product makes should carry that ID down to the function that fetches a token, so one customer's token can never reach another customer's request.

Don't cap the column. HubSpot's token docs say access tokens "have no defined maximum size" and recommend not imposing size limits when storing them. A varchar(255) column that worked in testing can start truncating tokens later and turn every call for that account into a 401.

Keep the client secret out of logs. The client secret is one value for your whole app, so a leak affects every customer at once. The 2026-09 token endpoints take all parameters in the request body, which HubSpot says "prevents sensitive values like your client_id and client_secret from appearing in server logs." If the secret does leak, the authentication overview lets you rotate it "to ensure the old one is invalidated."

Expect the security questionnaire. Certification includes "a security questionnaire addressing questions of encryption, access controls, and token lifecycle management relating to OAuth token access." Answers are easier to write when the store, its access controls and its audit log already exist.

Refreshing tokens without failed calls

Refresh on the clock, not on errors. HubSpot's usage guidelines say apps are "responsible for storing time-to-live (TTL) data" and that "Unauthorized (401) requests are not a valid indicator that a new access token must be retrieved." Save expires_in with each token, which is 1800 seconds today, and refresh a few minutes before it runs out.

The arithmetic shows why. The figures below are a planning example built from HubSpot's documented limits, not a benchmark. A 30-minute token expires up to 48 times a day for an account your product syncs around the clock. If your code waits for a 401 before refreshing, each expiry costs one failed call. For an account where your app makes 400 calls a day, 48 failures is 12 percent. The usage guidelines say errors "shouldn't exceed 5% of your total daily requests," and certification wants an average success rate above 95 percent. The same account refreshed on a timer loses nothing.

The second failure mode is concurrency. When several workers notice an expiring token at once, each one refreshes, and they race to save different results. HubSpot's blog advises "acquire a lock in your distributed cache" before refreshing. This sketch uses the 2026-09 endpoint and assumes a store and lock you provide.

async function getAccessToken(hubId) {
  const t = await tokenStore.get(hubId);
  if (t.expiresAt - Date.now() > 5 * 60 * 1000) return t.accessToken;
  return withLock(`hubspot-refresh:${hubId}`, async () => {
    const fresh = await tokenStore.get(hubId);
    if (fresh.expiresAt - Date.now() > 5 * 60 * 1000) return fresh.accessToken;
    const res = await fetch('https://api.hubapi.com/oauth/2026-09/token', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      },
      body: new URLSearchParams({
        grant_type: 'refresh_token',
        client_id: process.env.HUBSPOT_CLIENT_ID,
        client_secret: await secrets.get('hubspot-client-secret'),
        refresh_token: fresh.refreshToken,
      }),
    });
    const data = await res.json();
    if (data.error === 'invalid_grant') {
      await tokenStore.markDisconnected(hubId);
      throw new Error(`HubSpot account ${hubId} needs to reconnect`);
    }
    if (!res.ok) throw new Error(`Token refresh failed with status ${res.status}`);
    await tokenStore.save(hubId, {
      accessToken: data.access_token,
      refreshToken: data.refresh_token || fresh.refreshToken,
      expiresAt: Date.now() + data.expires_in * 1000,
    });
    return data.access_token;
  });
}

Two lines in it carry HubSpot-specific advice. The token is re-read inside the lock, so a worker that waited doesn't refresh a second time. The code also saves whatever refresh token comes back, because the blog says a refresh may return "potentially a new refresh token" and to "always use the latest one." The reference docs call the refresh token a "long-term" credential without a published expiry, so treat invalid_grant with "refresh token is invalid, expired or revoked" as a disconnected account and stop calling it.

Handling uninstalls from both directions

An uninstall can start in your product or in HubSpot, and each needs its own path.

When a customer disconnects from your product, call HubSpot. The app uninstalls API takes a DELETE request to /appinstalls/2026-09/external-install with that account's access token, and the account's admins get an email that the app was removed. Certification requires this endpoint, plus a demo video showing a user disconnecting and the app leaving the Connected Apps page. After the call succeeds, delete the account's tokens and revoke the refresh token with POST /oauth/2026-09/token/revoke, documented in the token revocation reference.

When a customer uninstalls from inside HubSpot, your app learns about it through the webhooks journal. You subscribe to the APP_LIFECYCLE_EVENT type using a client credentials token, which authenticates as your app rather than a customer, and uninstalls arrive as event type 4-1916193. If you miss the event, the certification guidance gives a fallback. When 100 percent of requests return 401 and the refresh fails, "consider the app uninstalled and stop making requests for the account until a user re-authenticates your app."

Where Salesforce teams map this differently

Teams that already ship a Salesforce integration often expect HubSpot tokens to behave like Salesforce tokens, and the two platforms line up only partly. Both steer multi-customer integrations to an OAuth app the customer authorizes. Salesforce's REST API guide says "creating connected apps is restricted as of Spring '26" and recommends external client apps instead. The difference is refresh token lifetime. A Salesforce external client app lets each customer's admin choose a refresh token policy, from Infinite to Zero, while HubSpot publishes no expiry. A shared token service should therefore read the lifetime per platform and per customer org, instead of assuming HubSpot's behavior everywhere. A Salesforce managed package that runs Apex inside the customer's org is a different model again, since that code doesn't hold a token for the org it runs in.

Mistakes that break HubSpot token handling after launch

These come from HubSpot's docs and certification feedback, and each one shows up as failed calls for a specific customer.

  • Calling the retired /oauth/v1/token endpoint, which HubSpot deprecates on February 16, 2027.
  • Hard-coding a 6-hour token lifetime from older guides instead of reading expires_in.
  • Refreshing only after a 401, which spends your error budget on every expiry.
  • Storing tokens in a size-limited column that truncates longer tokens.
  • Keeping one shared token in an environment variable for every customer.
  • Leaving tokens in storage after an uninstall, or calling an account that already disconnected.
  • Requesting scopes you don't use. Certification requires removing "extraneous scopes," which our HubSpot OAuth scopes guide covers.

Frequently Asked Questions

Are HubSpot API keys still available?

No. HubSpot stopped creating account API keys on July 15, 2022 and ended support on November 30, 2022, so use OAuth for customer accounts or a service key inside your own account.

How long do HubSpot OAuth access tokens last?

30 minutes. The token response returns expires_in of 1800 seconds, so store it and refresh a few minutes early.

Can I use a service key for a Marketplace app?

No. Service keys work only inside the account that created them and only for REST calls, while Marketplace apps must use the OAuth authorization code flow.

Do HubSpot refresh tokens expire?

HubSpot documents refresh tokens as long-term with no published expiry, but uninstalls and revocation invalidate them. Always save the latest refresh token a response returns.

What replaced HubSpot private apps?

Service keys for scripts in your own account, and developer platform apps for anything with webhooks, UI extensions or multiple customer accounts. Existing legacy private apps keep working until the September 2027 end of support.

Can Appnigma build and run our HubSpot integration?

Yes. Appnigma's done-for-you service builds customer integrations with "ongoing maintenance included," and its marketplace apps service covers a native HubSpot app with "HubSpot listing review and certification support where eligible."

About the author

Sunny Chauhan is the co-founder and CEO of Appnigma AI, which builds and maintains customer integrations and native Salesforce and HubSpot apps for B2B SaaS teams. Before Appnigma, he was on Salesforce's AppExchange team, where he worked with more than 300 SaaS partners. He has spent close to a decade on the Salesforce platform, including work at Zennify, and holds Salesforce certifications including Platform Developer II, Platform App Builder, Administrator, Data Cloud Consultant, and AI Associate.

Sources

  1. Authentication overview and Manage apps in HubSpot, HubSpot Developers
  2. Manage OAuth tokens with the 2026-09 API and Revoke an OAuth token, HubSpot Developers
  3. Make API requests using a service key and User-level apps, HubSpot Developers
  4. Legacy private apps, HubSpot Developers
  5. Legacy private app creation sunset, Fall 2026 Spotlight and Legacy APIs and legacy apps, what's going unsupported and when, HubSpot Developer Changelog
  6. Upcoming API key sunset (archived), HubSpot Developer Changelog
  7. API usage guidelines and limits, HubSpot Developers
  8. Certification requirements and App uninstalls API, HubSpot Developers
  9. Webhooks journal API, HubSpot Developers
  10. Production-ready OAuth token management, HubSpot Developer Blog
  11. Authorization through external client apps or connected apps, Salesforce Developers

All Blogs

Bring the customer requirements and your current setup. Get a clear scope and delivery timeline to take back to them.