HubSpot API - the complete developer guide to integrations that don’t break
HubSpot’s APIs let you build powerful integrations and apps that connect to HubSpot’s CRM, marketing, sales, service, and automation platform. Developers use HubSpot APIs to sync contacts and companies, create and update deals, track pipeline changes, push form submissions, trigger workflows, listen to webhooks for real-time updates, and power internal tools that give teams a single source of truth.
This guide is written for builders. It focuses on what you need to ship: authentication choices (OAuth vs private app tokens), the core CRM object model (records + properties + associations), search and batch endpoints, webhooks, rate limits, pagination, retry safety, and production architecture patterns.
Two main auth paths
Use OAuth for apps installed across many HubSpot accounts; use private app access tokens for single-account integrations.
CRM = objects + properties
Records (contacts/companies/deals/tickets) store properties. Associations connect records across objects.
Production readiness
Build around rate limits, retries, idempotency, and event-driven webhooks for reliable sync at scale.
This is an independent educational guide. Always verify the latest details in HubSpot’s official developer docs, because endpoints, limits, and recommended platform versions can change over time.
1) What the HubSpot API is (and what you can build)
OverviewHubSpot’s API ecosystem is broad. The simplest way to understand it is to separate “platform building blocks” from “product-specific APIs.” Platform building blocks include authentication, scopes/permissions, rate limits, pagination, search, batching, and webhooks. Product-specific APIs include CRM objects (contacts, companies, deals, tickets), engagements, and other operational endpoints.
Common real-world builds include:
- CRM sync: two-way sync between HubSpot and your database, data warehouse, or another CRM.
- Lead capture pipeline: create contacts from form submissions or product signups and track lifecycle stage changes.
- Sales automation: create deals and line items from checkout events; update deal stages from your billing system.
- Support workflows: create tickets from support requests; link tickets to contacts and companies.
- Event-driven integrations: respond to changes in HubSpot via webhooks (record created/updated, associations changed, etc.).
- Analytics and reporting: export objects on a schedule, build dashboards in your BI tool, and compute retention pipelines.
- App marketplace products: build a public app with OAuth so customers can connect their HubSpot portal to your SaaS.
A useful mental model: HubSpot is not “one API.” It’s a platform with multiple API families, each with its own objects, scopes, limits, and best practices.
2) Authentication: OAuth vs private app access tokens
CriticalHubSpot supports two primary ways to authenticate depending on how your integration is distributed: OAuth for apps installed across multiple HubSpot accounts, and static access tokens (private apps) for integrations installed into a single HubSpot account at a time.
2.1 When to use OAuth
Use OAuth when you’re building a public integration (for your customers) and each customer connects their own HubSpot account. OAuth is the standard flow for “install this app,” where HubSpot users authorize your app with selected scopes. Your system stores access tokens and refresh tokens (when applicable) and uses them to call HubSpot APIs on the customer’s behalf.
2.2 When to use a private app token
Use a private app access token when the integration is for a single HubSpot account—such as your own internal team’s portal. This is common for server-to-server sync where you control the HubSpot account and want a simpler deployment model.
Never put HubSpot tokens in browser JavaScript. Keep them on your server, store them in a secrets manager, rotate regularly, and redact from logs. Treat tokens like passwords.
2.3 OAuth flow (high level)
- Create a public app and configure redirect URLs.
- Send users to the authorization URL with client_id, scopes, and redirect_uri.
- Receive an authorization code to your redirect endpoint.
- Exchange the code for tokens using the OAuth tokens endpoint.
- Store tokens securely and refresh as needed.
# Pseudo-example: exchange authorization code for tokens
POST https://api.hubapi.com/oauth/v1/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&redirect_uri=https://yourapp.com/oauth/callback
&code=AUTHORIZATION_CODE
In production, always validate state parameters, use HTTPS, and store secrets outside source control. Ensure your OAuth app uses least-privilege scopes: request only what you need.
3) HubSpot developer platform basics
FoundationHubSpot’s developer platform supports building both modern apps (recommended versions) and continuing support for legacy apps. From a practical standpoint, you should design your integration as a “platform-aware” system:
- Scopes and permissions: each endpoint requires specific scopes; requests fail without them.
- Consistent object model: CRM objects behave similarly—create, read, update, delete, list, search.
- Strong operational guidance: rate limits, retry behavior, and headers are documented and must be respected.
- Event-driven options: webhooks reduce the need for heavy polling.
If you’re migrating from older endpoints or older app types, treat it as a disciplined engineering project: inventory endpoints, confirm scopes, validate payload shapes, and implement a staging environment where you can replay events safely.
4) The HubSpot CRM model: objects, records, properties, and associations
Core conceptMost HubSpot integrations revolve around the CRM. HubSpot stores CRM information as objects (like contacts, companies, deals, tickets). Each object has records (individual entries). Each record has properties (fields). And records connect to each other through associations.
4.1 Objects and records
Examples of common objects:
- Contacts: people interacting with your business.
- Companies: organizations those people represent.
- Deals: sales opportunities moving through pipelines.
- Tickets: support issues or service requests.
- Line items: products/services attached to deals.
4.2 Properties
Properties store the values you care about: email, first name, lifecycle stage, company domain, deal amount, ticket category, and more. Many properties are standard, and you can create custom properties for your business processes. In most integrations, you will:
- Read properties from HubSpot to enrich your system
- Write properties to HubSpot to keep reps aligned
- Map fields carefully to avoid overwriting important values
4.3 Associations
Associations connect records across objects: a deal is associated with a contact, a company, and line items; a ticket may be associated with a contact and company. Associations are critical for building correct business context, and HubSpot provides API endpoints to manage them, including newer API versions that support labels and schema management.
| Concept | What it is | Why it matters |
|---|---|---|
| Object | A type of data (contacts, companies, deals, tickets, etc.) | Your integration must know which object type it is reading/writing. |
| Record | An instance of an object (one contact, one company) | Records are created/updated during sync and automation. |
| Property | A field on a record (email, amount, lifecycle stage) | Field mapping drives data quality and avoids conflicts. |
| Association | A relationship between records (deal ↔ company) | Enables cross-object context, reporting, and workflows. |
5) CRUD basics: create, read, update, delete, list
PatternsHubSpot’s CRM object APIs share common patterns: create a record with properties, read a record by ID, update specific properties, list records with pagination, and (if needed) archive/delete a record.
5.1 A typical “create contact” request
POST /crm/v3/objects/contacts
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
{
"properties": {
"email": "jane@example.com",
"firstname": "Jane",
"lastname": "Doe",
"lifecyclestage": "lead"
}
}
In production, you typically “upsert” by a unique property rather than creating blindly. For contacts, email is often the unique key, but you should confirm your business rules and avoid creating duplicates across multiple systems.
5.2 Partial updates vs full overwrite
Most HubSpot updates are property-level, meaning you can update only the fields you want without overwriting the rest. This is crucial for safe integrations: you don’t want one sync job to wipe fields that sales reps are updating in the CRM.
5.3 Archiving/deleting safely
Deletions are high-impact. Many integrations avoid deletion and use a “soft-delete” property flag or lifecycle stage change. If you do archive records, keep an audit trail in your own system: who/what job archived it and why.
6) Search: finding the right records without downloading everything
Key featurePolling every record and filtering locally is expensive and slow. HubSpot provides CRM search endpoints that let you filter, sort, and search objects across your CRM. In sync and enrichment workflows, search becomes your “query language” for selecting the right records: “all open deals,” “contacts created after X,” “tickets in pipeline stage Y,” etc.
6.1 Search patterns you’ll use constantly
- Find by property: locate a contact by email, or a company by domain.
- Incremental sync: “all records updated after timestamp” (when supported by your object strategy).
- Operational filters: “all deals in stage Negotiation,” “all tickets assigned to team Support.”
- Backfills: select records in chunks for migration or rebuilding indexes.
POST /crm/v3/objects/contacts/search
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
{
"filterGroups": [
{
"filters": [
{ "propertyName": "email", "operator": "EQ", "value": "jane@example.com" }
]
}
],
"properties": ["email","firstname","lastname","lifecyclestage"],
"limit": 10
}
Tip: Use search for upserts and incremental pulls. Save full “download everything” listing for backfills and audits.
7) Associations: connecting objects (and why labels matter)
RelationshipsAssociations are how HubSpot represents relationships between records (contact ↔ company, deal ↔ company, ticket ↔ contact, etc.). If your integration only syncs objects in isolation, you’ll miss the business context that users depend on.
7.1 Common association workflows
- Create a deal and associate it with the contact who requested a demo.
- Associate a ticket with a company so reporting rolls up correctly.
- Associate line items with a deal for revenue reporting.
- Use association labels to represent meaning (e.g., “Decision maker” vs “Billing contact”).
7.2 Versioning note (v3 vs v4)
HubSpot has multiple versions of association APIs. Newer versions include additional functionality like creating and managing association labels and viewing association schema details. When building long-lived integrations, be deliberate about which version you adopt and document it.
Treat associations as first-class data. Store them in your database, sync them intentionally, and avoid “best guess” relinking that can create noisy CRM graphs.
8) Batch APIs: fewer requests, lower cost, faster sync
ScaleMany HubSpot object APIs support batch endpoints. Batch calls can dramatically reduce request volume, helping you stay within rate limits and improving throughput for migrations and daily sync.
8.1 When to use batch
- Initial data migration or large backfill
- Nightly sync jobs
- Mass property updates (with strong field mapping)
- Retrieving many records by ID
8.2 Practical limits
Batch endpoints generally cap the number of inputs per request (for example, common batch operations limit inputs to 100 records per request). Design your jobs to chunk work into stable batches and persist progress checkpoints so you can resume safely after failure.
POST /crm/v3/objects/contacts/batch/read
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
{
"properties": ["email","firstname","lastname"],
"inputs": [
{ "id": "101" },
{ "id": "102" }
]
}
Batch + search are your two biggest levers for performance. Use them early to avoid building a “poll everything” architecture.
9) Pagination: listing records reliably
Must-haveMost list endpoints paginate results. In production, you must implement pagination correctly so you don’t miss records or repeat them endlessly. A robust pagination design includes:
- Persisting paging cursors/checkpoints
- Handling empty pages and transient failures
- Logging request IDs and response headers for debugging
- Using stable sorting when the API supports it
For large datasets, you should combine pagination with incremental filters (created/updated after) or with search queries, so each run processes only new changes.
Avoid “full resync every hour.” Instead: (1) do one backfill, (2) subscribe to webhooks, (3) run a small periodic reconciliation job to catch any missed events.
10) Webhooks: real-time updates without heavy polling
Event-drivenWebhooks let HubSpot notify your app when events occur—like when a contact is created, a deal stage changes, or an association is updated. Instead of polling the API constantly, you listen for events and process them in near real time.
10.1 How HubSpot webhooks work
- You configure a webhook URL in your HubSpot app settings.
- You create subscriptions for the object/event types you care about.
- HubSpot sends batches of event payloads to your webhook endpoint.
- Your system verifies, acknowledges quickly, and processes asynchronously.
10.2 Webhook design best practices
- Acknowledge fast: return 2xx quickly; do heavy work in a queue.
- Idempotency: handle duplicates safely (events may retry).
- Backpressure: if you fall behind, scale your worker pool, not your webhook response time.
- Replay strategy: keep a reconciliation job in case you miss events.
// PSEUDO-CODE (Node/Express-style)
app.post("/hubspot/webhooks", async (req, res) => {
// 1) Verify signature / authenticity if applicable to your app type
// 2) Acknowledge quickly
res.status(200).send("ok");
// 3) Push events into a queue for async processing
const events = Array.isArray(req.body) ? req.body : [];
await queue.publish("hubspot.events", events);
});
// Worker:
queue.consume("hubspot.events", async (events) => {
for (const evt of events) {
// Idempotency key: evt.subscriptionId + evt.objectId + evt.occurredAt
await processEvent(evt);
}
});
Webhooks are a reliability multiplier. They reduce API calls, reduce sync delay, and let you respond instantly to user actions inside HubSpot.
11) Rate limits: how not to get throttled
Operational
HubSpot enforces API usage limits and returns headers that help you understand current capacity. Limits can include
short-term burst limits and longer-term daily limits, and the exact values depend on your account, auth type, and add-ons.
Always design your integration to handle 429 Too Many Requests.
11.1 Practical strategy
- Prefer webhooks over polling.
- Use batch endpoints to reduce request counts.
- Use search rather than listing everything.
- Queue requests and enforce concurrency caps per portal.
- Retry with exponential backoff + jitter for 429 and transient 5xx errors.
11.2 Limits can change (plan for variability)
HubSpot has historically updated limits over time. For example, HubSpot published changes that increased daily and burst limits for private apps and described capacity packs that add additional daily requests. Treat these as “moving parts”: don’t hardcode assumptions. Instead, implement adaptive throttling based on response headers and durable retry queues.
// PSEUDO-CODE
async function callHubSpot(requestFn, { maxRetries = 6 } = {}) {
let attempt = 0;
while (true) {
try {
return await requestFn();
} catch (err) {
const status = err.status || err.response?.status;
const retryable = status === 429 || (status >= 500 && status <= 599);
if (!retryable || attempt >= maxRetries) throw err;
// Exponential backoff with jitter
const base = Math.min(2000 * Math.pow(2, attempt), 30000);
const jitter = Math.random() * 500;
await sleep(base + jitter);
attempt++;
}
}
}
Your goal is not to “avoid 429 forever.” Your goal is to make throttling a normal, recoverable condition.
12) SDKs and tooling: build faster with client libraries
Developer experienceHubSpot provides official client libraries for popular languages (such as Node.js) and supports Postman collections. SDKs can simplify authentication, pagination, and object operations. But you still need to understand the underlying API: when debugging production issues, you’ll want to inspect raw HTTP requests and responses.
// Node.js (conceptual)
import hubspot from "@hubspot/api-client";
const client = new hubspot.Client({ accessToken: process.env.HUBSPOT_ACCESS_TOKEN });
const contact = await client.crm.contacts.basicApi.create({
properties: { email: "jane@example.com", firstname: "Jane", lastname: "Doe" }
});
console.log(contact);
Keep tokens in environment variables or secret managers. Do not embed them in source code.
13) Production architecture: the “never lose data” integration
Ship safelyA production HubSpot integration is not just “call the API.” It’s a system: it must keep data consistent, handle failures, cope with limits, and provide auditability. Here’s a reference architecture that works for most SaaS + CRM scenarios.
13.1 Reference design
- Auth module: manages OAuth tokens or private app tokens and rotates secrets.
- Sync engine: maps objects + properties, supports backfill and incremental updates.
- Event pipeline: webhooks → queue → workers that apply updates.
- Reconciliation job: periodic search-based checks to catch missed events.
- Rate limit manager: concurrency caps, adaptive backoff, and batching.
- Observability: logs, metrics, DLQ (dead letter queue), and replay tooling.
13.2 Data mapping rules (where integrations usually fail)
- Field ownership: decide which system “owns” each property (your app vs HubSpot UI edits).
- Conflict resolution: if both sides changed a field, choose a policy (last-write-wins, source of truth, manual review).
- Normalization: enforce formats for phone numbers, country codes, and date/time fields.
- Lifecycle semantics: don’t overwrite stages/pipelines unless your business truly requires it.
13.3 Idempotency and deduplication
Build every “create” operation as an upsert when possible: search first, then create only if not found. Store mapping tables: your internal ID ↔ HubSpot record ID. For webhooks, use idempotency keys and ensure events can be processed multiple times safely.
Treat HubSpot as a near-real-time replica, not your only database. Keep your own system-of-record for core entities, and sync intentionally.
14) Error handling: what to do with 400/401/403/404/409/429/5xx
ReliabilityStable integrations are defined by how they handle errors. Below is a practical, implementation-oriented playbook.
| Status | Meaning | What to do |
|---|---|---|
| 400 | Bad request (invalid payload, missing fields) | Validate inputs; log request IDs; return actionable messages to developers. |
| 401 | Unauthorized (missing/invalid token) | Rotate token, re-run OAuth, confirm correct environment and scopes. |
| 403 | Forbidden (insufficient scopes/permissions) | Confirm scopes for the endpoint and the portal’s permissions. |
| 404 | Not found (record doesn’t exist or wrong ID) | Check mapping; handle deletions/archives; avoid infinite retries. |
| 409 | Conflict (duplicate or incompatible state) | Implement dedupe rules; retry only if conflict is transient. |
| 429 | Too many requests (rate limit) | Backoff + jitter; queue; batch; reduce polling; use webhooks. |
| 5xx | Server errors | Retry with backoff; log; escalate if persistent. |
Reliability comes from discipline: structured logs, bounded retries, and a dead-letter queue for records that need manual review.
15) Security checklist: tokens, scopes, and least privilege
GovernanceHubSpot integrations often have access to sensitive customer data: emails, phone numbers, support content, deals and revenue information. Security must be designed in from the beginning.
15.1 Practical checklist
- Least privilege scopes: request only the scopes your app truly needs.
- Token storage: secrets manager; encrypted at rest; no plaintext in logs.
- Rotation: rotate tokens periodically and on suspected compromise.
- Webhook verification: verify authenticity (when supported by your app type) and prevent replay.
- Access control: restrict who in your org can see connected portals and integration logs.
- PII handling: minimize data you store; encrypt; redact in error payloads.
In enterprise contexts, you may also need audit logs, data retention policies, and internal approvals for scope expansion.
16) End-to-end use cases (practical recipes)
Blueprints16.1 “Upsert contact + associate to company” recipe
- Search contact by email.
- If found: update properties; else: create contact.
- Search company by domain; create if needed.
- Create association contact ↔ company.
- Log mapping IDs and source timestamps for future sync.
16.2 “Deal stage updates from billing events” recipe
- Receive billing event (invoice paid, subscription canceled).
- Map event to HubSpot deal ID (store this mapping at checkout).
- Update deal properties and stage.
- Optionally create a note/engagement or timeline event (if used in your stack).
16.3 “Support ticket sync + webhook-driven updates” recipe
- Create ticket when support request is created in your system.
- Associate ticket with contact and company.
- Subscribe to ticket update webhooks and keep your system synchronized.
- Run a daily reconciliation search for tickets updated in the last 24 hours to catch missed events.
Notice the pattern: search → create/update → associate → webhooks for changes → reconciliation. That combination is robust and scalable.
17) FAQ
Quick answersIs HubSpot API free?
HubSpot APIs are generally available to HubSpot accounts, but capabilities and limits can depend on your subscription level, app type, and add-ons. Always check your portal’s current API usage guidelines and limits.
Should I use OAuth or a private app token?
Use OAuth if you’re building an app for many customer portals (multi-tenant). Use a private app token for a single portal integration you control. OAuth is the correct long-term choice for marketplace-style products.
How do I avoid hitting rate limits?
Use webhooks, batch endpoints, and search queries. Queue requests and apply concurrency caps. Handle 429 with backoff + jitter. Keep a small reconciliation job instead of constantly polling.
What’s the most common integration bug?
Property mapping conflicts. Teams accidentally overwrite CRM user edits or use inconsistent formats. Fix it with field ownership rules, conflict resolution policies, and careful normalization.
Can I build a near-real-time sync?
Yes—webhooks drive real-time updates, while periodic reconciliation ensures correctness. This is the standard pattern for reliable CRM sync.
18) Official resources
Links- HubSpot API Reference Overview
- Developer Platform Overview
- Authentication overview (OAuth vs static tokens)
- API usage guidelines & limits
- Webhooks API guide
- CRM search endpoints guide
- CRM contacts API guide
- CRM companies API guide
- CRM associations v3 guide
- CRM associations v4 guide
If you’re building a customer-facing app, also review HubSpot’s app authentication docs and OAuth token management docs in the official developer site.