Skip to content
Back to Blog
Integration

HubSpot OAuth Scopes, a Reference for SaaS App Builders

Jun 18, 2026
SCSunny Chauhan
HubSpot OAuth Scopes, a Reference for SaaS App Builders

To read contacts and deals through HubSpot's CRM API, an app requests crm.objects.contacts.read and crm.objects.deals.read, and adds the matching .write scope only if it creates or updates those records. The harder decision is which list each scope goes in. HubSpot lets an OAuth app mark scopes as required, conditionally required or optional, and its certification rules say an app must "Use all scopes it requests for installation." A scope that only some customers need belongs in the optional list, or it will block installs and get flagged in review.

For a SaaS company, the scope list is part of the product. Every customer installs your app in their own HubSpot account, their admin reads the consent screen before clicking connect, and a scope tied to a paid HubSpot tier can stop a whole segment of customers from installing. Appnigma's marketplace apps service is built for that case. It delivers "a native app, marketplace listing preparation, and review support." For HubSpot that includes "HubSpot listing review and certification support where eligible." If you only need to connect one HubSpot account for internal use, HubSpot's static auth option is simpler and can only define required scopes.

Updated October 2026. Checked against HubSpot's scopes reference, OAuth guides, the 2026-09 token reference and the certification requirements. This update corrects the token endpoint, the claim that HubSpot has no optional scopes, the legacy status of tickets and timeline, and the source of the 30-day usage check. It adds the three scope types, tier-gated scopes and what an access token can see.

Which scopes contacts, deals and companies need

HubSpot's scopes reference lists every scope with the accounts it works in. The CRM object scopes below are "Available to all accounts" unless the table says otherwise, which matters more than the names once customers on different HubSpot tiers start installing.

What the app doesScopeAccount availability
Read contactscrm.objects.contacts.readAll accounts
Create or update contactscrm.objects.contacts.writeAll accounts
Read or write dealscrm.objects.deals.read, crm.objects.deals.writeAll accounts
Read or write companiescrm.objects.companies.read, crm.objects.companies.writeAll accounts
Read deal or contact property settingscrm.schemas.deals.read, crm.schemas.contacts.readAll accounts
See who owns a recordcrm.objects.owners.readAll accounts
Read or write ticketscrm.objects.tickets.read, crm.objects.tickets.writeAll accounts
Read contact listscrm.lists.readAll accounts
Custom objectscrm.objects.custom.read, crm.schemas.custom.readEnterprise only
Custom workflow actionsautomationProfessional or Enterprise only
Sensitive Data propertiescrm.objects.contacts.sensitive.read and similarEnterprise only for contacts, companies, deals and custom objects

The object scope and the schema scope do different jobs. crm.objects.deals.read returns deal records and their property values, while crm.schemas.deals.read covers "property settings for deals," which a field-mapping screen needs to list a customer's custom deal properties. A sync that maps fixed fields can skip the schema scope.

You don't add oauth yourself. The reference calls it the "Basic scope required for OAuth" and says it "is added by default to all apps." Several older scopes still appear in guides but are now marked Legacy, including tickets, timeline, files and hubdb. HubSpot recommends that apps using them "migrate to use the corresponding new granular scopes," so tickets becomes crm.objects.tickets.read and crm.objects.tickets.write. Its granular scopes migration guide dates the replacements to September 8, 2026. It also says "Existing installs of your app keep working with their current access while a migration is available." The scopes page lists accounting, actions, e-commerce, integration-sync and social as deprecated scopes that "should not be used for new app development."

Required, conditionally required and optional scopes

An app on HubSpot's developer platform declares scopes in the auth block of its app-hsmeta.json file, and the app configuration reference gives three arrays. Required scopes "must grant these scopes to successfully install the app." Optional scopes "can be excluded from the authorization during installation if the account or user installing the app doesn't have the proper permissions." Conditionally required scopes are "required only when included in the scope query parameter of the install URL."

"auth": {
  "type": "oauth",
  "redirectUrls": ["https://app.example.com/hubspot/callback"],
  "requiredScopes": [
    "crm.objects.contacts.read",
    "crm.objects.deals.read",
    "crm.objects.deals.write"
  ],
  "optionalScopes": ["crm.objects.custom.read", "crm.schemas.custom.read"],
  "conditionallyRequiredScopes": ["automation"]
}

