Skip to content
Browse the documentation
Connectors

HubSpot

What the HubSpot connector reads, with which permissions, what it never touches, how it syncs, and the facts it produces.

Last changed Markdown versionllms.txt

Source module: app/connectors/hubspot.py. Kind: both (declared; claims are not produced yet — see limitations). Display name: "HubSpot".

Purpose

Reads ticket pipeline-stage history, meetings and deals as facts so that resolution, meeting-booked and lead-qualified outcomes can be checked against HubSpot. Intended to also ingest Breeze Customer Agent resolutions as claims when an export is available.

Auth and scopes

Item Value
Method Access token: a service key (Settings → Integrations → Service keys, the replacement for private apps on newer accounts) or a private app token, with read scopes only, sent as Authorization: Bearer, against https://api.hubapi.com
Credentials stored (encrypted) access_token; optional base_url
Least-privilege scopes tickets (read), crm.objects.deals.read, crm.objects.meetings.read, crm.objects.contacts.read (declared for email hashing; see limitations). No write scopes.
Connection test GET /crm/v3/objects/tickets?limit=1
Non-secret config none

Fields pulled and why

Object / endpoint Properties Used for
POST /crm/v3/objects/tickets/search (filter hs_lastmodifieddate GT since) hs_pipeline_stage, createdate, hs_lastmodifieddate, closed_date, hs_ticket_priority, source_type Subject id, watermark, channel
GET /crm/v3/objects/tickets/{id}?propertiesWithHistory=hs_pipeline_stage stage history (value, timestamp) Status-change and reopen facts
POST /crm/v3/objects/meetings/search hs_meeting_outcome, hs_meeting_start_time, hs_timestamp Meeting facts
POST /crm/v3/objects/deals/search dealstage, closedate, hs_lastmodifieddate Opportunity-stage facts

Ticket subject/content, notes, emails, calls, contact names and any other properties are not requested.

What is hashed / never stored

  • No raw identifiers are stored. The connector declares the contacts read scope for hashing contact emails, but the current implementation does not fetch contact records; facts from HubSpot therefore carry no customer_hid and link to other sources only by exact subject id.
  • The access token is stored only as ciphertext.

Incremental sync and watermark

  • All three searches filter on hs_lastmodifieddate > <watermark in epoch ms> (0 on first sync), page size 100, cursor via paging.next.after.
  • One additional request per ticket fetches the pipeline-stage history.
  • Watermark = maximum ticket hs_lastmodifieddate (meetings and deals do not advance it).
  • Upserts are idempotent.

Rate-limit handling

Shared HttpClient (Retry-After, exponential backoff on 429/5xx, 6 attempts, immediate reauth failure on 401/403). HubSpot private apps have per-10-second and daily request limits; the per-ticket history request dominates.

Fact types produced

fact_type Subject / kind When Attributes raw_ref
status_change hubspot_ticket_{id} / ticket Each pipeline-stage history entry, in timestamp order from (previous stage or null), to (stage id or name, lower-cased), actor: "agent", channel: <source_type> hubspot:ticket:{id}:stage:{i}
reopen hubspot_ticket_{id} / ticket Stage moves from closed or 4 (default closed stage id) to another stage — hubspot:ticket:{id}:reopen:{i}
meeting_event hubspot_meeting_{id} / customer Each meeting status: occurred when hs_meeting_outcome == completed, otherwise the outcome value, or scheduled hubspot:meeting:{id}
opportunity_stage hubspot_deal_{id} / opportunity Each deal (current stage) stage: <dealstage lower-cased> hubspot:deal:{id}:{dealstage}

Claims produced

None yet. Breeze Customer Agent resolutions must currently be uploaded via CSV mapped to hubspot_breeze_customer_agent_resolution, with subject_id values of the form hubspot_ticket_{id} so they match the facts above.

Subject id format

hubspot_ticket_{ticketId}, hubspot_meeting_{meetingId}, hubspot_deal_{dealId}.

Known limitations

  • No claims. The connector is declared kind = both, but Breeze resolution export ingestion is not implemented.
  • No customer_hid. Contact emails are not fetched, so HubSpot facts cannot be linked to other sources by hashed email; they link by exact subject id only.
  • Pipeline stage values are HubSpot stage ids unless the portal uses labels; contracts that test record_status_in: [closed, …] need the closed stage to be literally closed or 4. Map stages through a CSV upload if the portal uses custom ids.
  • Meeting facts are keyed by meeting id, not by the associated contact or ticket; associations are not fetched, so a meeting cannot be linked to a lead claim without an explicit subject link.
  • Deal stage facts record the current stage at sync time, not the full stage history; the occurred_at is the deal's hs_lastmodifieddate.
  • No customer_message, human_reply, escalation or csat_response facts.