Everything an AI agent can do with the HubSpot API.

A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.

Endpoints27
API versionv3
Last updated23 June 2026
Orientation

How the HubSpot API works.

The HubSpot API is how an app or AI agent works with a HubSpot account: reading and creating contacts, updating a deal's stage, opening a support ticket, or linking a contact to a company. Access is granted through a Bearer token, either a private app token tied to one account or an OAuth token for a public app, and the token's scopes, like crm.objects.contacts.read or crm.objects.deals.write, decide which objects a call can read or write. A state change can be pushed to a public app as a webhook event.

27Endpoints
6Capability groups
13Read
14Write
10Permissions
Authentication
HubSpot authenticates every call with a Bearer token sent in the Authorization header, against https://api.hubapi.com. A private app, tied to one account, produces a static token that does not expire and is the recommended choice for a single-account integration. A public app, installable across many accounts, uses OAuth 2.0 with a short-lived access token, about 30 minutes, and a refresh token. The legacy hapikey API key is deprecated and should not be used.
Permissions
A token carries scopes, and most CRM objects use a granular pair per object, like crm.objects.contacts.read and crm.objects.contacts.write, with extra crm.objects.contacts.sensitive.read and highly_sensitive variants for protected fields. Property definitions use crm.schemas.{object}.read and write. Tickets additionally accept a legacy single tickets scope covering both read and write. A request without the needed scope returns 403.
Versioning
HubSpot versions its CRM endpoints in the URL path rather than pinning one dated version per account. The core objects, search, properties, and owners APIs are at v3; the associations API is at v4. Breaking changes ship as a new path version, and additive changes and deprecations are announced through the developer changelog. An integration calls a fixed version until it chooses to move up.
Data model
HubSpot is a CRM of objects: contacts, companies, deals, and tickets, plus line items, products, and quotes, each a record with properties. Records are linked by associations, managed through the v4 Associations API, and a contact can associate with a company, a deal, or a ticket. Activity like calls, emails, meetings, and notes is recorded as engagements associated to records. A state change can be pushed to a public app as a webhook event.
Connect & authenticate

Connection & authentication methods.

How an app or AI agent connects to HubSpot determines what it can reach. There is a REST route for making calls, a webhook route for receiving events, and a hosted server that exposes HubSpot tools to agents, and each is governed by the token behind it and the scopes that token carries.

Ways to connect

REST API

The REST API answers at https://api.hubapi.com, takes and returns JSON, and pages through lists with a cursor. A call authenticates with a Bearer token, either a private app access token or an OAuth access token, and the token's scopes decide what it can reach. CRM objects sit at /crm/v3/objects, associations at /crm/v4, and properties at /crm/v3/properties.

Best forConnecting an app or AI agent to HubSpot.
Governed byThe token and the scopes it carries.
Docs ↗

Webhooks

A public app subscribes to event types through the Webhooks v3 API at webhooks/v3/{appId}/subscriptions and registers an HTTPS URL. HubSpot then POSTs events, like contact.creation or deal.propertyChange, to that URL. Each delivery carries an X-HubSpot-Signature header, a SHA-256 hash of the app secret and the request body, so the receiver can confirm it came from HubSpot.

Best forReceiving HubSpot events at an app or AI agent.
Governed byThe app's subscriptions and its signing secret.
Docs ↗

MCP server

A hosted Model Context Protocol server at https://mcp.hubspot.com exposes HubSpot tools to AI agents and LLM clients. It went generally available on 13 April 2026. It authenticates with OAuth using PKCE, and an app's read and write scopes set what the agent can do. Tools cover reading, creating, updating, and searching CRM records like contacts, companies, deals, and tickets, plus property and owner lookups, with search built on the CRM Search API.

Best forConnecting an AI agent to HubSpot through MCP.
Governed byThe OAuth grant and the scopes it carries.
Docs ↗
Authentication

Private app access token

A private app belongs to one HubSpot account and is granted a fixed set of scopes. It produces a static access token that does not expire, sent as a Bearer token. This is the recommended way to connect a single account, and the token must be kept server-side.

TokenBearer access token (private app)
Best forSingle-account integrations and internal tools.
Docs ↗

OAuth 2.0

A public app, installable across many accounts, uses the OAuth 2.0 authorization-code flow. The installing user approves the app's requested scopes, and the app exchanges the code for an access token and a refresh token. The access token is short-lived, typically about 30 minutes, and is refreshed with the refresh token.

TokenOAuth access token (refreshable)
Best forPublic apps installed by multiple HubSpot accounts.
Docs ↗
Endpoint reference

Every HubSpot API method.

Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.

MethodEndpointWhat it doesAccessPermissionVersion

Contacts

List, read, create, update, archive, and search contact records, and act on them in batches.8

