> ## Documentation Index
> Fetch the complete documentation index at: https://docs.introw.io/llms.txt
> Use this file to discover all available pages before exploring further.

# HubSpot permissions and scopes

> Exactly what Introw asks for in HubSpot: every required, conditional and optional OAuth scope, how HubSpot's permission model differs from Salesforce, and what happens when a scope is missing.

> For the HubSpot admin or security reviewer being asked to approve the connection.

"Accept all requested permissions" is a reasonable thing to hesitate over, and the hesitation is usually where a CRM connection stalls.
This page is the honest answer: every scope Introw asks for, what each group of them is actually for, how HubSpot's permission model works (it is genuinely different from Salesforce), and what happens when something is not granted.

## What you'll achieve

Enough detail to approve or refuse the connection on the facts: the full scope list, the model that governs it, and a clear statement of where the boundary of Introw's access sits.

## How HubSpot's permission model works

This is the part worth understanding before reading the list, because it is not the same as Salesforce.

**Scopes are granted portal-wide, to the app.** They are not the connecting user's permissions. HubSpot has no per-user field-level security an app is subject to, and no record-level sharing that applies to an app. So connecting as a restricted HubSpot user does not restrict Introw, and there is no HubSpot equivalent of the dedicated integration user we recommend for Salesforce.

**The consequence, stated plainly:** within the scopes you grant, Introw's record visibility is complete. A property that is read-only in HubSpot is read-only for everyone, including Introw, but there is no way to hide a subset of companies or deals from the app while granting the scope. If you need that boundary, it has to be a scope you do not grant rather than a permission you narrow.

**What limits Introw instead:**

* **The scopes themselves.** An object with no granted scope is invisible: Introw does not offer it, cannot read it and cannot write it.
* **Your own configuration.** Which companies become partners is a filter you set, which objects link to a partner is a mapping you set, and which fields a partner can see or edit in the portal is a per-field choice. That configuration, not the scope list, is what decides what leaves HubSpot for a partner.
* **Write protection.** Introw defaults to never overwriting a value your team already set, and only fields you have marked editable can be written from the partner side.

<Note>
  Your HubSpot tokens are not stored in Introw's own application. They are held in a separate, dedicated credential vault, and every request is signed and scoped to your organisation alone. See [How the sync stays accurate and secure](../technical#how-the-sync-stays-accurate-and-secure).
</Note>

## The scopes Introw requests

HubSpot splits an app's scopes into three kinds, and the split matters: only the first group is non-negotiable.

### Required

Declining any of these ends the connection, because the core of the product cannot run without them. HubSpot returns you to Introw with a message that all permissions are required.

| Scope                                                                                 | Why Introw needs it                                                                                                                                                  |
| ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `crm.objects.companies.read` / `.write`                                               | Companies are the default partner object: read to detect partners and keep them current, write to push a partner's tier, manager and team roles back onto the record |
| `crm.schemas.companies.read` / `.write`                                               | Read the company property list to map fields; write is what lets Introw create the attribution property for you instead of asking RevOps for one                     |
| `crm.objects.deals.read` / `.write`                                                   | Deals are what a partner program is measured on: read for partner pipeline, attribution and commissions, write for deal registration and partner-side updates        |
| `crm.schemas.deals.read` / `.write`                                                   | The same property mapping and one-click attribution property, for deals                                                                                              |
| `crm.objects.owners.read`                                                             | Resolve deal and company owners, so a registration can be assigned to the right rep                                                                                  |
| `crm.objects.line_items.read` / `.write`, `crm.schemas.line_items.read`, `e-commerce` | Line items on a deal, which is what a reseller quoting on their own deal writes                                                                                      |
| `crm.objects.quotes.read`, `crm.schemas.quotes.read`                                  | Read quotes attached to a deal                                                                                                                                       |
| `tickets`                                                                             | Tickets, so a partner can collaborate on a support case as well as a deal                                                                                            |
| `settings.currencies.read`                                                            | Your portal's currencies and exchange rates, so commission amounts are correct rather than converted by us                                                           |

### Conditionally required

Requested only for the capabilities that need them. If your program does not use the feature, the scope does no work.

