HubSpot logo

HubSpot

Overview

HubSpot's API is authenticated with a Private App access token — a long-lived bearer token that you create inside the HubSpot UI and scope to the data Ingest should read. This is HubSpot's recommended pattern for server-to-server integrations on a single account; OAuth2 is also supported but unnecessary unless you're building a multi-tenant marketplace app.

The available endpoints depend on your HubSpot subscription tier — most CRM endpoints work on Free, but Marketing, Service Hub Pro features (feedback_submissions, goals), Enterprise-only features (schemas, roles), Marketing Hub Starter+ (files, folders), and Content Hub (blog_*, landing_pages, site_pages, hubdb_*) require the corresponding paid subscription.

Setup guide

Create the Private App token

  1. Sign in to HubSpot.
  2. Click the gear icon (top right) to open Settings.
  3. In the left sidebar: Integrations → Private Apps.
  4. Click Create a private app, give it a name (e.g. ingest), and an optional description.
  5. Switch to the Scopes tab and check the scope for every object type you want Ingest to read. The most common picks are: crm.objects.contacts.read, crm.objects.companies.read, crm.objects.deals.read, crm.objects.tickets.read, crm.objects.line_items.read, crm.objects.products.read, crm.lists.read, crm.objects.owners.read, tickets, e-commerce, forms, automation, content, files, and business-intelligence. Add others as your endpoint selection grows.
  6. Click Create app and copy the access token shown on the next screen. The full token is only shown once.

Add it to Ingest

In the Ingest UI under Connectors → HubSpot, paste the token. Ingest stores it in AWS Secrets Manager under the key token. The runtime sends it as Authorization: Bearer <token> on every request.

Mind the limits

A HubSpot Private App on Free/Starter has two limits in play simultaneously: a burst ceiling of 100 requests per 10-second window, and a daily ceiling of 250,000 requests. The Ingest runtime dispatches at 5 req/sec globally to respect HubSpot's separate Search-endpoint limit (also 5 req/sec) and uses AIMD backoff if 429s appear.

Errors with status 400 (malformed request), 401 (bad/expired token), 403 (scope missing or paid feature on a Free workspace), and 404 (object id not found) are treated as fatal — fix the cause before retrying.

Pick endpoints

HubSpot's API is large — 66 endpoints in this connector. Most customers want the CRM core (contacts, companies, deals, tickets, plus their *_properties lookups for the field schema) and the Engagement objects (notes, calls, emails, meetings, tasks). Pipelines, owners, lists, and search variants round out the CRM workflow. Marketing, automation, analytics, and CMS endpoints are tier-gated; see each endpoint's description for the subscription requirement.

The cascade is mostly flat — every endpoint takes a token and queries directly. The exceptions:

  • lists_searchlist_memberships (lists must be enumerated first)
  • threadsthread_messages (one set of messages per conversation thread)
  • hubdb_tableshubdb_rows (rows are scoped to a table)
  • association_labels / association_definitions use enum-templated URLs ({from_object} × {to_object}); the generator enumerates the cross-product.

Supported streams

42 endpoints are available out of the box. Each endpoint syncs into its own Iceberg table in Snowflake.

EndpointDescriptionReference
actors
actors
association_definitions
association_definitions
association_labels
association_labels
calls
calls
channel_accounts
channel_accounts
channels
channels
communications
communications
companies
companies
companies_properties
companies_properties
companies_search
companies_search
contacts
contacts
contacts_properties
contacts_properties
contacts_search
contacts_search
deals
deals
deals_properties
deals_properties
deals_search
deals_search
emails
emails
forms
forms
imports
imports
inboxes
inboxes
line_items
line_items
line_items_properties
line_items_properties
list_memberships
list_memberships
lists_search
lists_search
meetings
meetings
notes
notes
owners
owners
pipelines_deals
pipelines_deals
pipelines_tickets
pipelines_tickets
postal_mail
postal_mail
products
products
products_properties
products_properties
quotes
quotes
quotes_properties
quotes_properties
tasks
tasks
taxes
taxes
teams
teams
threads
threads
tickets
tickets
tickets_properties
tickets_properties
tickets_search
tickets_search
users
users

Authentication

Auth type
Bearer Token
Sent as header
Authorization

Performance & limits

Rate limit
Private App on Free/Starter — 100 req/10s + 250,000 req/day. Search endpoints have a separate 5 req/s ceiling. Ingest dispatches at 5 req/s globally to respect the search cap and lets AIMD tune up where higher rates are allowed.
Automatic backoff
Ingest throttles requests to the published rate limit and retries with exponential backoff on transient errors. You don't need to handle 429s, retries, or pagination yourself.

Resources