Read-only.

Acts oncontact
Permission (capability)crm.objects.contacts.read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read-only. Sensitive fields need crm.objects.contacts.sensitive.read on top.

Acts oncontact
Permission (capability)crm.objects.contacts.read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

A core write.

Acts oncontact
Permission (capability)crm.objects.contacts.write
VersionAvailable since the API’s base version
Webhook eventcontact.creation
Rate limitStandard limits apply

A core write.

Acts oncontact
Permission (capability)crm.objects.contacts.write
VersionAvailable since the API’s base version
Webhook eventcontact.propertyChange
Rate limitStandard limits apply

Archives rather than permanently deletes; a separate GDPR-delete endpoint erases for good.

Acts oncontact
Permission (capability)crm.objects.contacts.write
VersionAvailable since the API’s base version
Webhook eventcontact.deletion
Rate limitStandard limits apply

Read-only. The CRM Search API has its own limit of 4 requests per second per token, separate from the burst limit.

Acts oncontact
Permission (capability)crm.objects.contacts.read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limit4 requests/sec (CRM Search)

A batch request counts as a single call against the rate limit but acts on many records.

Acts oncontact
Permission (capability)crm.objects.contacts.write
VersionAvailable since the API’s base version
Webhook eventcontact.creation
Rate limitStandard limits apply

Read-only.

Acts oncontact
Permission (capability)crm.objects.contacts.read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Companies

List, read, create, update, and search company records.4

Read-only.

Acts oncompany
Permission (capability)crm.objects.companies.read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

A core write.

Acts oncompany
Permission (capability)crm.objects.companies.write
VersionAvailable since the API’s base version
Webhook eventcompany.creation
Rate limitStandard limits apply

A core write.

Acts oncompany
Permission (capability)crm.objects.companies.write
VersionAvailable since the API’s base version
Webhook eventcompany.propertyChange
Rate limitStandard limits apply

Read-only. Subject to the CRM Search API limit of 4 requests per second per token.

Acts oncompany
Permission (capability)crm.objects.companies.read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limit4 requests/sec (CRM Search)

Deals

List, read, create, update, and search deal records in the sales pipeline.4

Read-only.

Acts ondeal
Permission (capability)crm.objects.deals.read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

A core write.

Acts ondeal
Permission (capability)crm.objects.deals.write
VersionAvailable since the API’s base version
Webhook eventdeal.creation
Rate limitStandard limits apply

A core write; moving a deal stage fires deal.propertyChange.

Acts ondeal
Permission (capability)crm.objects.deals.write
VersionAvailable since the API’s base version
Webhook eventdeal.propertyChange
Rate limitStandard limits apply

Read-only. Subject to the CRM Search API limit of 4 requests per second per token.

Acts ondeal
Permission (capability)crm.objects.deals.read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limit4 requests/sec (CRM Search)

Tickets

List, read, create, update, and search support ticket records.4

Read-only. The tickets spec also accepts the legacy tickets scope, which covers both read and write.

Acts onticket
Permission (capability)crm.objects.tickets.read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

A core write. The legacy tickets scope also grants this.

Acts onticket
Permission (capability)crm.objects.tickets.write
VersionAvailable since the API’s base version
Webhook eventticket.creation
Rate limitStandard limits apply

A core write. The legacy tickets scope also grants this.

Acts onticket
Permission (capability)crm.objects.tickets.write
VersionAvailable since the API’s base version
Webhook eventticket.propertyChange
Rate limitStandard limits apply

Read-only. Subject to the CRM Search API limit of 4 requests per second per token.

Acts onticket
Permission (capability)crm.objects.tickets.read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limit4 requests/sec (CRM Search)

Associations

Link and unlink records across objects, like a contact to a company or a deal, and read those links.4

Needs write on both objects being linked, so the exact scopes vary by object type; this is the v4 Associations API.

Acts onassociation
Permission (capability)crm.objects.contacts.write
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Needs write on both linked objects; the scope set varies by object type.

Acts onassociation
Permission (capability)crm.objects.contacts.write
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read-only. Needs read on both objects; the scope set varies by object type.

Acts onassociation
Permission (capability)crm.objects.contacts.read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Unlinks the records without deleting either; needs write on both objects.

Acts onassociation
Permission (capability)crm.objects.contacts.write
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Properties

Read the fields defined on an object and create new ones.3

Read-only. The schema scope matches the object, like crm.schemas.deals.read; the object's own read scope also grants it.

Acts onproperty
Permission (capability)crm.schemas.contacts.read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read-only. The schema scope matches the object type in the path.

Acts onproperty
Permission (capability)crm.schemas.contacts.read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Changes the account's field definitions for every record of that object; the schema write scope matches the object.

