Skip to main content

🔌 Hubspot Integration

🎯 Overview

Hubspot is a comprehensive CRM platform that provides customer relationship management, sales pipeline, marketing automation, and customer service tools. The DashClicks integration enables bidirectional synchronization of contacts, companies, deals, and notes (engagements) between the platforms.

Provider: HubSpot, Inc. (https://www.hubspot.com) API Version: v1 (Contacts), v2 (Companies), v1 (Deals), v1 (Engagements) Integration Type: OAuth 2.0 REST API

📁 Directory Structure

Documentation Structure:

hubspot/
├── 📄 index.md - Integration overview and setup
├── 📄 authentication.md - OAuth 2.0 flow and token management
├── 📄 contacts.md - Contact synchronization
├── 📄 companies.md - Company data export
├── 📄 deals.md - Deal pipeline management
└── 📄 notes.md - Engagements (notes) synchronization

Source Code Location:

  • Base Path: external/Integrations/Hubspot/
  • Controllers: Controllers/authController.js, Controllers/contactController.js
  • Providers: Providers/api.js, Providers/crmData.js
  • Routes: Routes/authRoutes.js, Routes/exportRoutes.js
  • Models: Models/keys.js

🗄️ MongoDB Collections

📚 Detailed Schema: See Database Collections Documentation

integrations.hubspot.key

  • Purpose: Store OAuth access tokens and refresh tokens
  • Model: shared/models/hubspot-key.js
  • Primary Use: Persist Hubspot OAuth credentials for authenticated API requests

Schema Structure:

{
_id: ObjectId,
account_id: String, // DashClicks account ID
owner: String, // User ID who connected the integration
token: {
access_token: String, // Short-lived access token (expires in seconds)
refresh_token: String, // Long-lived refresh token for obtaining new access tokens
expires_in: Number, // Token expiration time in seconds
token_type: String // "bearer"
},
generated_at: Number, // Unix timestamp when token was generated
token_invalidated: Boolean // Flag indicating if token is manually invalidated
}
Schema Flexibility

The Hubspot key model uses {strict: false} schema option, allowing additional fields from Hubspot OAuth responses to be stored dynamically.

🔐 Authentication & Configuration

Authentication Method: OAuth 2.0 Authorization Code Grant

Required Environment Variables:

VariableDescriptionRequired
HUBSPOT_CLIENT_IDOAuth application client ID
HUBSPOT_CLIENT_SECRETOAuth application client secret
HUBSPOT_SCOPESOAuth permission scopes (e.g. contacts)
HUBSPOT_AUTHORIZE_URLOAuth authorization endpoint
HUBSPOT_TOKEN_URLOAuth token exchange endpoint
HUBSPOT_GRANT_TYPEGrant type (authorization_code)
HUBSPOT_REDIRECT_URLOAuth callback URL
HUBSPOT_CONTACT_ENDPOINTContacts API endpoint
HUBSPOT_COMPANIES_ENDPOINTCompanies API endpoint
HUBSPOT_DEALS_ENDPOINTDeals API endpoint
HUBSPOT_ENGAGEMENTS_ENDPOINTEngagements (notes) API endpoint

Example Configuration:

HUBSPOT_CLIENT_ID=2acbec95-d71a-4f7a-a039-0f5c2c3e9282
HUBSPOT_CLIENT_SECRET=45e4abbc-41d3-40bc-9dc0-c175f8b01336
HUBSPOT_SCOPES=contacts
HUBSPOT_AUTHORIZE_URL=https://app.hubspot.com/oauth/authorize
HUBSPOT_TOKEN_URL=https://api.hubapi.com/oauth/v1/token
HUBSPOT_GRANT_TYPE=authorization_code
HUBSPOT_REDIRECT_URL=http://localhost:5000/v1/integrations/hubspot/auth/callback
HUBSPOT_CONTACT_ENDPOINT=https://api.hubapi.com/contacts/v1/lists/all/contacts/all
HUBSPOT_COMPANIES_ENDPOINT=https://api.hubapi.com/companies/v2/companies/paged?properties=name&properties=website
HUBSPOT_DEALS_ENDPOINT=https://api.hubapi.com/deals/v1/deal/paged?properties=dealname&includeAssociations=true
HUBSPOT_ENGAGEMENTS_ENDPOINT=https://api.hubapi.com/engagements/v1/engagements/paged

Credential Storage: OAuth tokens stored in integrations.hubspot.key collection

🏗️ Architecture Overview

Key Responsibilities:

  • OAuth Authentication: Manage OAuth 2.0 authorization flow with automatic token refresh
  • Contact Synchronization: Export contacts from Hubspot with pagination support
  • Company Data: Retrieve company information with custom properties
  • Deal Management: Access deal pipeline data with associations
  • Engagement Tracking: Export notes and engagement history

API Communication Pattern:

  • Protocol: REST API over HTTPS
  • Authentication: Bearer token in Authorization header
  • Data Format: JSON request/response
  • Pagination: Cursor-based with offset and limit parameters

Rate Limiting:

  • Hubspot Limits: 10 requests per second per OAuth token (may vary by subscription)
  • Handling: No automatic rate limiting in current implementation
  • Recommendation: Implement exponential backoff for 429 responses

🔗 Features & Capabilities

Core Features

  • 📘 Authentication - OAuth 2.0 flow with automatic token refresh
  • 📗 CRM Data - Contact, company, deal, and note synchronization

🔄 Integration Data Flow

sequenceDiagram
participant Client as DashClicks Frontend
participant Router as API Router
participant Auth as Auth Controller
participant Provider as Hubspot Provider
participant DB as MongoDB
participant Hubspot as Hubspot API

Client->>Router: GET /v1/integrations/hubspot/auth/login
Router->>Auth: Verify scope & access
Auth->>DB: Check existing token
alt Token exists and valid
Auth-->>Client: Redirect to success URL
else Token missing/invalid
Auth->>Auth: Generate JWT state token
Auth-->>Client: Redirect to Hubspot OAuth
Client->>Hubspot: User authorizes app
Hubspot-->>Auth: Redirect with code
Auth->>Provider: Exchange code for tokens
Provider->>Hubspot: POST /oauth/v1/token
Hubspot-->>Provider: Access + refresh tokens
Provider->>DB: Store tokens
Auth-->>Client: Redirect to success URL
end

Note over Client,Hubspot: Data Export Flow

Client->>Router: GET /v1/integrations/hubspot/export/contacts
Router->>DB: Fetch stored token
DB-->>Router: Return refresh token
Router->>Provider: Get fresh access token
Provider->>Hubspot: POST /oauth/v1/token (refresh)
Hubspot-->>Provider: New access token
Provider->>DB: Update stored token
Router->>Provider: Retrieve contacts
Provider->>Hubspot: GET /contacts/v1/lists/all/contacts/all
Hubspot-->>Provider: Contact data + pagination
Provider-->>Client: Formatted response with pagination

🔗 API Endpoints

Authentication Endpoints

EndpointMethodScopeDescription
/v1/integrations/hubspot/auth/loginGETcontacts, contacts.externalInitialize OAuth flow
/v1/integrations/hubspot/auth/callbackGETNoneOAuth callback (auto-redirect)
/v1/integrations/hubspot/auth/DELETEcontacts, contacts.externalDelete OAuth token

Data Export Endpoints

EndpointMethodScopeRequired ParamsDescription
/v1/integrations/hubspot/export/contactsGETcontacts, contacts.externaloffset, limitExport contacts
/v1/integrations/hubspot/export/companiesGETcontacts, contacts.externaloffset, limitExport companies
/v1/integrations/hubspot/export/dealsGETcontacts, contacts.externaloffset, limitExport deals
/v1/integrations/hubspot/export/notesGETcontacts, contacts.externaloffset, limitExport engagements
Dynamic Routing

Export endpoints use dynamic routing with /:type parameter, allowing contacts, companies, deals, or notes as the type.

📊 Response Format

All data export endpoints return a standardized response structure:

{
"success": true,
"message": "DATA Recieved",
"data": {
"has-more": true,
"offset": 3412996225,
"contacts": [...], // or companies, deals, etc.
"vid-offset": 3412996225 // for contacts endpoint
},
"pagination": {
"hasMore": true,
"offset": 3412996225 // Normalized offset for all types
}
}

Pagination Handling:

  • Hubspot uses different pagination fields for different endpoints
  • contacts endpoint: Uses vid-offset (visitor ID offset)
  • companies, deals, notes: Use offset
  • Integration normalizes to consistent pagination.offset field

🚨 Error Handling

Common Error Scenarios:

Error CodeScenarioHandling
401Unauthorized / Invalid tokenToken refresh attempted automatically
404Token not found in databaseUser redirected to re-authenticate
429Rate limit exceededNo automatic retry (manual implementation needed)
400Invalid request parametersError message returned to client

Token Invalidation:

When token_invalidated: true is set on a stored token, the integration automatically deletes the token and forces re-authentication.

📊 Monitoring & Logging

Token Lifecycle Tracking:

  • generated_at field tracks when tokens were last refreshed
  • Token expiration managed automatically via refresh token flow
  • Manual invalidation supported via token_invalidated flag

Recommended Monitoring:

  • Track OAuth callback failures
  • Monitor token refresh frequency
  • Alert on 401 errors indicating token issues
  • Log rate limit 429 responses

🎯 Integration Use Cases

Contact Synchronization

Import Hubspot contacts into DashClicks for unified CRM view:

GET /v1/integrations/hubspot/export/contacts?limit=100&offset=0

Company Intelligence

Retrieve company data for enrichment:

GET /v1/integrations/hubspot/export/companies?limit=50

Deal Pipeline Analysis

Export deal data with associations for reporting:

GET /v1/integrations/hubspot/export/deals?limit=200&offset=400

Activity History

Fetch engagement notes for contact history:

GET /v1/integrations/hubspot/export/notes?limit=100

⚠️ Implementation Notes

OAuth State Management

  • JWT tokens used for state parameter with 6-hour expiration
  • State includes account_id, owner, and forward_url
  • Prevents CSRF attacks by validating state on callback

Token Refresh Strategy

  • Access tokens automatically refreshed on each API call
  • Refresh tokens have no expiration (until manually revoked)
  • Updated tokens saved back to database immediately

Pagination Best Practices

  • Always include limit parameter to control response size
  • Default limit is 10 if not specified
  • Use returned offset value for subsequent requests
  • Check hasMore flag to determine if more data exists

Scope Requirements

All endpoints require one of:

  • contacts scope - Full contact management
  • contacts.external scope - External contact integration

These scopes are enforced via verifyScope middleware.

🚀 Getting Started

1. Configure OAuth App

Create OAuth app in Hubspot developer portal and configure environment variables.

2. Initiate OAuth Flow

Direct users to:

GET /v1/integrations/hubspot/auth/login?forward_url=https://app.dashclicks.com/success

3. Export Data

Once authenticated, export data using:

GET /v1/integrations/hubspot/export/{type}?limit=100&offset=0

Where {type} is one of: contacts, companies, deals, notes

4. Handle Pagination

Use returned pagination.offset for subsequent requests:

GET /v1/integrations/hubspot/export/contacts?limit=100&offset=3412996225

Continue until pagination.hasMore is false.

💬

Documentation Assistant

Ask me anything about the docs

Hi! I'm your documentation assistant. Ask me anything about the docs!

I can help you with:
- Code examples
- Configuration details
- Troubleshooting
- Best practices

Try asking: How do I configure the API?
09:30 AM