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

# HubSpot setup

ConfigView reads your HubSpot account through HubSpot's API, using the access token of a **private app** that a super admin creates in HubSpot.

You will end up with **1 secret** in ConfigView (`HUBSPOT_PRIVATE_APP_TOKEN`) when setup is complete.

> **Scope of this integration today.** ConfigView reads who has HubSpot, their permission set, teams and paid seats, who is a super admin, every sign-in attempt, and HubSpot's security log: integrations installed, data exports, users added, removed or deactivated, admin rights granted, two-factor and single sign-on changes, and private app tokens viewed. On Enterprise it also reads the audit log. ConfigView only reads. It never reads contacts, companies, deals, tickets or any other CRM record, and never changes anything.

***

## Step 1: Open the HubSpot page in ConfigView

Open ConfigView in a second browser tab and leave it open:

`https://{companyname}.configview.com/admin/integrations/hubspot`

***

## Step 2: Create a private app in HubSpot

You need to be a HubSpot **super admin** to create a private app.

1. Sign in to [HubSpot](https://app.hubspot.com/) as a super admin
2. In the main navigation, open **Development**, then **Legacy apps** in the left sidebar. (Older portals: **Settings → Integrations → Private apps**.) HubSpot now calls private apps "legacy apps", but they are fully supported and are the right choice for a read-only connection to your own portal
3. Click **Create legacy app**, then choose **Private**
4. On the **Basic Info** tab, name it `ConfigView` and add a short description, for example *Read-only access review*
5. Open the **Scopes** tab, click **Add new scope**, and tick **only** these three read scopes:

| Scope | What it lets ConfigView read |
| - | - |
| `settings.users.read` | Users, their permission sets, seats and super admin flag |
| `settings.users.teams.read` | Teams and who belongs to them |
| `account-info.security.read` | Login history, security activity and (Enterprise) the audit log |

Do not add any `crm.*` scope. ConfigView never reads CRM records
6\. Leave the **Webhooks** tab empty
7\. Click **Create app**, then **Continue creating**
8\. On the app's page, open the **Auth** tab, click **Show token**, then **Copy**. The token starts with `pat-`
9\. Switch to the ConfigView tab, paste it into `HUBSPOT_PRIVATE_APP_TOKEN` under **Credentials**, and click the save icon

### Keep the token working

* **Who creates the app matters.** If the super admin who created the private app is later removed from HubSpot, the token starts failing. Create it from an admin who is staying, or a shared admin account.
* **Rotating the token.** HubSpot recommends rotating private app tokens every six months (**Auth** tab → **Rotate**). "Rotate and expire later" keeps the old token working for 7 days. Paste the new token into ConfigView before it expires.
* **Viewing the token is logged.** Every time someone clicks **Show token**, HubSpot records it in the security log, and ConfigView reports it (see *Private app tokens and keys viewed or changed*).

***

## Step 3: Connect and verify

1. Back on `https://{companyname}.configview.com/admin/integrations/hubspot`, confirm the credential shows as saved
2. Click **Connect**. ConfigView creates its tables and schedules every collector at your default run time. Stop any you don't want under **Collectors**:

| Script | Notes |
| - | - |
| **Users** | Every HubSpot user: name, email, permission set, primary and secondary teams, paid seats held, and whether they are a super admin. |
| **Permission Sets** | Permission sets (roles) defined in the account, and whether each one can change billing. |
| **Teams** | Teams and the users who belong to each, as primary or secondary members. |
| **Login History** | Every sign-in attempt, web and mobile, successful or failed: who, when, IP address, country and region, and browser. |
| **Security Activity** | Security events: integrations installed or removed, contact and user exports, users added, removed, deactivated or impersonated, admin rights granted, two-factor and single sign-on changes, private app tokens viewed or rotated, permanent deletions. |
| **Audit Log** | Enterprise only. Who did what and when across HubSpot: record and property changes, workflow and content edits, approvals and critical actions. Records the category, action and the id of what was touched, never the record's contents. |

3. Click **Verify now**. The health check confirms the token, reads the portal id and the token's scopes, and makes one small read from each endpoint.

If a check fails:

* **"Token scopes" fails naming a scope.** Open the private app's **Scopes** tab, add the scope it names, and save. The same token picks up the new scope; you don't need to paste it again.
* **401, or "the token is wrong, rotated or expired".** The token was rotated or mistyped. Copy it again from the **Auth** tab.
* **"Audit log (Enterprise)" is skipped.** Expected on Starter and Professional: HubSpot only offers the audit log API on Enterprise.

***

## Plan requirements

| Data | Free | Starter | Professional | Enterprise |
| - | - | - | - | - |
| Users, permission sets, teams | ✓ | ✓ | ✓ | ✓ |
| Login history, security activity | see note | ✓ | ✓ | ✓ |
| Audit log | | | | ✓ |

HubSpot's API reference lists login history and security activity on every tier, while its Knowledge Base lists the activity history from Starter up. On a Free portal the health check will tell you which one applies.

***

## API usage

HubSpot gives each portal a **daily API limit** (250,000 calls on Free and Starter, 625,000 on Professional, 1,000,000 on Enterprise) that is **shared by every private app in the portal**, including your other integrations. ConfigView keeps its share small:

* A normal day costs a few dozen calls. The user, team and permission set lists are one to a few calls each, and the activity logs only read what is new since the last run.
* The first run reads HubSpot's whole retained history (90 days of sign-ins and security activity, and 90 days of audit log on Enterprise), which can take a few hundred to a few thousand calls on a large, busy portal.
* Every collector stops early if less than 10% of the day's limit is left, and caps the calls it makes in one run.
* ConfigView paces itself at about 2 calls a second, well under HubSpot's per-app burst limit.

You can see ConfigView's calls on the private app's **Logs** tab in HubSpot.

***

## Data Tables

Once the scripts run, these tables are created in your database. Each has a `run_at` column and a `raw_json` column holding the record as HubSpot returned it.

The user, permission set and team tables are **snapshots**: each run replaces the previous one. The login, security and audit tables are **histories**: each event is stored once and kept, so they grow past HubSpot's own 90-day window.

| Table | Source | Key Columns |
| - | - | - |
| `hubspot_users` | `GET /settings/users/2026-09` | user\_id, email, first\_name, last\_name, role\_id, role\_ids, primary\_team\_id, secondary\_team\_ids, seat\_names, super\_admin |
| `hubspot_roles` | `GET /settings/users/2026-09/roles` | role\_id, name, requires\_billing\_write |
| `hubspot_teams` | `GET /settings/users/2026-09/teams` | team\_id, name, user\_ids, secondary\_user\_ids, member\_count |
| `hubspot_login_history` | `GET /account-info/2026-09/activity/login` | login\_id, login\_at, user\_id, email, login\_succeeded, ip\_address, location, country\_code, region\_code, user\_agent |
| `hubspot_security_activity` | `GET /account-info/2026-09/activity/security` | event\_id, created\_at, user\_id, activity\_type, acting\_user\_email, object\_id, info\_url, ip\_address, location, country\_code, region\_code |
| `hubspot_audit_logs` | `GET /account-info/2026-09/activity/audit-logs` | event\_id, occurred\_at, category, sub\_category, action, target\_object\_id, acting\_user\_id, acting\_user\_email |

***

## Things worth knowing

**Installed apps are named by id only.** HubSpot's security log records an integration install as `INSTALL_INTEGRATION` with the app's id in `object_id`, not its name. Match the id against **Settings → Integrations → Connected apps** in HubSpot. Removals are recorded as `UNINSTALL_INTEGRATION`.

**Find super admins with `super_admin = 1`.** Super admin overrides any permission set, so don't rely on `role_id` to spot them.

**Seats are names, not counts.** `seat_names` lists the paid seats a user holds (for example `sales-hub-professional`). How many seats remain unassigned needs a billing scope that ConfigView deliberately does not ask for.

**User events point at user ids.** For `ADD_USER`, `REMOVE_USER`, `DEACTIVATE_USER` and admin grants, `object_id` in `hubspot_security_activity` holds the affected user's id, which joins to `hubspot_users.user_id`. The catalog questions about deactivated users rely on this.

**Audit log volume.** On a busy Enterprise portal the audit log records every property change, so this table grows fastest. It holds ids and action names only, never field values.

## What isn't collected

* Contacts, companies, deals, tickets, emails, notes or any other CRM record or property value
* The private app token itself, other apps' tokens, client secrets or API keys. Only the fact that one was viewed, created or rotated
* Exported files. Only who exported, when and from where


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.