Acts onproperty
Permission (capability)crm.schemas.contacts.write
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply
No endpoints match those filters.
Webhooks

Webhook events.

HubSpot can notify an app when something happens in an account, like a contact being created or a deal property changing. A public app subscribes to event types, and HubSpot posts the events to a registered URL, so an integration learns about activity without polling.

EventWhat it signalsTriggered by
contact.creationA new contact was created in the account./crm/v3/objects/contacts
/crm/v3/objects/contacts/batch/create
contact.propertyChangeA property on a contact changed. The subscription names the property to watch./crm/v3/objects/contacts/{contactId}
contact.deletionA contact was deleted or archived./crm/v3/objects/contacts/{contactId}
company.creationA new company was created in the account./crm/v3/objects/companies
company.propertyChangeA property on a company changed./crm/v3/objects/companies/{companyId}
deal.creationA new deal was created in the account./crm/v3/objects/deals
deal.propertyChangeA property on a deal changed, like its stage or amount./crm/v3/objects/deals/{dealId}
ticket.creationA new support ticket was created in the account./crm/v3/objects/tickets
ticket.propertyChangeA property on a ticket changed, like its pipeline stage or priority./crm/v3/objects/tickets/{ticketId}
No events match that search.
Rate limits & pagination

Rate limits, pagination & request size.

HubSpot limits how fast and how much an app can call, by a burst rate measured over ten seconds and by a separate daily request quota, both depending on the account's subscription and any limit-increase add-on.

Request rate

HubSpot meters requests two ways, both depending on the account's subscription and any API Limit Increase add-on. The first is a burst limit per private app, measured over ten seconds: 100 per ten seconds on Free and Starter, 190 per ten seconds on Professional and Enterprise, and 250 per ten seconds with the add-on. The second is a daily quota shared across all of an account's private apps: 250,000 requests a day on Free and Starter, 625,000 on Professional, and 1,000,000 on Enterprise, with the add-on lifting the daily ceiling to 1,000,000. A publicly distributed OAuth app is instead capped at 110 requests per ten seconds per account that installs it. The CRM Search API has its own separate limit of 4 requests per second per token. Going over any of these returns HTTP 429, with the X-HubSpot-RateLimit-Daily, X-HubSpot-RateLimit-Daily-Remaining, X-HubSpot-RateLimit-Max, and X-HubSpot-RateLimit-Remaining headers reporting the current state and a Retry-After header on the response.

Pagination

CRM list endpoints are cursor-based: a limit parameter sets the page size and the response returns paging.next.after, an opaque cursor passed as after to fetch the following page. A search request pages the same way and also caps how deep it goes. Batch read endpoints take up to 100 ids per request instead of paging.

Request size

A batch endpoint acts on at most 100 records per request. A search request returns at most 200 records per page and a maximum of 10,000 total results per query, and allows up to five filter groups with up to six filters each. A single property value is capped at 65,536 characters.

Errors

Status codes & error handling.

The status codes an agent should handle, and what to do about each.

StatusCodeMeaningWhat to do
400VALIDATION_ERRORThe request was bad: a required field is missing, a value is the wrong type, or a value fails validation. The response body holds an errors array with a code and context per field.Read the message and the errors array, fix the named fields, and resend. The request is not retryable as-is.
401UnauthorizedAuthentication is missing or invalid: no Bearer token, a malformed Authorization header, or an expired OAuth token.Send a valid private app or OAuth access token in the Authorization header, refreshing an expired OAuth token first.
403ForbiddenThe token is valid but lacks the scope the request needs, or the account does not have access to the feature.Grant the missing scope to the app, then reauthorize, or confirm the account's subscription covers the endpoint.
404Not FoundThe requested record or endpoint does not exist, for example a bad object id or a deleted record.Verify the id and the path, and confirm the record was not archived.
429RATE_LIMITA rate limit was hit: the per-app ten-second burst limit, the account's daily quota, or the CRM Search API's per-second limit. The X-HubSpot-RateLimit-* headers report the current state.Back off using the Retry-After header, then retry with exponential backoff, and smooth the request rate.
502Bad Gateway / Service UnavailableA transient error on HubSpot's side, which can also appear as 503 or 504.Retry with exponential backoff, and contact HubSpot support if it persists.
Versioning & freshness

Version history.

HubSpot versions its CRM endpoints in the path, with the stable objects, associations, and properties APIs at v3 and v4, and ships dated changes through its developer changelog rather than a single pinned account version.

Version history

What changed, and when

Latest versionv3
v3Current version
Current CRM objects API (v3), associations at v4

HubSpot versions its CRM endpoints in the path. The core objects, search, properties, and owners APIs are at v3, while the associations API is at v4. HubSpot does not pin one dated API version per account; instead a fixed path version stays stable and changes are announced through the developer changelog.