The tier column in the table is why these lists exist. The working with OAuth guide says "users will get an error if they try to install your app in an account that doesn't have access to an included scope." Put automation in the required list and every customer on a HubSpot Starter or free account fails to install, even if your workflow action is a minor feature. As an optional scope it is "automatically dropped from the authorization request" for those accounts, and the install goes through. The installing admin can also turn optional permissions off, since the scopes reference says users "can customize and confirm each optional permission they grant to your app."

Conditionally required scopes suit a feature you sell on one of your own plans. The scopes reference describes offering two install URLs, one that includes the scope "for users with access to a feature" and one that omits it. Your product can show the first link to customers on the plan that includes the HubSpot workflow action and the second to everyone else.

How the install URL and token exchange carry scopes

The scope lists in your config only take effect through the install URL. The OAuth quickstart passes required scopes in scope and optional ones in optional_scope, each "separated by URL-encoded spaces." Any scope checked as required in the app's settings has to be in scope, "or the authorization page will display an error."

https://app.hubspot.com/oauth/authorize
  ?client_id=YOUR_CLIENT_ID
  &scope=crm.objects.contacts.read%20crm.objects.deals.read%20crm.objects.deals.write
  &optional_scope=crm.objects.custom.read%20crm.schemas.custom.read
  &redirect_uri=https://app.example.com/hubspot/callback
  &state=RANDOM_VALUE_TIED_TO_THE_SESSION

After the customer approves, HubSpot redirects with a code, and your server exchanges it at the token endpoint. HubSpot's token reference for the 2026-09 API uses /oauth/2026-09/token and says these endpoints require "all parameters to be in the request body rather than as query parameters." Older guides that call /oauth/v1/token and read a portal_id field describe the legacy version, and the v1 token guide says "On February 16, 2027, HubSpot will deprecate v1 of the OAuth API." For a Marketplace app the change is already a review item. HubSpot's May 2026 changelog says new listings, certification submissions and recertifications "must use the new OAuth v3 endpoints," and lists them under the date-based /oauth/2026-03/token path. The response names the account as hub_id and lists the granted scopes.

const res = await fetch('https://api.hubspot.com/oauth/2026-09/token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  body: new URLSearchParams({
    grant_type: 'authorization_code',
    client_id: process.env.HUBSPOT_CLIENT_ID,
    client_secret: process.env.HUBSPOT_CLIENT_SECRET,
    redirect_uri: 'https://app.example.com/hubspot/callback',
    code: req.query.code
  })
});
const {
  access_token, refresh_token, expires_in, hub_id, scopes
}
= await res.json();
// Store tokens per hub_id. Turn on features only for the scopes actually granted.

The scopes array is the part most implementations ignore. With optional scopes, HubSpot says "you will need to check the access token or refresh token to see which ones were granted." Save that array with the account and gate features on it, so a customer whose account dropped crm.objects.custom.read never sees a custom object option that would return a 403. The access token lasts 30 minutes, and the /oauth/2026-09/token/introspect endpoint returns the same scopes list for an existing token if you need to check later.

An access token can see more than the user who installed it

HubSpot's OAuth quickstart states this plainly. "Access tokens reflect the scopes requested from the app and do not reflect the permissions or limitations of what a user can do in their HubSpot account." Its example is a user allowed to view only their own contacts, whose install still produces a token that "can view all contacts in the account."

For a SaaS product that shows HubSpot data inside its own interface, that moves record visibility into your code. If a sales rep in your app should only see the deals they own in HubSpot, your app has to filter by owner, using crm.objects.owners.read, because the token won't do it. It also explains who can install. The app management guide allows Super Admins, or users with the HubSpot Marketplace access permission "along with any scope groups requested by the app," so a request for crm.import means the installer needs the Import permission too.

Can a HubSpot app ask for more scopes after it is installed?

Yes. A HubSpot app can add scopes after install by sending the customer through an install URL that includes the new scopes, and the customer approves the updated consent screen. Scopes are only granted through that authorization step, so there is no separate prompt your app can trigger inside a session. Most teams need it less than they expect, because the optional and conditionally required lists already let one app serve customers with different HubSpot tiers and different plans of your product.

When you do add a scope, the customer authorizes again. HubSpot's Sensitive Data guide spells out the pattern for its own scopes. Existing users "need to reauthorize with the updated scopes," and the developer has to "notify app users of the change and request re-authorization of your app" by sending them an authorization URL. HubSpot doesn't push that prompt to customers for you. Plan it as a release task. Ship the feature behind a check on the stored scopes array, ask admins inside your product to reconnect, and keep the old behavior working for accounts that haven't.

