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
- Sign in to HubSpot.
- Click the gear icon (top right) to open Settings.
- In the left sidebar: Integrations → Private Apps.
- Click Create a private app, give it a name (e.g.
ingest), and an optional description. - 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, andbusiness-intelligence. Add others as your endpoint selection grows. - 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. 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, and lists round out the CRM workflow. Marketing, automation, analytics, and CMS endpoints are tier-gated; see each endpoint's description for the subscription requirement.
Capturing all your fields (important). By default HubSpot's object list endpoints return only a handful of system fields (created/modified dates, id) — not your custom properties. To capture the full record, activate each object's *_properties endpoint alongside the object itself: for example, enable Contact Properties together with Contacts. The object endpoint then reads the complete property list from that lookup and requests every defined field — including your custom properties — on the next run. If your portal defines an unusually large number of properties and requests start failing, pin a specific subset with the Properties to capture setting on the object endpoint.
The cascade is mostly flat — every endpoint takes a token and queries directly. The exceptions:
lists_search→list_memberships(lists must be enumerated first)threads→thread_messages(one set of messages per conversation thread)hubdb_tables→hubdb_rows(rows are scoped to a table)association_labels/association_definitionsuse enum-templated URLs ({from_object}×{to_object}); the generator enumerates the cross-product.
Supported streams
45 endpoints are available out of the box. Each endpoint syncs into its own Iceberg table in Snowflake.
| Endpoint | Description | Reference |
|---|---|---|
| actors actors | – | |
| association_definitions association_definitions | – | |
| association_labels association_labels | – | |
| calls calls | – | |
| calls_properties calls_properties | – | |
| channel_accounts channel_accounts | – | |
| channels channels | – | |
| communications communications | – | |
| communications_properties communications_properties | – | |
| companies companies | – | |
| companies_properties companies_properties | – | |
| contacts contacts | – | |
| contacts_properties contacts_properties | – | |
| deals deals | – | |
| deals_properties deals_properties | – | |
| emails emails | – | |
| emails_properties emails_properties | – | |
| 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 | – | |
| meetings_properties meetings_properties | – | |
| notes notes | – | |
| notes_properties notes_properties | – | |
| owners owners | – | |
| pipelines_deals pipelines_deals | – | |
| pipelines_tickets pipelines_tickets | – | |
| postal_mail postal_mail | – | |
| postal_mail_properties postal_mail_properties | – | |
| products products | – | |
| products_properties products_properties | – | |
| quotes quotes | – | |
| quotes_properties quotes_properties | – | |
| tasks tasks | – | |
| tasks_properties tasks_properties | – | |
| taxes taxes | – | |
| teams teams | – | |
| threads threads | – | |
| tickets tickets | – | |
| tickets_properties tickets_properties | – | |
| users users | – |
Authentication
- Auth type
- Bearer Token
- Sent as header
Authorization- Provider docs
- developers.hubspot.com ↗
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.