| name | hubspot-integration |
| description | Build integrations with HubSpot CRM, Marketing Hub, and Sales Hub using REST APIs and webhooks. Covers contacts, deals, pipelines, email automation, and MCP server patterns for AI-driven CRM workflows. |
| license | Apache 2.0 |
| tags | ["hubspot","crm","marketing-automation","api-integration","sales","mcp"] |
| difficulty | intermediate |
| time_to_master | 6-10 weeks |
| version | 1.0.0 |
HubSpot Integration
Overview
HubSpot serves 200K+ customers across its CRM, Marketing, Sales, and Service Hubs. Unlike Salesforce's enterprise complexity, HubSpot offers a developer-friendly REST API with generous free-tier access, making it the most accessible CRM integration target. This skill covers authentication, core API operations, webhook handling, and AI agent integration patterns.
When to Use This Skill
- Building CRM-connected AI agents for sales or marketing automation
- Syncing contacts, deals, and activities between HubSpot and other systems
- Automating lead nurturing workflows with AI-powered personalization
- Creating MCP servers that expose HubSpot data to Claude or other LLMs
- Implementing real-time deal pipeline analytics
Core Concepts
HubSpot API Structure
| Hub | Key Objects | API Endpoints |
|---|
| CRM | Contacts, Companies, Deals, Tickets | /crm/v3/objects/{objectType} |
| Marketing | Emails, Forms, Lists | /marketing/v3/ |
| Sales | Meetings, Calls, Tasks, Quotes | /crm/v3/objects/ |
| CMS | Pages, Blog posts, Files | /cms/v3/ |
Authentication
HubSpot supports two auth methods:
| Method | Use Case | Token Lifetime |
|---|
| Private App Token | Server-to-server, internal tools | No expiry (revokable) |
| OAuth 2.0 | Multi-tenant apps, marketplace | 30 min (refresh available) |
Object Model
Company (1) ──► (N) Contacts
│ │
│ ▼
│ (N) Deals ──► Pipeline Stages
│ │
▼ ▼
Activities Line Items
(Calls, Emails, (Products,
Meetings, Notes) Quoted prices)
Implementation Guide
Basic API Operations
import { Client } from "@hubspot/api-client";
const hubspot = new Client({ accessToken: process.env.HUBSPOT_TOKEN });
const searchResponse = await hubspot.crm.contacts.searchApi.doSearch({
filterGroups: [{
filters: [{
propertyName: "lifecyclestage",
operator: "EQ",
value: "lead",
}],
}],
sorts: [{ propertyName: "createdate", direction: "DESCENDING" }],
properties: ["firstname", "lastname", "email", "company", "lifecyclestage"],
limit: 20,
});
const deal = await hubspot.crm.deals.basicApi.create({
properties: {
dealname: "Acme Corp - Enterprise Plan",
pipeline: "default",
dealstage: "qualifiedtobuy",
: ,
: ,
},
: [{
: { : contactId },
: [{ : , : }],
}],
});
MCP Server for HubSpot
server.tool(
"search_hubspot_contacts",
"Search HubSpot contacts by name, email, company, or lifecycle stage",
{
query: z.string().describe("Search term"),
lifecycleStage: z.enum(["subscriber", "lead", "marketingqualifiedlead",
"salesqualifiedlead", "opportunity", "customer"]).optional(),
limit: z.number().default(10),
},
async ({ query, lifecycleStage, limit }) => {
const filters = [{ propertyName: "hs_searchable_calculated_phone_number_country_code", operator: "HAS_PROPERTY" }];
const results = await hubspot.crm.contacts.searchApi.doSearch({
query,
filterGroups: lifecycleStage ? [{
filters: [{ propertyName: "lifecyclestage", operator: "EQ", value: lifecycleStage }],
}] : [],
properties: ["firstname", "lastname", "email", "company", "lifecyclestage", "hs_lead_status"],
limit,
});
{
: [{
: ,
: results..(
).(),
}],
};
}
);
server.(
,
,
{
: z.().(),
: z.().(),
},
({ stage, minAmount }) => {
filters = [
{ : , : , : stage },
];
(minAmount) {
filters.({ : , : , : (minAmount) });
}
results = hubspot....({
: [{ filters }],
: [, , , , ],
: [{ : , : }],
: ,
});
total = results..( sum + (d.. || ), );
{
: [{
: ,
: +
results..(
).(),
}],
};
}
);
Webhook Processing
import crypto from "crypto";
function verifyHubSpotWebhook(req, clientSecret) {
const signature = req.headers["x-hubspot-signature-v3"];
const timestamp = req.headers["x-hubspot-request-timestamp"];
if (Date.now() - Number(timestamp) > 300000) return false;
const sourceString = `${req.method}${req.url}${JSON.stringify(req.body)}${timestamp}`;
const hash = crypto.createHmac("sha256", clientSecret).update(sourceString).digest("base64");
return crypto.timingSafeEqual(Buffer.from(hash), Buffer.from(signature));
}
Rate Limits
| Tier | Limit | Burst |
|---|
| Free | 100 calls/10 sec | 110 |
| Starter | 100 calls/10 sec | 110 |
| Professional | 150 calls/10 sec | 160 |
| Enterprise | 200 calls/10 sec | 200 |
Daily limit: 250,000 calls for free/starter; 500,000 for pro/enterprise.
Best Practices
- Use the official Node.js client (
@hubspot/api-client) over raw HTTP
- Batch API calls — use
/batch/read and /batch/create for multiple records
- Implement retry logic for 429 (rate limit) responses with
Retry-After header
- Use search API over list — search supports filters, sorting, and pagination efficiently
- Subscribe to webhooks for real-time sync instead of polling
- Cache property definitions — custom properties rarely change; fetch once and cache
Resources
Changelog
| Version | Date | Changes |
|---|
| 1.0.0 | 2026-03-31 | Initial documentation |