HubSpot

Connect & Ingest data from HubSpot

HubSpot is an all-in-one CRM platform that helps businesses manage marketing, sales, customer service, and content management. The Sling HubSpot connector extracts data from the HubSpot REST API, supporting CRM objects (contacts, companies, deals, tickets), engagement data (calls, emails, meetings, notes, tasks), marketing data (forms, emails, lists), and associations.

Setup

The following credentials and inputs are accepted:

Secrets:

  • access_token (required) -> Your HubSpot Legacy App Access Token (starts with pat-)

Inputs:

  • anchor_date (optional) -> The starting date for historical data extraction (default: 1 year ago). Format: YYYY-MM-DD

Getting Your Access Token

HubSpot uses Legacy Apps (formerly called Private Apps) for API authentication:

  1. Log in to your HubSpot account

  2. Go to Settings (gear icon) > Integrations > Private Apps (now called Legacy Apps)

  3. Click Create a private app (or Create a legacy app)

  4. Give your app a name (e.g., "Sling Integration")

  5. Go to the Scopes tab and add the following scopes based on your needs:

Required scopes for CRM data:

  • crm.objects.contacts.read

  • crm.objects.companies.read

  • crm.objects.deals.read

  • crm.objects.owners.read

Optional scopes (add based on endpoints you need):

  • tickets - For tickets endpoint

  • sales-email-read - For engagements_emails

  • crm.objects.marketing_events.read - For marketing events

  • forms - For forms and form_submissions

  • automation - For workflows

  1. Click Create app

  2. Copy your Access token (it starts with pat-na1- or similar)

Using sling conns

sling conns set HUBSPOT type=api spec=hubspot-v3 secrets='{ access_token: pat-na1-xxxxxxxxxxxx }'

Environment Variable

export HUBSPOT='{ type: api, spec: hubspot-v3, secrets: { access_token: "pat-na1-xxxxxxxxxxxx" } }'

Sling Env File YAML

See here to learn more about the sling env.yaml file.

connections:
  HUBSPOT:
    type: api
    spec: hubspot-v3
    secrets:
      access_token: "pat-na1-xxxxxxxxxxxx"

With anchor date for historical data:

connections:
  HUBSPOT:
    type: api
    spec: hubspot-v3
    secrets:
      access_token: "pat-na1-xxxxxxxxxxxx"
    inputs:
      anchor_date: "2020-01-01"

Replication

Here's an example replication configuration to sync HubSpot data to a PostgreSQL database:

source: HUBSPOT
target: MY_POSTGRES

defaults:
  mode: incremental
  object: hubspot.{stream_table}

streams:
  # Core CRM objects with incremental sync
  contacts:
  companies:
  deals:
  tickets:

  # Reference data (full-refresh only)
  owners:
    mode: full-refresh
  deal_pipelines:
    mode: full-refresh

Full refresh for reference data:

source: HUBSPOT
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: hubspot.{stream_table}

streams:
  # Pipeline and configuration data
  deal_pipelines:
  ticket_pipelines:
  owners:

  # Property definitions
  properties_contacts:
  properties_companies:
  properties_deals:

Sync all endpoints:

source: HUBSPOT
target: MY_POSTGRES

defaults:
  mode: incremental
  object: hubspot.{stream_table}

streams:
  # Sync all available endpoints
  '*':

  # Disable child endpoints if you don't need associations
  contact_to_company:
    disabled: true
  deal_to_contact:
    disabled: true
  deal_to_company:
    disabled: true
  form_submissions:
    disabled: true

Endpoints

Core CRM Objects

Endpoint
Description
Incremental

contacts

Contact records

Yes

companies

Company records

Yes

deals

Deal records

Yes

tickets

Ticket records

Yes

products

Product catalog

No

line_items

Deal line items

No

quotes

Quotes/proposals

No

Configuration & Metadata

Endpoint
Description
Incremental

owners

HubSpot users/owners

No

deal_pipelines

Deal pipeline stages

No

ticket_pipelines

Ticket pipeline stages

No

properties_contacts

Contact property definitions

No

properties_companies

Company property definitions

No

properties_deals

Deal property definitions

No

Engagement Objects

Endpoint
Description
Incremental

engagements_calls

Call activity records

Yes

engagements_emails

Email activity records

Yes

engagements_meetings

Meeting activity records

Yes

engagements_notes

Note activity records

Yes

engagements_tasks

Task activity records

Yes

Marketing

Endpoint
Description
Incremental

forms

HubSpot forms

No

form_submissions

Form submission data (child of forms)

No

marketing_emails

Marketing email templates

No

contact_lists

Contact lists (legacy API)

No

Associations (Parent-Child)

Endpoint
Description
Notes

contact_to_company

Contact-company relationships

Requires contacts endpoint to run first

deal_to_contact

Deal-contact relationships

Requires deals endpoint to run first

deal_to_company

Deal-company relationships

Requires deals endpoint to run first

Advanced

Endpoint
Description
Incremental

workflows

Automation workflows

No

email_events

Email opens, clicks, etc.

Yes

To discover available endpoints:

sling conns discover HUBSPOT

Incremental Sync

The HubSpot connector uses time-based incremental sync for supported endpoints:

  • First run: Fetches records modified from anchor_date (default: 1 year ago) to present

  • Subsequent runs: Only fetches records modified after the last sync

Incremental sync is supported for:

  • Core CRM objects (contacts, companies, deals, tickets)

  • Engagement objects (calls, emails, meetings, notes, tasks)

  • Email events

Associations

Association endpoints (contact_to_company, deal_to_contact, deal_to_company) use a queue-based pattern:

  1. First, the parent endpoint runs (e.g., contacts)

  2. Record IDs are collected into a queue

  3. The association endpoint iterates through the queue to fetch relationships

This means you should run the parent endpoint before the association endpoint in your replication.

HubSpot Scopes

Different endpoints require different HubSpot scopes. If you encounter a 403 MISSING_SCOPES error, add the required scope to your Legacy App:

Endpoint Category
Required Scope

Contacts

crm.objects.contacts.read

Companies

crm.objects.companies.read

Deals

crm.objects.deals.read

Tickets

tickets

Owners

crm.objects.owners.read

Forms

forms

Workflows

automation

Marketing Emails

content

Rate Limiting

The HubSpot API has rate limits that vary by subscription:

  • Free/Starter: 100 requests/10 seconds, 250K daily

  • Professional: 190 requests/10 seconds, 625K daily

  • Enterprise: 190 requests/10 seconds, 1M daily

  • Search API: 5 requests/second (more restrictive)

The connector automatically:

  • Uses conservative rate limiting (5 requests/second)

  • Retries with exponential backoff on 429 (rate limit) responses

Common Use Cases

Sync Core CRM Data

source: HUBSPOT
target: MY_POSTGRES

defaults:
  mode: incremental
  object: crm.{stream_table}

streams:
  contacts:
  companies:
  deals:
  tickets:
  owners:
    mode: full-refresh

Sync Engagement Data

source: HUBSPOT
target: MY_POSTGRES

defaults:
  mode: incremental
  object: engagements.{stream_table}

streams:
  engagements_calls:
  engagements_emails:
  engagements_meetings:
  engagements_notes:
  engagements_tasks:

Sync Forms and Submissions

source: HUBSPOT
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: marketing.{stream_table}

streams:
  forms:
  form_submissions:

If you are facing issues connecting, please reach out to us at [email protected], on discord or open a Github Issue here.

Last updated

Was this helpful?