HubSpot Connector
Coppermind's HubSpot connector is a read-only, per-client mind CRM ingest. Connect it from an active client or prospect mind with:
connectors action=connect source_type=hubspot
The tool returns a Coppermind-generated HubSpot OAuth URL. Do not send customers into HubSpot's App Marketplace Claude integration or HubSpot's direct Claude connector; that is a different product path and does not connect Coppermind's auto-ingest pipeline.
After OAuth succeeds, discovery runs on the normal connector poll cadence, defaulting to 15 minutes. The first sync starts a historical backfill, defaulting to two years of HubSpot CRM history, before settling into incremental updates.
Beta Customer Setup Script#
Use this copy when walking a beta customer through setup:
1. In Coppermind, switch to the client/prospect mind that should receive HubSpot data.
Example: switch to CLIENT
2. Ask Coppermind to create the HubSpot OAuth link:
connectors action=connect source_type=hubspot
3. Open the returned auth_url in your browser and approve Coppermind's read-only HubSpot app.
4. Return to Coppermind and check:
connectors action=status
Expected result: the connector moves from pending_setup to active, syncing, or backfilling. Backfill can take time on large portals; normal incremental polling runs about every 15 minutes.
Do not ask the customer for a HubSpot private app token, personal access key, developer API key, service key, client secret, or direct Claude connector install. The v1 connector is OAuth-only and read-only.
OAuth Scopes#
The connector requests only read scopes for the v1 CRM ingest:
crm.objects.contacts.readcrm.objects.companies.readcrm.objects.deals.readcrm.objects.owners.readcrm.schemas.contacts.readcrm.schemas.companies.readcrm.schemas.deals.read
It does not request sales email scopes and does not write back to HubSpot.
The HubSpot user approving OAuth must be allowed to install apps and grant the CRM read scopes above. If app installation is restricted, a HubSpot admin needs to approve the Coppermind app.
What Gets Ingested#
The initial backfill reads:
- Contacts, companies, and deals modified inside the configured historical window.
- The default window is two years back from first successful sync.
- A custom ISO timestamp can be stored in
connectors.config.hubspot_backfill_sincebefore sync starts when a shorter or longer backfill is needed.
After backfill completes, each incremental sync reads:
- Contacts, companies, and deals changed since the connector watermark.
- HubSpot property definitions for contacts, companies, and deals.
- Owner records for resolving
hubspot_owner_id. - Deal associations to contacts and companies, so deal memories can include company and customer geography context.
- All property names returned by the property definition API. Required properties are pulled during search; records are then hydrated through batch reads so custom fields can be preserved when HubSpot accepts the full property set.
If full-property hydration fails for an account, the connector falls back to the required search properties and records the error in connector logs.
Scheduled Marketing Synthesis#
Per-record HubSpot ingest still runs on the normal connector poll cadence, defaulting to every 15 minutes. Strategic HubSpot synthesis runs slower so memory search is not spammed:
- Default synthesis cadence is weekly.
- Set
connectors.config.hubspot_synthesis_cadencetomonthlyfor monthly recompute. - Synthesis waits for the historical backfill to finish before publishing summaries.
- Queue source refs are stable within the cadence period, so retries do not enqueue duplicate summary work.
- Aggregate memory pointers store
aggregate_connector_id,aggregate_period_key, andaggregate_scope, and memory source refs are derived from those fields so multiple HubSpot portals connected to one client mind do not overwrite each other's summaries.
Scheduled synthesis reads from the normalized HubSpot reporting store (hubspot_crm_objects and associations), scoped to the current connector. Weekly/monthly cadence controls refresh timing; the memory text is explicitly labeled as all synced HubSpot CRM history through the refresh date. It recomputes:
- Channel/source performance and closed-won revenue.
- Customer geography from deal-contact/company associations.
- Lead disqualification and lead-leak reasons, including source denominators where available.
- Closed-lost themes.
- A sensitive strategy synthesis fact that summarizes the strongest source, leaks, geography, loss themes, a notable high-value deal signal, and the next planning move to inspect.
Backfill progress is reported by connectors action=status in the hubspot_backfill object:
status:runningorcompletesince: historical window startstarted_at/completed_atcounts: records discovered so far by object typestate: per-object pagination state
The same status response also includes hubspot_diagnostics for each HubSpot connector:
operational_state:active,syncing,backfilling,draining_queue,queue_backed_up,synthesis_error,stale,setup_error,auth_error,rate_limited, orerror.last_successful_hubspot_pull,last_queue_enqueue,queue, andqueue_state.records_pulled_by_type,last_poll_record_counts_by_type,latest_deal_seen, andaggregate_recompute_at.synthesis_cadence,synthesis_period_key,synthesis_recomputed_at,synthesis_count,synthesis_skipped_reason, andsynthesis_last_error.persistent_errorsfor auth, rate-limit, or scope failures.
If OAuth approval returns to Coppermind but the token exchange fails, the connector remains pending_setup and status surfaces last_error plus hubspot_diagnostics.setup_error instead of silently showing no error detail.
Troubleshooting Setup#
If the customer sees:
This account is not eligible to connect to Claude
they are in HubSpot's direct Claude integration flow, not the Coppermind HubSpot connector flow. Send them back to Coppermind and have them open the auth_url returned by connectors action=connect source_type=hubspot.
connectors action=connect source_type=hubspot and connectors action=status include setup_help with the correct flow, permission requirements, and the exact wrong-flow error text for support handoffs.
Memory Mapping#
HubSpot records are not sent through generic text extraction. They are mapped directly to readable memories:
| HubSpot signal | Memory type | Sensitivity |
|---|---|---|
| Closed-won deal | campaign_outcome | sensitive |
| Closed-lost deal with loss reason | objection or pain_point | sensitive |
| Late-stage open deal | buying_signal | sensitive |
| Contact | stakeholder | open |
| Company | fact | open |
| Aggregate channel mix | fact | sensitive |
| Aggregate geography / lead leaks / loss themes | fact | sensitive |
| Strategy synthesis | fact | sensitive |
Memory text uses resolved labels for stages, lifecycle stages, lead statuses, source values, and owners. Raw HubSpot enum IDs should not appear in memory content.
Filtering#
The provider drops internal/test contacts before queueing memories when either condition matches:
- The contact email exactly matches
connectors.config.hubspot_excluded_emailsorconnectors.config.excluded_emails. - The contact email domain matches the pinned client mind's
company_info.domain/company_info.domains,connectors.config.hubspot_excluded_email_domains,connectors.config.hubspot_excluded_domains, orconnectors.config.excluded_email_domains.
Simple property filters can be stored in connectors.config.hubspot_property_filters or connectors.config.hubspot_filters, either as a flat property map or scoped by object type:
{
"hubspot_property_filters": {
"deals": { "pipeline": "default" },
"contacts": { "hs_lead_status": ["NEW", "OPEN"] }
}
}
CRM Report Date Basis#
memory defaults revenue-style reports to HubSpot closedate, which matches normal closed-won revenue reporting. The response includes the selected basis in period.date_basis, period.date_basis_label, and period.hubspot_property; detailed deal rows include both close_date and report_date.
Use date_basis=hs_lastmodifieddate when validating deals that were edited recently but may have been backdated into an earlier close-date period. Supported values are:
closedatehs_closed_won_datedate_entered_closed_wondate_entered_current_stagehs_lastmodifieddate
CRM Report Trust Metadata#
Every memory response includes a trust block before revenue/source conclusions. It records the synced HubSpot reporting store as the data source, whether live fallback was used, portal IDs, connector IDs, client mind/customer IDs, last successful sync, report range, date basis, configured filters, record counts, freshness status, and backfill completeness.
If HubSpot sync is stale or historical backfill is still running, the first entries in audit.caveats say so before the report conclusions. Use those warnings when answering whether the report reflects the latest HubSpot activity.
Disconnect#
connectors action=disconnect connector_id=<id> revokes the stored HubSpot token best-effort, clears encrypted credentials, marks the connector inactive, and stops future polling. Existing memories are preserved.
Ready to try this yourself?
Coppermind is free to start and runs inside Claude. Your first meeting prep will convince you.
Try Coppermind Free