How to Integrate with the HubSpot API: A Step-by-Step Guide for B2B SaaS Teams
February 20, 2026
HubSpot provides a powerful CRM API. You can read and write contacts, companies, deals, pipelines, and engagements. You can subscribe to webhook events. You can search and filter data across objects.
But integrating HubSpot in a production B2B SaaS product involves more than just calling GET /contacts.
This guide covers:
- How to integrate directly with the HubSpot API
- The operational complexity you'll own
- How to integrate HubSpot using Unified's CRM API
- When to build direct vs when to use Unified
This is written for product teams building customer-facing CRM integrations.
Direct HubSpot API Integration
Step 1: Create a HubSpot Developer Account
HubSpot offers a free CMS developer sandbox account for building and testing.
Step 2: Create a Public App (OAuth 2.0)
Inside the HubSpot Developer Dashboard:
- Go to Development → Legacy Apps → Create Legacy App → Public App
- Open the Auth tab
- Under Redirect URLs, add your application's OAuth callback URL, for example:
https://yourapp.com/oauth/hubspot/callback
This must be a URL controlled by your backend. HubSpot will redirect users to this URL after they approve access.
Step 3: Configure OAuth Scopes
HubSpot requires you to explicitly configure scopes in your app.
Important rules:
- The
oauthscope must be included. - If a scope is marked as Required, it must be present in every authorization request.
- If a scope is not configured in the app, it cannot be requested later.
- When using webhooks, read scopes for subscribed objects typically need to be marked as Required.
Example configuration for reading and writing Deals:
{
"requiredScopes": [
"oauth",
"crm.objects.deals.read"
],
"optionalScopes": [
"crm.objects.deals.write"
]
}
Your OAuth authorization request must request the same scopes you configure here.
Scope mismatches will result in authorization failures.
Step 4: Retrieve OAuth Credentials
After creating the app:
- Go to the Auth tab
- Copy:
- Client ID
- Client Secret
You will use these values in your OAuth flow.
If you plan to manage webhook subscriptions or other developer features, you may also need a Developer API Key from the developer dashboard.
Step 5: Implement the OAuth Flow
A direct HubSpot OAuth flow requires:
- Redirect the user to HubSpot's authorization URL
- Receive an authorization code at your redirect URI
- Exchange that code for access and refresh tokens
Example token exchange:
POST https://api.hubapi.com/oauth/v1/token
grant_type=authorization_code
client_id=YOUR_CLIENT_ID
client_secret=YOUR_CLIENT_SECRET
code=AUTH_CODE
redirect_uri=https://yourapp.com/oauth/hubspot/callback
Operational considerations:
- Access tokens are short-lived.
- You must securely store refresh tokens.
- You must refresh access tokens before expiration.
- You must handle revoked tokens.
- You must handle
401 Unauthorizedresponses cleanly.
Step 6: Call the CRM API
Example:
GET https://api.hubapi.com/crm/v3/objects/contacts?limit=100
Authorization: Bearer ACCESS_TOKEN
HubSpot CRM supports:
- Contacts
- Companies
- Deals
- Pipelines
- Tickets
- Custom objects
Search endpoint example:
POST https://api.hubapi.com/crm/v3/objects/contacts/search
Constraints to be aware of:
- Search endpoints are rate limited per account.
- Search results are capped (10,000 results per query).
- Pagination uses cursor-based tokens (
after). - Newly updated records may take a short time to appear in search results.
Step 7: Configure Webhooks
HubSpot webhooks allow you to receive change notifications.
Characteristics:
- Batch delivery (up to ~100 events)
- Not guaranteed ordered
- At-least-once delivery
- Duplicate events possible
- Retries for failed deliveries
To configure webhooks:
- In your HubSpot developer app, go to Webhooks
- Set the Target URL to your webhook receiver, for example:
https://yourapp.com/webhooks/hubspot
- Subscribe to the object events you need (e.g., contact.propertyChange, deal.propertyChange)
You must:
- Verify webhook signatures
- Respond quickly (return 2xx promptly)
- Deduplicate events
- Handle out-of-order delivery
- Implement idempotent writes
Webhook subscriptions are app-level, meaning they apply to every account that installs your app.
Where HubSpot Integrations Become Operationally Expensive
Direct HubSpot integration means you own:
- OAuth scope drift
- Token refresh logic
- Retry logic for 429 responses
- Burst limits (110–190 per 10 seconds depending on plan)
- Daily limits (250K–1M per account depending on tier)
- Webhook subscription management
- Webhook retries + dead-letter handling
- Deduplication logic
- Search window partitioning to avoid 10K cap
- Multi-account authorization storage
- Region handling (US vs EU)
For a single internal tool, this may be manageable.
For a multi-tenant SaaS product supporting hundreds of HubSpot customers, this becomes infrastructure.
Integrating HubSpot via Unified's CRM API
Unified provides a CRM-specific unified API surface.
Instead of implementing per-vendor OAuth, retries, and schema handling, you integrate once against the CRM category.
Step 1: Activate HubSpot in Unified
In your Unified workspace:
- Go to Integrations
- Select HubSpot
- Enter:
- Client ID
- Client Secret
- Developer API Key
- Activate
Unified uses the same redirect URI:
https://api.unified.to/oauth/code
Step 2: Authorize a Customer
Option A — Embedded Authorization Component
Minimal React example:
import UnifiedDirectory from '@unified-api/react-directory';
function App() {
return (
<UnifiedDirectory
workspaceId="{WORKSPACE_ID}"
environmentId="production"
success_redirect="https://yourapp.com/success"
/>
);
}
When a user authorizes HubSpot:
- Unified handles the OAuth exchange.
- Tokens are stored securely.
- You receive a
connection_idin the callback URL.
Option B — Custom Authorization URL
You can build your own UI and redirect to Unified's authorization endpoint with:
- success_redirect
- failure_redirect
- scopes
- state
After authorization, Unified returns:
- connection_id
- state (if provided)
No per-vendor token exchange logic required.
Step 3: Call the CRM API
Example:
GET https://api.unified.to/crm/{connection_id}/contact?limit=100
Authorization: Bearer YOUR_API_KEY
Unified CRM supports:
- list
- get
- create
- update
- remove
Across:
- Company
- Contact
- Deal
- Event
- Lead
- Pipeline
Readable and writable fields are validated, and writable fields are always a subset of readable fields.
Pagination:
- limit
- offset
- updated_gte
- query
- object-specific filters
If you need provider-specific fields, you can request original provider fields when required.
Step 4: Webhooks
Create webhook:
POST /unified/webhook
{
hook_url: "https://yourapp.com/webhook",
connection_id: "{CONNECTION_ID}",
object_type: "crm_contact",
event: "updated"
}
Webhook behavior:
- Native when provider supports it (HubSpot does)
- Virtual when provider lacks webhooks
- Automatic retry:
- 3 immediate retries (1 second apart)
- Then Fibonacci backoff (1 min, 2 min, 3 min, 5 min, 8 min…)
- At-least-once delivery
- Duplicates possible → use atomic writes
Webhook failures do not block API calls.
Step 5: What Unified Handles
Using Unified's CRM API means you do not build:
- OAuth token refresh logic
- Scope mapping logic
- Webhook subscription registration
- Retry backoff for webhook delivery
- Virtual polling fallback
- Per-provider schema mapping
- Per-provider rate-limit modeling
Unified routes every request directly to the source API in real time and does not cache customer data.
Pricing is usage-based, not per-connection.
Direct vs Unified — When to Choose Each
Build Directly with HubSpot If:
- You only support HubSpot
- You need deep HubSpot-only features
- You want full control of vendor logic
- You are building internal tooling
Use Unified's CRM API If:
- You support multiple CRMs (HubSpot + Salesforce + others)
- You want one CRM API surface across providers
- You want to avoid maintaining OAuth logic
- You want webhook retry handled
- You want consistent object schemas
- You want usage-based pricing without per-connection fees
Why This Matters
Integrating with HubSpot is not difficult.
Operating a production-grade HubSpot integration across hundreds of customer accounts is.
The difference between:
- Fetching a contact
and - Running a multi-tenant, webhook-driven CRM integration layer
is infrastructure.
If HubSpot is your only CRM target and you have a dedicated integration team, build direct.
If CRM integrations are a requirement—not your core product—using a CRM-specific unified API surface reduces long-term maintenance and accelerates delivery.
And that tradeoff compounds over time.