An agent that logs meetings and nudges stale deals gives a RevOps team hours back every week. An agent holding a full-scope token to your CRM is one bad prompt away from overwriting a quarter of lifecycle stages. The difference is not the model; it is how you wire the connection. This guide covers the safe path: which HubSpot auth model to pick, the smallest scope set that still works, how to verify before you allow writes, and the failure modes that catch teams.

One boundary before we start. Our posts on HubSpot meeting logging, lead scoring, and deal-stage nudges answer what an agent should do in your CRM. This page answers how to wire it safely, once, so any of those agents can run on the same connection. Source of truth is HubSpot's developer documentation (developers.hubspot.com, retrieved 2026-07-06). Where this guide and HubSpot's docs disagree, trust HubSpot.

Private app token vs OAuth app

HubSpot gives you two ways to authenticate an integration. Pick by how many portals you manage, not by which tutorial you found first.

Private app. Created inside your own portal under Settings, then Integrations, then Private Apps. You pick scopes at creation and get a single access token for that portal. No consent screens, no refresh tokens, and you can rotate the token from the same settings page. This is the right choice for a company connecting an agent to its own CRM, which is most readers of this page. HubSpot retired account-wide API keys in 2022; private apps are the replacement, and unlike the old keys they are scoped.

Public OAuth app. Built in a developer account and installed into other people's portals through a consent flow. Each install produces its own tokens, refresh logic is on you, and each installed account is limited to 110 requests per 10 seconds. This is the right choice only if you are an agency or a vendor wiring the same integration into many portals.

The failure pattern to avoid is starting with OAuth because a generic tutorial did. You inherit token refresh, app review, and consent UX for a portal you already own. If you run one portal, use a private app.

The minimum scope set

Scopes are chosen when you create the private app, and this is where most integrations go wrong: the temptation is to check every box so nothing fails later. Grant by task instead. The table below covers the common CRM agent jobs (per HubSpot's scopes reference, retrieved 2026-07-06).

ScopeWhat it allowsWhen the agent needs it
crm.objects.contacts.readRead contacts and their engagement historyAlways. Also required to read meetings and notes, which ride on the contacts scopes.
crm.objects.deals.readRead deals, stages, amounts, close datesDeal monitoring, stale-deal nudges, forecast digests.
crm.objects.companies.readRead company recordsEnrichment context; almost always harmless to grant.
crm.objects.owners.readResolve owner names to owner IDsAnything that routes work to a human or filters by rep.
crm.schemas.contacts.read, crm.schemas.deals.readEnumerate properties and pipelinesSetup and validation; lets the tool discover IDs instead of hardcoding names.
crm.objects.contacts.writeCreate and update contacts, log meetings and notesOnly when the agent writes activity or contact fields. Not on day one.
crm.objects.deals.writeUpdate deal properties, move stagesOnly when the agent updates deals, and only with the allow-list below in place.

Two notes on this table. First, engagement objects (meetings, notes, calls, tasks) do not have their own granular scopes; the v3 engagement endpoints are covered by the contacts object scopes, so an agent that logs meetings needs crm.objects.contacts.write. Second, HubSpot also offers sensitive-data scopes such as crm.objects.contacts.sensitive.read on certain tiers. Do not grant them to an agent. If a workflow genuinely needs sensitive fields, that workflow should go through a human.

Start with the read scopes only. The write scopes come after the verification step below has run clean on real data. This mirrors the pattern from our Google Calendar tutorial: read first, earn writes.

Connect and verify

  1. In HubSpot, go to Settings, then Integrations, then Private Apps. Create an app named after the agent's job ("meeting-logger"), not a generic "AI integration". When something misbehaves in the audit log, the name tells you which connection to pull.
  2. Select the read scopes from the table. Skip writes for now.
  3. Copy the access token into your secret manager. The token never goes in a prompt, a repo, or a spreadsheet. In Gravity, you paste it once into the encrypted connection vault and agents reference the connection, never the token.
  4. Make the first safe call: fetch a single contact (GET /crm/v3/objects/contacts?limit=1). No writes. Confirm you get a record back.
  5. Enumerate deal pipelines (GET /crm/v3/pipelines/deals) and note the pipeline and stage IDs. You will need them for the allow-list.
  6. Confirm the guardrail works: call an endpoint you did not scope, expect a 403 with a MISSING_SCOPES error. That error is the system doing its job; you want to see it once on purpose before you see it by surprise.

Only after a few days of clean read-only operation do you edit the app, add the specific write scopes the agent's job requires, and rotate the token. Scope changes on a private app are immediate; there is no re-consent flow to wait on.

Pipeline and property allow-listing

Here is the limit of what scopes can do: crm.objects.deals.write is portal-wide for deals. It cannot say "only the Renewals pipeline" or "only the next-step property". Scopes gate object types; they know nothing about pipelines, properties, or owners. That restriction has to live in the tool wrapper, the same place we put calendar allow-lists in the Calendar guide.

  1. Pipeline allow-list. The agent may touch deals in named pipeline IDs only. Validate on read and on write; reject and log anything else.
  2. Property allow-list. Enumerate the exact properties the agent may write (say, hs_next_step and one custom field). Every other property is read-only to the agent, whatever the scope allows.
  3. Owner allow-list. If the agent assigns or notifies, limit it to a known set of owner IDs so a hallucinated owner cannot swallow a hot lead silently.

Use IDs, not names. Pipeline and property labels get renamed by well-meaning admins; IDs are stable. This is the same principle as role-based access control for agents: the credential says what is possible, the wrapper says what is permitted, and the gap between the two is your audit surface.

Write-safety patterns

Dedupe before create. Before the agent creates a contact, search for the email address first and update the existing record if there is a hit. CRMs rot through duplicate creation faster than through any other agent mistake. One caveat: HubSpot's search index lags slightly behind record creation, so a record created seconds ago may not appear in search yet. Treat a search miss as "probably absent", and make creates idempotent where you can.

Associate everything. A meeting logged without associations to its contact and deal is invisible in every timeline that matters. The tool wrapper should refuse to log an engagement without at least one association, because the model will eventually forget one.

Enrich, never clobber. The default write rule: the agent may fill empty properties and append notes, but may not overwrite a non-empty, human-entered value without an approval step. Most of the value of a CRM agent is filling the gaps humans leave; almost all of the risk is overwriting what humans typed.

Stamp your writes. Set a dedicated property ("last updated by agent") on every agent write. When something looks off two weeks later, you can answer "did the agent do this?" in one filtered view instead of a forensic session.

Rate limits and common failure modes

HubSpot's limits for private apps are generous for an agent workload but easy to trip with a naive loop (numbers from HubSpot's API usage guidelines, retrieved 2026-07-06): 100 requests per 10 seconds per app on Free and Starter, 190 on Professional and Enterprise, with daily caps shared across the account of 250,000, 625,000, and 1,000,000 calls respectively. The API limit increase add-on lifts a portal to 250 requests per 10 seconds and 1,000,000 daily calls. The CRM search API is throttled more tightly than regular endpoints on every tier.