Removing a scope has its own catch. The webhooks guide says "you won't be able to remove any scopes required by active webhook subscriptions without first pausing and removing the subscriptions." Webhooks also decide which list a scope can live in, because subscriptions need the matching scope configured as required. An app that listens for contact events can't make crm.objects.contacts.read optional.

What HubSpot certification checks about scopes

Listing and certification are separate reviews, and scopes come up in both. The certification requirements say an app must "Use all scopes it requests for installation (i.e. both in the required scope parameter and the optional_scope parameter)," that "Extraneous scopes must be removed," and that scopes for "a subset of your app's user base" should be conditionally required or optional.

HubSpot checks this against its own request logs. Its example rejection reads "it only made requests to the CRM Contacts and Timeline Events APIs in the last 30 days," and asks the developer to remove two scopes. That is where the 30-day window comes from. The security questionnaire HubSpot added in May 2026 asks about "OAuth token access and storage," not unused scopes. The 30-day figure is an example of how reviewers read your logs, so the safe reading is that any scope with no matching API traffic in recent weeks will be questioned. Optional scopes count too, which surprises teams that moved a scope to optional to avoid the check.

Two more scope rules sit outside the API calls. The setup guide must show "the scope approval screen," and HubSpot's example feedback flags a screenshot that "does not show the business-intelligence scope." HubSpot also expects an app that keeps getting 403 errors "for missing the proper scopes" to stop making those calls for that account.

Sensitive Data scopes go through a separate gate. For Marketplace apps, the Sensitive Data guide says "you'll need to request access to specific sensitive scopes from HubSpot's Ecosystem Quality team," which allowlists them after testing and compliance checks. The listing requirements add that an app with app cards "must not access, request, or use sensitive data scopes." Certification only opens once an app has been listed for six months with 60 active installs, so the scope list you submit for listing is the one you will be living with by then.

Scope mistakes that block installs or fail review

  • Putting an Enterprise or Professional scope in the required list. Every lower-tier customer's install fails at the consent screen.
  • Requesting write scopes for a sync that only reads. Reviewers see no write calls and ask you to remove them.
  • Keeping tickets or timeline from an older build when the granular scopes exist.
  • Marking a scope optional when a webhook subscription depends on it. Subscriptions need it as a required scope.
  • Reading custom properties without crm.schemas.*.read, then getting 403s on the mapping screen.
  • Ignoring the scopes array in the token response, so the app calls APIs for optional scopes the account never granted.
  • Leaving a scope behind after removing the feature that used it. Audit the list whenever a feature ships or goes.

For how these permissions behave once the app makes calls at volume, see our HubSpot API rate limits guide, and for the full listing process, the HubSpot Marketplace listing guide.

Frequently Asked Questions

What scopes does a HubSpot app need to read contacts and deals?

crm.objects.contacts.read and crm.objects.deals.read, both available in every HubSpot account. Add crm.schemas.deals.read only if the app lists the customer's deal properties.

What is the difference between scope and optional_scope in HubSpot OAuth?

Scopes in scope must be granted or the install fails. Scopes in optional_scope are dropped when the account lacks access or the admin declines them, so check the granted scopes in the token response.

Can a HubSpot app request more scopes after install?

Yes. Send the customer through an install URL that includes the added scopes and they approve the new consent screen. Existing tokens keep the old scopes until they do.

Does HubSpot certification check unused scopes?

Yes. The app must use every scope it requests, required and optional, and HubSpot's example rejection is based on 30 days of the app's API logs.

Is the HubSpot oauth scope still required?

You don't need to add it. HubSpot's scopes reference says oauth is added by default to all apps.

Can Appnigma build our HubSpot app and scope list?

Yes. Appnigma's marketplace apps service delivers a native HubSpot app with listing preparation and review support, including certification support where eligible. HubSpot decides approval, and ongoing maintenance can run through done-for-you delivery.

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. Scopes, HubSpot Developers
  2. App configuration and Authentication overview, HubSpot Developers
  3. OAuth quickstart guide and Working with OAuth, HubSpot Developers
  4. Manage OAuth access tokens with the 2026-09 API, HubSpot Developers
  5. Manage apps in HubSpot, HubSpot Developers
  6. Certification requirements, Applying for app certification and App Marketplace listing requirements, HubSpot Developers
  7. Sensitive Data and Webhooks guide, HubSpot Developers
  8. Update your app to use granular scopes and v1 OAuth tokens guide, HubSpot Developers
  9. App listing and app certification requirement updates for May 2026, HubSpot Developer Changelog

All Blogs

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