HubSpot Legacy Private App Creation Is Ending: Service Keys vs Project-Based Apps
HubSpot is permanently removing the account-UI flow for creating new legacy private apps. For HubSpot accounts created on or after 28 September 2026, creation is disabled from that date. Accounts created earlier keep the old creation flow until 26 October 2026. Existing legacy private apps continue to work for now.
The replacement is not one universal credential. HubSpot now expects teams to choose based on what the integration actually does:
- Service Key for account-level, system-to-system REST API access that does not need webhooks or HubSpot UI features.
- Project-based private app when the integration needs webhooks, UI extensions, app pages, serverless/app features or an app lifecycle managed as code.
- OAuth project-based app when an integration must be installed across multiple customer accounts or distributed through the HubSpot Marketplace.
The migration task is therefore an architecture decision, not a token swap.
What exactly is HubSpot disabling?
HubSpot announced on 27 August 2026 that it is permanently removing the ability to create new legacy, non-Project-based private apps through the account UI.
The official HubSpot developer changelog gives two dates:
| HubSpot account | New legacy private app creation |
|---|---|
| Account created on or after 28 September 2026 | Disabled from 28 September 2026 |
| Account created before 28 September 2026 | Disabled from 26 October 2026 |
| Existing legacy private apps | Continue working for now |
This distinction matters. HubSpot is not saying every existing private-app access token stops working on 28 September. The immediate change is the removal of the legacy creation path.
Any runbook that says __INLINE_CODE_0__ now has an expiry date. New client integrations, data pipelines and internal CRM automation need a new default architecture.
Why is HubSpot replacing the old private-app flow?
Legacy private apps served several different jobs with one object. Teams used them for data warehouses, scheduled scripts, CRM syncs, webhooks, UI extensions, app pages and private backend integrations.
HubSpot's newer developer platform separates data credentials from applications more explicitly:
Need access to HubSpot data only?
→ Service Key
Need HubSpot app capabilities?
→ Project-based app
Need installation across multiple accounts?
→ OAuth project-based appThis prevents a full application object from being the default solution for every bearer-token use case.
What is a HubSpot Service Key?
A Service Key is an account-level API credential for system-to-system, data-oriented integrations.
HubSpot introduced Service Keys in public beta in February 2026 and described them as the replacement for legacy private apps where OAuth and webhooks are unnecessary. See the official Service Keys announcement and Service Key documentation.
Typical use cases include:
- data warehouse syncs
- BI/reporting tools
- scheduled scripts
- internal data automation
- nightly ETL jobs
- server-to-server CRM reads/writes
- one-account integrations that need REST API access but no app features
A request still uses a bearer credential:
Authorization: Bearer YOUR_SERVICE_KEYbut the key is managed as an account-level integration credential rather than a legacy private app.
What do Service Keys improve?
Scoped permissions
A Service Key receives only the scopes selected for it, and HubSpot says the creator cannot grant scopes beyond permissions they already hold. A reporting job that only reads contacts should not inherit unrelated write permissions.
Activity visibility
HubSpot provides activity and last-used information for Service Keys, making stale integration credentials easier to identify.
Rotation
Service Keys support rotation with a grace period. A practical sequence is:
Generate rotated key
→ update secret in integration
→ deploy/restart
→ verify successful API calls
→ retire previous keyThis is safer than changing a production credential and discovering later that a forgotten worker still uses the old value.
Account-level lifecycle
The credential is designed for the account's integration, rather than depending on one employee continuing to own the integration.
When is a Service Key the wrong choice?
A Service Key is intentionally narrower than a HubSpot app.
HubSpot says Service Keys cannot be used for:
- webhooks
- UI extensions
- app pages
- broader developer-platform functionality beyond REST API access
So this architecture does not fit a Service Key:
HubSpot deal changes
→ webhook to your backend
→ your system calculates result
→ result displayed in a HubSpot CRM cardThat needs a project-based app because the integration uses event subscriptions and HubSpot UI functionality.
Likewise, a Marketplace product installed by many customers should not use one account-level Service Key.
Service Key vs project-based private app
The most important decision is not old vs new. It is:
Is this a credential, or is this an application?
| Requirement | Service Key | Project-based private app |
|---|---|---|
| REST API reads/writes | Yes | Yes |
| One-account system-to-system access | Strong fit | Supported |
| Scheduled script / ETL | Strong fit | Often unnecessary |
| Webhooks | No | Yes |
| UI extensions / CRM cards | No | Yes |
| App pages/settings UI | No | Yes |
| Application configuration as code | No app lifecycle | Yes |
| Single-account app token | Not an app | Static auth supported |
| Multi-account installation | No | OAuth required |
| Marketplace distribution | No | OAuth + Marketplace distribution |
A Service Key is the lighter object when the only need is durable, scoped REST access. A project-based app is the better abstraction when the integration has behaviour, features and deployment lifecycle beyond REST calls.
What is a project-based app?
HubSpot's current developer platform manages apps as source-controlled projects created and deployed through the HubSpot CLI.
The official Create a new app guide shows a workflow beginning with:
hs project createThe app definition can describe distribution, authentication, scopes, redirect URLs, webhooks, UI components and other app features.
For serious integrations, managing configuration as code can improve reproducibility, code review, CI/CD, environment consistency and onboarding.
It also means a data analyst who only wants a token for a warehouse should not be forced into that workflow. That is where Service Keys fit.
Static token vs OAuth in a project-based app
Once an integration is genuinely an app, there is a second decision: static authentication or OAuth?
HubSpot's current app configuration documentation distinguishes them clearly.
Static authentication
A static-auth project-based app is appropriate when the app is privately distributed and restricted to a single HubSpot account at a time.
Your private app/backend
↓
Static app token
↓
One HubSpot accountThis can fit an integration that needs webhooks or UI extensions but does not need multi-customer installation.
OAuth
OAuth is required when an app needs installation across multiple HubSpot accounts or Marketplace distribution.
Customer A ─┐
Customer B ─┼─ OAuth authorization → Your app
Customer C ─┘HubSpot's OAuth documentation states that apps designed for installation by multiple HubSpot accounts or Marketplace distribution must use OAuth.
The product/distribution model should determine the authentication model.
A practical decision tree
Use this before creating anything new:
Only REST API access to one HubSpot account?
↓ yes
Need webhooks, UI extensions or app pages?
↓ no
Use Service KeyIf app capabilities are required:
Need webhooks/UI/app features?
↓ yes
Project-based app
↓
Installed in one account?
├─ yes → private + static auth may fit
└─ no → OAuthIf the app is installed by multiple customers or listed publicly:
Project-based app
+ OAuth
+ appropriate distribution configurationThis avoids rebuilding a simple data sync as an unnecessarily complex app, or trying to use a Service Key for a webhook-driven product.
What should you do with existing legacy private apps?
Inventory them before migrating them.
HubSpot says existing legacy private apps continue to function for now, so migration can be deliberate.
For each app, record:
| Question | Why it matters |
|---|---|
| Which systems use its token? | Prevent accidental outages |
| Which scopes are actually used? | Reduce privilege during migration |
| Does it subscribe to webhooks? | Service Key may not fit |
| Does it provide UI/app features? | Requires project-based architecture |
| Is it used by one account? | Static/private model may fit |
| Is it distributed across accounts? | OAuth needed |
| Who owns the integration? | Operational accountability |
| When was the token last used? | Identify stale apps |
| Where is the secret stored? | Rotation/security planning |
Do not begin by deleting or rotating the legacy app. First establish the dependency graph.
Old tokens are often hidden in cron jobs, server environment variables, ETL platforms, BI tools, serverless functions, staging environments or automation platforms.
Migration path 1: legacy private app to Service Key
This is the cleanest path for data-only integrations.
- Inventory current scopes. Compare the legacy app's scopes with actual API usage rather than copying everything.
- Create a least-privilege Service Key. Grant only the reads/writes the integration needs.
- Store the key in secret management. Use deployment secrets or a managed secret store, not source code.
- Cut over one controlled consumer first. Verify authentication, endpoints, scopes and write behaviour.
- Monitor activity. Confirm production calls are using the new key.
- Decommission the legacy credential only after every consumer has moved.
A migration is also an opportunity to split one overpowered credential into several purpose-specific keys.
Migration path 2: legacy private app to project-based app
Use this path when the integration is genuinely an application.
Typical triggers include:
- webhooks
- CRM cards
- UI extensions
- app settings/pages
- serverless/app functionality
- structured deployment requirements
HubSpot provides migration guidance, but the path depends on the app's current type and features. Review the current migration overview before treating migration as one CLI command.
A safe sequence is:
Inventory features
→ map each feature to new platform capability
→ create/migrate project source
→ reproduce scopes/auth configuration
→ deploy to test account
→ verify webhooks + UI + backend
→ cut over
→ monitorDo not make “the token works” the acceptance test when the old app also had event subscriptions and UI behaviour.
What about an existing legacy private app that still works?
You do not need to break it merely to satisfy the September cutoff. HubSpot's August 27 announcement says existing legacy private apps are not affected at this time.
Three sensible categories are:
Keep temporarily
A stable, complex legacy app can remain in place while its migration is planned and future HubSpot announcements are monitored.
Migrate now
A data-only app is a strong Service Key candidate because the migration can simplify credential management.
Rebuild deliberately
A webhook/UI-heavy private app should move only after its functionality is mapped to a project-based design and tested.
The worst option is a rushed credential change that silently drops event subscriptions or permissions.
Should you create spare legacy private apps before the cutoff?
Usually, no.
Creating dormant apps “just in case” produces unowned credentials and cleanup work. Preserve known production dependencies when necessary, but do not stockpile unused credentials to avoid adopting the current architecture.
Security improvements to make during migration
Reduce scopes
Rebuild permissions from actual API requirements instead of copying years of accumulated access.
Separate integrations
Avoid one credential shared by a warehouse, reporting job, CRM write sync and internal admin tool. A compromised reporting pipeline should not inherit unrelated write permissions.
Rotate safely
Deploy the replacement secret and verify it before retiring the old credential.
Centralise ownership
Every production HubSpot credential should have:
- owner
- purpose
- environment
- scopes
- secret location
- last use
- rotation date
- dependent system
That inventory is more important than whether the credential is named “private app” or “Service Key”.
What about API limits?
A new credential does not remove HubSpot API limits.
HubSpot's current API usage guidance documents limits for privately distributed apps and other integration types.
Preserve or improve:
- __INLINE_CODE_0__ handling
- retry/backoff
- pagination
- batching where supported
- concurrency control
Authentication architecture and API-consumption architecture are related, but separate.
A Node.js migration pattern
Keep authentication behind one integration client rather than spreading the credential through business code:
const HUBSPOT_BASE_URL = 'https://api.hubapi.com'
export async function hubspotRequest(path, options = {}) {
const response = await fetch(`${HUBSPOT_BASE_URL}${path}`, {
...options,
headers: {
...options.headers,
Authorization: `Bearer ${process.env.HUBSPOT_SERVICE_KEY}`,
'Content-Type': 'application/json',
},
})
if (response.status === 429) {
throw new Error('HubSpot rate limit reached')
}
if (!response.ok) {
throw new Error(`HubSpot API request failed: ${response.status}`)
}
return response.json()
}The valuable abstraction is that business code depends on a __INLINE_CODE_0__, not a __INLINE_CODE_1__. Future authentication changes are then cheaper.
For OAuth apps, the client layer should obtain and refresh the account-specific OAuth token instead.
Migration test matrix
| Test | Service Key data sync | Project-based app |
|---|---|---|
| Read required objects | Yes | Yes |
| Create/update required records | If scoped | If scoped |
| Pagination | Test | Test |
| Rate-limit retry | Test | Test |
| Secret rotation | Test | Test |
| Webhook delivery | N/A | Required if used |
| UI extension renders | N/A | Required if used |
| App settings/pages | N/A | Required if used |
| Multi-account install | N/A | OAuth test |
| Revocation behaviour | Test | Test |
A migration is complete when the business workflow works, not when one contacts API call returns __INLINE_CODE_0__.
What should integration runbooks change?
Old pattern:
Create HubSpot private app
→ copy token
→ build integrationNew pattern:
Classify integration
↓
Data-only, one account?
→ Service Key
App features, one account?
→ Project-based private app / static auth
Multiple customer accounts?
→ Project-based OAuth app
↓
Define scopes
→ build secret lifecycle
→ implement
→ test business workflowChoose the credential/app model before writing integration code.
September 2026 readiness checklist
Before the first cutoff on 28 September:
- □Inventory existing legacy private apps.
- □Search source code, secret stores and automation tools for their tokens.
- □Record owner, purpose, scopes and last use.
- □Classify new integrations as data-only or app-capability.
- □Use Service Keys for suitable system-to-system REST integrations.
- □Use project-based apps where webhooks or UI/app features are required.
- □Use OAuth for integrations installed in multiple independent accounts.
- □Remove unnecessary scopes during migration.
- □Store credentials in managed secrets.
- □Test rate-limit and retry behaviour.
- □Test webhook/UI behaviour for project migrations.
- □Keep the old credential until cutover is verified.
- □Decommission stale credentials after migration.
- □Update documentation so nobody follows the old creation flow after the cutoff.
FAQs
When is HubSpot disabling new legacy private app creation?
For accounts created on or after 28 September 2026, new legacy private app creation is disabled on 28 September. Accounts created before that date retain the creation option until 26 October 2026.
Will existing HubSpot legacy private apps stop working on September 28?
No. HubSpot's August 27 announcement says existing legacy private apps continue working for now. The immediate change removes the ability to create new ones through the legacy UI flow.
Should I replace a legacy private app with a Service Key?
Use a Service Key when the integration is account-level, system-to-system REST API access and does not need webhooks, UI extensions or other app features.
Can HubSpot Service Keys receive webhooks?
No. HubSpot says Service Keys do not support webhooks. Use a project-based app when real-time webhook subscriptions are required.
When do I need OAuth?
Use OAuth when the app is designed for installation in multiple HubSpot accounts or distribution through the HubSpot Marketplace.
Do I need to migrate every existing private app immediately?
No. Existing legacy private apps are currently still supported. Inventory each app and migrate according to its actual capabilities and risk rather than forcing every integration through the same path.
Conclusion
HubSpot's September and October 2026 cutoff is not a mass shutdown of existing integrations. It is a change in the default architecture for new integrations.
Data-only system-to-system integration
→ Service Key
Private app functionality such as webhooks/UI
→ Project-based private app
Multi-account or Marketplace integration
→ Project-based app + OAuthExisting legacy private apps can continue for now, which gives teams time to migrate safely.
Use that time to do more than replace tokens. Inventory consumers, remove unnecessary scopes, separate unrelated integrations, improve rotation, move secrets into proper storage, and verify the entire business workflow before decommissioning anything.
That turns a platform sunset into a cleaner integration architecture rather than another emergency credential swap.
If your business relies on HubSpot integrations that connect CRM data with internal portals, sales systems, reporting or automation, Softotic's custom software development service can help design the integration layer, while web application development can support customer-facing and internal CRM-connected applications.
Sources and references
- HubSpot Developer Changelog: Legacy Private App Creation Being Disabled
- HubSpot Developer Changelog: Service Keys enter public beta for system-to-system integrations
- HubSpot Developers: Make API requests using a Service Key
- HubSpot Developers: Create a new app using the CLI
- HubSpot Developers: App configuration and authentication
- HubSpot Developers: Working with OAuth