The failure modes we see most:

Burst 429s from per-record loops. An agent asked to "update these 300 deals" that loops one API call per deal will hit the 10-second window. Use the batch endpoints (up to 100 records per call for most objects), and back off exponentially on 429 responses. This belongs in the tool wrapper, not the prompt.

Silent token death. Someone rotates the private app token, or deletes the app, and the agent starts collecting 401s. Alert on the first 401, not the hundredth; a CRM agent that has been failing quietly for a week is worse than one that never ran, because now you do not know what is missing.

Permission drift after portal changes. An admin edits the app's scopes, archives a pipeline on the allow-list, or deletes a property the agent writes. The symptoms are 403s and validation errors that worked yesterday. Re-run the verification calls from the connect step on a schedule; five read-only calls a day is cheap insurance and rounds to nothing against the daily cap.

Search-lag duplicates. Two workflow runs minutes apart both search, both miss the fresh record, both create. If your volume makes this likely, serialize creates through a queue or use idempotency on your side. The same discipline applies to email, where the blast radius is bigger; see giving an agent email access safely.

Everything above is what you build if you wire this yourself. On Gravity, it is what the platform does for you: you connect HubSpot once with a minimum-scope token, and every agent you run reuses that connection with allow-lists, dedupe, and audit built into the tools. You describe the outcome, "log every sales call to the right deal", and the plumbing in this post is already handled. The free tier runs one agent at no cost; paid plans start at $20 per month and include $20 of usage, so you can prove value on the free tier before a card is involved.

Frequently asked questions

Can an AI agent update HubSpot?

Yes. An agent with a private app token and write scopes can create and update contacts, move deals between stages, and log meetings or notes through HubSpot's CRM API. The real question is how much it should be allowed to update. Start with read scopes, verify behaviour on real data, then grant write scopes for the specific objects the agent needs, with an allow-list on pipelines and properties.

What HubSpot scopes does an AI agent need?

A typical CRM agent needs crm.objects.contacts.read, crm.objects.deals.read, crm.objects.owners.read, and the schema read scopes for setup. Add crm.objects.contacts.write only if it logs activity or updates contact fields, and crm.objects.deals.write only if it updates deals. Engagement objects such as meetings and notes are covered by the contacts object scopes rather than dedicated scopes. Never grant the sensitive-data scopes to an agent.

Should I use a private app or an OAuth app for a HubSpot agent?

Use a private app if you are connecting an agent to your own portal: it takes minutes, the token is portal-specific, and you can rotate it from settings. Build an OAuth public app only if you distribute the integration across many portals, for example as an agency or a software vendor. OAuth adds a consent flow, token refresh logic, and a separate rate limit of 110 requests per 10 seconds per installed account.

Is it safe to give an AI agent access to my CRM?

It is safe when access is scoped, not blanket. The safe pattern has four layers: minimum scopes on the token, an allow-list of pipelines and properties in the tool wrapper, enrich-only write rules so the agent never overwrites human-entered data, and an audit trail of every write. A CRM agent with read-only scopes and no allow-list violations for 30 days has earned write access; an agent with a full-scope token on day one has not.

How do I limit what an AI agent can change in HubSpot?

Scopes limit object types portal-wide, but they cannot restrict the agent to one pipeline or one set of properties. That restriction lives in the tool wrapper: validate every write against an allow-list of pipeline IDs, property names, and owner IDs before the API call, and reject and log anything outside it. Use IDs, not names; pipeline and property labels change, IDs do not.

What HubSpot API rate limits apply to an AI agent?

For private apps, HubSpot allows 100 requests per 10 seconds per app on Free and Starter, and 190 per 10 seconds on Professional and Enterprise. Daily limits are shared across the account: 250,000 calls on Free and Starter, 625,000 on Professional, 1,000,000 on Enterprise. The API limit increase add-on raises this to 250 requests per 10 seconds and 1,000,000 per day. The CRM search API has stricter limits, so batch reads and cache lookups where you can.

Three takeaways before you close this tab

Sources