| What you turn on                                                                                           | Scopes it needs                                                                                                    |
| ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| Partner contacts, portal access from a CRM field, contact-level sync                                       | `crm.objects.contacts.read` / `.write`, `crm.schemas.contacts.read` / `.write`                                     |
| A custom object as your partner object, or a custom object shared with partners                            | `crm.objects.custom.read` / `.write`, `crm.schemas.custom.read`                                                    |
| Partner file uploads landing on the HubSpot record                                                         | `files`                                                                                                            |
| Partners building or sending quotes                                                                        | `crm.objects.quotes.write`                                                                                         |
| Commerce objects in a reseller or distributor program: orders, invoices, subscriptions, listings, services | The matching `crm.objects.*` and `crm.schemas.*` pairs, plus `crm.pipelines.orders.read`                           |
| Course enrollments and certificates as real HubSpot records                                                | The `crm.app.objects.*` and `crm.app.schemas.*` scopes for **Introw Course Enrollment** and **Introw Certificate** |
| Reading email engagement on a shared record                                                                | `sales-email-read`                                                                                                 |

### Optional

| Scope                               | What it unlocks                                                                              |
| ----------------------------------- | -------------------------------------------------------------------------------------------- |
| `crm.objects.leads.read` / `.write` | HubSpot leads: a lead list in the portal, and referrals that land as leads rather than deals |

Leads are genuinely optional. Decline them and everything else works; you simply cannot use HubSpot leads as a referral target or show a lead list to partners.

## What happens when a scope is missing

Nothing fails silently, which is the behaviour to check for in a review.

<Steps>
  <Step title="Objects you cannot read are not offered">
    Introw only lists objects whose read scope is granted, so the setup wizard and the section picker show what is genuinely reachable in your portal rather than everything HubSpot defines.
  </Step>

  <Step title="Missing write access is reported where it matters">
    Where a scope blocks a write, Introw shows a **Permission limitations** notice on the screen that depends on it: the **Object linking** step on the integration, and a form's **Automation** tab. Each affected object carries a verdict pill with the reasoning on hover, reading **No access**, **No read access**, **Read-only**, **Cannot create**, or **Cannot update** depending on which half of the scope pair is missing.
  </Step>

  <Step title="Read-only properties are named too">
    In a form's property picker, every property HubSpot will not accept a value for is struck through with the reason beside it: **Calculated in your CRM** for a calculation property, **Managed by your CRM** for a property HubSpot owns. Unlike Salesforce, these are never a permission you can grant: a read-only HubSpot property is read-only for your own team as well.
  </Step>

  <Step title="Fix it and re-check without reconnecting">
    After changing permissions in HubSpot, use **Re-check after changing permissions** on that notice. Introw re-probes rather than making you tear down the connection.
  </Step>
</Steps>

[Every CRM error Introw logs](./every-crm-error-introw-logs) maps these notices against the other three places a CRM failure is reported, including a record HubSpot refused and what the Introw card says on a HubSpot record when the connection breaks.

## Scope updates over time

Introw ships support for new HubSpot objects, and new objects need new scopes. When that happens the HubSpot tile in Introw shows **Update available** and the integration header shows **Install update**.

Re-authorizing is a HubSpot admin action, and until it is done the affected data stops syncing while everything else continues.
Treat the update prompt as maintenance rather than an error: it is the mechanism by which a connection you approved once stays limited to what you approved, instead of an app quietly widening its own access.

## Verify it worked

Open the HubSpot integration in Introw and confirm the objects you expect are listed and carry no **Permission limitations** notice.
Then check it from the HubSpot side: the connected app lists the scopes actually granted, which is the record to attach to a security review rather than this page.

## Related

<CardGroup cols={2}>
  <Card title="Connect HubSpot" icon="plug" href="./connect-hubspot">
    The connection itself, end to end.
  </Card>

  <Card title="Salesforce permissions and scopes" icon="shield-halved" href="./salesforce-permissions-and-scopes">
    The equivalent, and a genuinely different model.
  </Card>

  <Card title="Troubleshoot a CRM connection" icon="wrench" href="./troubleshoot-a-crm-connection">
    When sync shows needs attention.
  </Card>

  <Card title="Every CRM error Introw logs" icon="triangle-exclamation" href="./every-crm-error-introw-logs">
    Where a scope gap or a refused write is reported.
  </Card>

  <Card title="Implementation reference" icon="screwdriver-wrench" href="../technical">
    Full configuration options.
  </Card>
</CardGroup>
