HubSpot Loader
The HubSpot loader pulls CRM, marketing, and sales data from your HubSpot account into your data warehouse. It supports both OAuth 2.0 and private app API keys, and uses HubSpot’s incremental search endpoints for efficient data extraction.
Prerequisites
- A HubSpot account (Free, Starter, Professional, or Enterprise)
- A HubSpot user with Super Admin permissions (for OAuth) or a private app with appropriate scopes
- A connected Warehouse (target warehouse) with write permissions on the target schema
Authentication
The HubSpot loader supports two authentication methods.
OAuth 2.0
- In SignalSmith, click Add Loader and select HubSpot
- Choose OAuth 2.0 as the authentication method
- Click Connect with HubSpot
- Log in to your HubSpot account and select the portal to connect
- Review the requested permissions and click Grant Access
- You’ll be redirected back to SignalSmith with the connection established
SignalSmith automatically refreshes the OAuth token. If the connection is revoked from HubSpot’s Connected Apps settings, you’ll need to re-authenticate.
API Key (Private App)
For environments where OAuth isn’t practical, you can use a HubSpot private app access token:
- In HubSpot, go to Settings > Account Setup > Integrations > Private Apps
- Click Create a Private App
- Name the app (e.g., “SignalSmith Loader”)
- Under Scopes, enable the scopes listed below for each object you want to sync
- Click Create App and copy the access token
- In SignalSmith, paste the access token into the API Key field
Required scopes by object:
| Object | Required Scope |
|---|---|
| Contacts | crm.objects.contacts.read |
| Companies | crm.objects.companies.read |
| Deals | crm.objects.deals.read |
| Custom Objects | crm.objects.custom.read |
| Owners | crm.objects.owners.read |
| Pipelines | crm.objects.pipelines.read |
| Lists | crm.lists.read |
| Forms | forms |
| Email Events | content |
Available Objects
| Object | API Name | Description | Default Sync Mode |
|---|---|---|---|
| Contacts | contacts | People in your CRM — leads, customers, subscribers | Incremental |
| Companies | companies | Organizations associated with contacts and deals | Incremental |
| Deals | deals | Sales opportunities with pipeline stages and amounts | Incremental |
| Tickets | tickets | Support tickets from HubSpot Service Hub | Incremental |
| Products | products | Product catalog items | Incremental |
| Line Items | line_items | Products associated with deals | Incremental |
| Owners | owners | HubSpot users who own records | Full Refresh |
| Pipelines | pipelines | Deal and ticket pipeline definitions | Full Refresh |
| Lists | lists | Static and dynamic contact lists | Full Refresh |
| Forms | forms | Form definitions and submission data | Incremental |
| Email Events | email_events | Email sends, opens, clicks, and bounces | Incremental |
| Custom Objects | custom_objects | Any custom object defined in your HubSpot portal | Incremental |
Custom Objects
HubSpot custom objects (available on Enterprise plans) are automatically discovered. They appear in the object list with their configured label and API name. Custom properties are included in the extracted schema.
Associations
HubSpot uses associations to link objects (e.g., contact-to-company, deal-to-contact). SignalSmith extracts association data into separate junction tables (e.g., contact_to_company) so you can join objects in your models.
Configuration
| Setting | Description | Default |
|---|---|---|
| Auth Method | OAuth 2.0 or API Key | OAuth 2.0 |
| Portal ID | Your HubSpot portal/account ID (auto-detected for OAuth) | Auto-detected |
| Objects | List of objects to sync | — (you choose during setup) |
| Include Associations | Whether to extract association tables | true |
| Sync Mode | Full Refresh or Incremental (per object) | Incremental |
| Cursor Field | Field used for incremental sync | updatedAt |
| Primary Key | Field(s) that uniquely identify a record | id |
| Target Schema | Warehouse schema for HubSpot tables | — (required) |
| Table Prefix | Optional prefix for table names | hs_ |
| Schedule | Sync frequency | Hourly |
Scheduling Notes
- Rate limits: HubSpot enforces API rate limits based on your subscription tier. Free and Starter plans allow 100 requests per 10 seconds; Professional and Enterprise allow 150. SignalSmith respects these limits automatically with backoff and retry.
- Property history: HubSpot’s API can return property change history for contacts and companies. Enable this option if you need historical values — note that it significantly increases data volume.
- Archived records: By default, SignalSmith does not sync archived (deleted) records. Enable “Include Archived” if you need these for analytics.
- Custom object limits: HubSpot Enterprise allows up to 10 custom object definitions. Each custom object is discovered and treated like a standard object.
Schema Mapping
HubSpot property types are mapped to warehouse-compatible types:
| HubSpot Type | Warehouse Type | Notes |
|---|---|---|
string | VARCHAR | |
number | DOUBLE | HubSpot stores all numbers as doubles |
bool | BOOLEAN | |
date | DATE | |
datetime | TIMESTAMP | UTC normalized |
enumeration | VARCHAR | Picklist values as semicolon-separated strings |
json | VARCHAR / JSON | Depends on warehouse support |
phone_number | VARCHAR |
Troubleshooting
| Issue | Solution |
|---|---|
| ”401 Unauthorized” | Your OAuth token or API key is invalid. Re-authenticate or regenerate the private app token |
| ”403 Forbidden” on specific objects | The authenticated user or private app lacks the required scope. Add the necessary scope in HubSpot settings |
| ”429 Too Many Requests” | SignalSmith handles rate limiting automatically with exponential backoff. If this persists, reduce sync frequency |
| Custom objects not appearing | Custom objects require a HubSpot Enterprise subscription. Verify your plan level |
| Missing properties on contacts | HubSpot API returns only properties that are set. Null/empty properties are not included in API responses |
| Association tables are empty | Verify that associations exist in HubSpot. Some association types require Enterprise-tier features |
| ”CONTACT_EXISTS” errors | This indicates duplicate contacts in HubSpot. The loader handles deduplication by primary key in the warehouse |
Next Steps
- Create a model to transform your raw HubSpot data
- Build an audience using HubSpot contacts
- Sync audiences back to HubSpot as a destination