What changed
  • CRM objects, search, batch, properties, and owners served at /crm/v3.
  • Associations served at /crm/v4, with default and labeled association types.
  • Granular per-object scopes (crm.objects.{object}.read/write) plus sensitive and highly_sensitive variants.
2026-04-13Feature update
Remote HubSpot MCP server reaches general availability

The hosted Model Context Protocol server at mcp.hubspot.com graduated from public beta to general availability, giving AI agents an OAuth-authenticated, scope-governed way to read, write, and search CRM data.

What changed
  • MCP server GA at https://mcp.hubspot.com.
  • OAuth with PKCE required for MCP clients.
  • Tools for reading, creating, updating, and searching contacts, companies, deals, and tickets.
2020-04-30Feature update
CRM Search API rate limit raised to 4 requests per second

HubSpot raised the CRM Search API limit from one request per second to four requests per second per authentication token, the separate per-second cap that still governs all search endpoints today.

What changed
  • Search limit increased from 1 to 4 requests per second per token.
  • Applies across all CRM search endpoints combined.

An integration calls a fixed path version and moves up when HubSpot ships a new one.

HubSpot developer changelog ↗
Questions

HubSpot API, answered.

Private app token or OAuth, which should I use?+
A private app is the simpler default for connecting one HubSpot account. It is granted a fixed set of scopes and produces a static access token that does not expire, sent as a Bearer token. OAuth 2.0 is for a public app meant to be installed across many accounts: each install approves the app's scopes, and the app handles short-lived access tokens, around 30 minutes, refreshed with a refresh token. The legacy hapikey API key is deprecated.
How do HubSpot's scopes work?+
A token carries scopes, and each CRM object has a granular read and write scope, like crm.objects.deals.read and crm.objects.deals.write. Sensitive and highly_sensitive variants gate protected fields, and property definitions use crm.schemas.{object} scopes. Tickets also accept an older single tickets scope that covers both read and write. A call missing the scope it needs returns a 403, so an app should request only the scopes it uses.
What are the rate limits?+
There are two main limits, both varying by subscription. A per-app burst limit over ten seconds runs at 100 on Free and Starter, 190 on Professional and Enterprise, and 250 with the API Limit Increase add-on. A daily quota, shared across an account's private apps, runs from 250,000 on Free and Starter up to 1,000,000 on Enterprise. The CRM Search API has its own limit of 4 requests per second. Going over returns 429 with X-HubSpot-RateLimit headers and a Retry-After value.
Why is my search slow or rate-limited when other calls aren't?+
The CRM Search API is metered separately from the general burst limit, at 4 requests per second per token across all search endpoints combined. Searching contacts and deals at the same time draws on the same pool. A search also returns at most 200 records per page and 10,000 total per query, so very large pulls are better done with a cursor-paginated list endpoint than with repeated searches.
How do I receive events instead of polling?+
Use webhooks, which require a public app. The app subscribes to event types like contact.creation, deal.propertyChange, or ticket.creation through the Webhooks v3 API and registers an HTTPS URL. HubSpot POSTs the events to that URL. Each delivery carries an X-HubSpot-Signature header, a SHA-256 hash of the app secret and the raw request body, which the receiver recomputes and compares to confirm the payload came from HubSpot.
How do associations work?+
Associations link records across objects, like a contact to a company or a deal to a ticket, and are managed through the v4 Associations API at /crm/v4. A default association uses HubSpot's built-in link type, while a labeled association applies a named label, like 'Primary' or a custom one. Reading, creating, and deleting an association needs read or write on both objects involved, so the exact scopes depend on which two object types are being linked.
Does HubSpot have an MCP server for AI agents?+
Yes. HubSpot runs a hosted Model Context Protocol server at https://mcp.hubspot.com, generally available since 13 April 2026. It authenticates with OAuth using PKCE, and the connecting app's read and write scopes decide what the agent can do. Its tools read, create, update, and search CRM records like contacts, companies, deals, and tickets, with search built on the CRM Search API.
Related

More crm API guides for agents

What is Bollard AI?

Control what every AI agent can do in HubSpot.

Bollard AI sits between a team's AI agents and HubSpot. Grant each agent exactly the access it needs, read or write, object by object, and every call is checked and logged.

  • Set read, write, or full access per agent, never a shared HubSpot token.
  • Denied by default, so an agent reaches only what has been explicitly allowed.
  • Every call recorded in plain English: who, what, where, and the decision.
HubSpot
CRM Agent
Read contacts ResourceOffReadFull use
Update deals ActionOffReadFull use
Delete records ActionOffReadFull use
Per-agent access, set in Bollard AI, not in HubSpot