HubSpot UI Connector
The HubSpot UI connector lets a workspace owner link a HubSpot account directly from the agentlyleads app — no terminal, no CLI. Once connected, you pull products and contacts/companies into your workspace with a single click.
Prefer automation? The same sync runs from the command line — see the HubSpot CLI Connector.
Before you begin
You need two things:
-
Owner access. Only the workspace owner can connect, sync, or disconnect. Members with other roles can view sync status but not change it.
-
A HubSpot Private App token with these three read scopes:
Scope Grants access to crm.objects.contacts.readContacts crm.objects.companies.readCompanies crm.objects.products.readProducts
Create a HubSpot Private App
Open Private Apps
In HubSpot, go to Settings → Integrations → Private Apps and click Create a private app.
Name the app
Give it a recognizable name, such as agentlyleads sync.
Add the read scopes
On the Scopes tab, add crm.objects.contacts.read, crm.objects.companies.read, and crm.objects.products.read.
Create and copy the token
Click Create app, confirm with Continue creating, then copy the generated access token.
HubSpot shows the token only once. Copy it now — if you lose it, rotate the token in the Private App settings and reconnect.
Connect HubSpot
Open Integrations
In agentlyleads, go to Settings → Integrations (owner-only).
Paste your token
In the HubSpot card, paste the Private App access token.
Connect
Click Connect. agentlyleads validates the token against the HubSpot API and, on success, stores it encrypted (AES-256-GCM). The card then shows a green Connected badge.
Run a sync
Once connected, two buttons appear on the HubSpot card:
| Button | What it pulls into agentlyleads |
|---|---|
| Sync products | HubSpot products → Offerings |
| Sync contacts & companies | HubSpot contacts and companies → Contacts and Companies |
Click either to start. Large contact/company syncs can take a few minutes — the card shows a spinner while running and updates with a last synced timestamp and row counts when done.
Syncs are idempotent: re-running updates existing records and adds new ones, but never duplicates. Run the same sync as often as you like.
Sync status
| Status | Meaning |
|---|---|
| Idle | No sync running; the last sync time and counts are shown if available |
| Running | A sync is in progress; the sync buttons are disabled |
| Error | The last sync failed; the error message appears below the card |
If a sync is interrupted (for example by a server restart) and stays in Running, agentlyleads unlocks it automatically after 15 minutes so you can re-trigger.
What gets synced
Products → Offerings
| HubSpot field | agentlyleads field |
|---|---|
name | name |
hs_sku | sku |
price | price |
hs_cost_of_goods_sold | cost |
description | description |
hs_recurring_billing_period | billingPeriod (MONTHLY / YEARLY) |
hs_term_in_months | termMonths |
| HubSpot Record ID | externalId (dedupe key) |
HubSpot has no native product category, so synced products start uncategorized.
Contacts and companies
Contacts and companies use the same engine as the CLI migration. Existing records are matched by email (contacts) and domain (companies) and updated in place.
Disconnect
Click Disconnect in the HubSpot card to remove the integration. This deletes the stored token from your workspace. Data you already synced — offerings, contacts, companies — is not deleted.
Security
- The token is never returned to the browser after it's stored. It's encrypted at rest with AES-256-GCM, using a key derived from your server secret.
- Connect, sync, and disconnect are owner-only; the API returns
403 Forbiddenfor other roles. - The token is validated against HubSpot on connect — an invalid token is rejected immediately.