HubSpot Connector
Manage contacts, companies, deals, and marketing in HubSpot
HubSpot Connector
Integrate your workflows with HubSpot CRM and marketing automation. Create and manage contacts, manage deals, run email campaigns, and sync your customer data seamlessly.
Overview
The HubSpot connector provides 9 operations for managing your inbound marketing and CRM workflows. Whether you're automating contact creation, managing the sales pipeline, or triggering marketing campaigns, this connector makes it easy.
Authentication
HubSpot supports two authentication methods:
Option 1: OAuth 2.0 (Recommended)
Secure, user-authorized access. Best for production:
auth_type: oauth2
client_id: "your-app-client-id"
client_secret: "your-app-secret"
scopes:
- crm.objects.contacts.read
- crm.objects.contacts.write
- crm.objects.companies.read
- crm.objects.deals.read
How to set it up:
- Go to HubSpot App Marketplace > Develop apps
- Create a new app
- Under Auth, enable OAuth and add redirect URI:
https://yourapp.deepchain.dev/oauth/callback - Request the scopes you need (contacts, companies, deals, etc.)
- Copy your Client ID and Client Secret
Option 2: Private App Token
For testing or simpler setups:
auth_type: private_app
access_token: "pat-your-private-app-token"
Create a private app in Settings > Integrations > Private apps and copy the access token.
Available Operations
Here's what you can do:
Contacts
| Operation | What It Does |
|---|---|
getContact |
Fetch a contact by ID |
createContact |
Create a new contact |
updateContact |
Update contact details |
searchContacts |
Search contacts with filters |
Companies
| Operation | What It Does |
|---|---|
getCompany |
Fetch a company by ID |
createCompany |
Create a new company |
updateCompany |
Update company details |
Deals
| Operation | What It Does |
|---|---|
getDeal |
Fetch a deal by ID |
createDeal |
Create a new deal |
updateDeal |
Update deal details |
Practical Workflow Examples
Example 1: Auto-Create Contact from Email Signup
Someone subscribes to your email list → automatically create a contact in HubSpot:
- id: create_contact
type: hubspot_connector
config:
operation: createContact
properties:
email: "{{ input.email }}"
firstname: "{{ input.first_name }}"
lastname: "{{ input.last_name }}"
company: "{{ input.company_name }}"
phone: "{{ input.phone }}"
lifecyclestage: "subscriber"
Example 2: Search for Existing Contacts
Check if a contact already exists before creating a duplicate:
- id: search_contact
type: hubspot_connector
config:
operation: searchContacts
filterGroups:
- filters:
- propertyName: "email"
operator: "EQ"
value: "{{ input.email }}"
limit: 1
Then in a conditional:
- id: check_exists
type: conditional
config:
condition: "{{ search_contact_1.response.length > 0 }}"
true_path: "update_contact"
false_path: "create_contact"
Example 3: Move Contact Through the Funnel
Update a contact's lifecycle stage as they progress:
- id: update_lifecycle
type: hubspot_connector
config:
operation: updateContact
contactId: "{{ input.contact_id }}"
properties:
lifecyclestage: "{{ input.new_stage }}" # e.g., "lead", "marketingqualifiedlead", "customer"
Example 4: Create a Deal and Link to Contact
Create an opportunity and connect it to the contact:
- id: create_deal
type: hubspot_connector
config:
operation: createDeal
properties:
dealname: "{{ input.deal_name }}"
dealstage: "negotiation" # Pick from your HubSpot pipeline stages
amount: "{{ input.deal_value }}"
closedate: "{{ formatDate(input.close_date, 'x') }}" # Unix timestamp
hubspot_owner_id: "{{ input.owner_id }}" # Sales rep user ID
Example 5: Update Multiple Contacts in Bulk
Use search results to update many contacts at once:
- id: find_inactive
type: hubspot_connector
config:
operation: searchContacts
filterGroups:
- filters:
- propertyName: "lifecyclestage"
operator: "EQ"
value: "lead"
- propertyName: "hs_analytics_last_visit"
operator: "LT"
value: "{{ formatDate(subtractDays(now(), 90), 'x') }}"
limit: 100
- id: loop_inactive
type: loop
config:
items: "{{ find_inactive_1.response }}"
- id: update_stage
type: hubspot_connector
config:
operation: updateContact
contactId: "{{ loop_1.current.id }}"
properties:
lifecyclestage: "subscriber"
Rate Limits
HubSpot enforces different limits based on your app type:
- OAuth apps: 100 requests per 10 seconds
- Private apps: 150 requests per 10 seconds
- Burst limit: 1,200 requests per minute
Note: DeepChain handles retries automatically, so you'll rarely hit these limits. But if you do, we'll queue requests until the rate limit resets.
Error Handling
Common HubSpot Errors
| Error | What It Means | How to Fix |
|---|---|---|
UNAUTHORIZED |
Invalid or expired token | Re-authenticate in Credentials |
INVALID_EMAIL |
Email format is invalid | Check the email address |
CONTACT_EXISTS |
Contact already exists | Use update instead of create |
INVALID_PROPERTY |
Property doesn't exist | Check property names in HubSpot |
INVALID_ENUM_VALUE |
Picklist value doesn't exist | Pick a value from the list |
Debugging
Enable debug logging:
Node Configuration:
debug: true
logRequest: true
logResponse: true
Check execution logs for exact API responses from HubSpot.
Best Practices
1. Store Contact IDs, Not Email Addresses
Always use HubSpot's internal contact ID, not email:
# Good
contactId: "{{ input.contact_id }}"
# Okay but slower
searchContacts:
filterGroups:
- filters:
- propertyName: "email"
value: "{{ input.email }}"
2. Use Correct Property Names
HubSpot property names are specific—check your HubSpot setup:
# Standard properties (note lowercase)
email: "{{ input.email }}"
firstname: "{{ input.first_name }}"
lastname: "{{ input.last_name }}"
# Custom properties (usually lowercase with underscores)
custom_field_name: "{{ input.value }}"
3. Format Dates as Unix Timestamps
HubSpot dates need Unix timestamps (milliseconds):
closedate: "{{ formatDate(input.date, 'x') }}" # Converts to Unix timestamp
4. Handle Lifecycle Stages
Use the exact stage names from your HubSpot pipeline:
lifecyclestage: "subscriber" # or "lead", "marketingqualifiedlead", "opportunity", "customer", "evangelist", "other"
5. Batch Operations When Possible
Instead of updating one contact at a time, batch them:
# Do searches once, then loop and update
- id: find_contacts
type: hubspot_connector
config:
operation: searchContacts
# ... filter criteria ...
- id: loop
type: loop
items: "{{ find_contacts_1.response }}"
- id: batch_update
type: hubspot_connector
config:
operation: updateContact
contactId: "{{ loop_1.current.id }}"
# ... update properties ...
Next Steps
- Connectors Overview — See all connectors
- Salesforce Connector — Enterprise CRM alternative
- HubSpot API Documentation — Full API reference
- HubSpot Property Reference — Find property names
- Deal Pipelines — Manage your sales pipeline