How to Build an AI Agent for HubSpot Service Hub (2026)
If your support runs on HubSpot Service Hub, an AI agent that reads a ticket, looks up the contact, answers from your knowledge base, and either replies or escalates is the highest-leverage automation you can add. There are two ways to get there: build it against the HubSpot API yourself, or connect an agent platform that already speaks HubSpot Service Hub. This guide covers both honestly — the real API path with code, the production work it takes, and the faster route — so you can pick the one that fits your team.
What a HubSpot Service Hub AI agent does
The loop is the same as any support agent, wired to HubSpot: a new ticket arrives → the agent reads it and the associated contact's history → it calls tools (look up the order, search your knowledge base, check a policy) → it posts a reply on the conversation or routes the ticket to a human. The trick is doing that reliably against real tickets. (New to agents generally? Start with AI agents for customer service.)
Option 1: Build it against the HubSpot Service Hub API
HubSpot has a full REST API, so you can build the agent yourself. The pieces:
- Read tickets — the CRM Tickets object API and the Conversations API to pull the ticket, its thread, and the associated contact.
- Reply / act — update the ticket (stage, owner, properties) via the CRM API, or send a message on the conversation thread.
- Trigger on new tickets — a HubSpot workflow or webhook subscription fires your endpoint when a ticket is created.
A reply/update tool against the real HubSpot API looks like this. HubSpot's CRM API authenticates with a private-app access token (a Bearer token you generate per app, scoped to tickets read/write and crm.objects.contacts.read); OAuth is the alternative for multi-account apps:
import requests
HS = "https://api.hubapi.com"
HEADERS = {"Authorization": f"Bearer {ACCESS_TOKEN}", # private-app token, tickets scope
"Content-Type": "application/json"}
def update_ticket(ticket_id: str, reply: str):
r = requests.patch(f"{HS}/crm/v3/objects/tickets/{ticket_id}",
json={"properties": {"hs_pipeline_stage": "3", # e.g. "Waiting on contact"
"content": reply}},
headers=HEADERS, timeout=10)
r.raise_for_status() # handle 429 rate limits, token refresh
return {"status": "sent"}
To actually post a customer-visible reply (not just update a property), you send a message on the ticket's associated thread via the Conversations API (/conversations/v3/conversations/threads/{threadId}/messages) — so a full agent wires up update_ticket, a send_message, a get_contact, and a search_knowledge_base, then hands them to an agent loop on the model of your choice. See our from-scratch walkthrough in how to build an AI agent: from scratch vs. platform.
The production part
The API calls are the easy bit; making the agent run on real tickets is the work. You stand up a webhook to trigger the agent, and it has to verify HubSpot's signature and dedupe retries so one ticket never gets two replies. HubSpot signs each webhook with a X-HubSpot-Signature-v3 header (an HMAC-SHA256 over your app secret, method, URI, and raw body, plus a timestamp you must reject if stale), and it retries failed deliveries, so idempotency isn't optional:
import hashlib, hmac, base64, time
from fastapi import FastAPI, Request, HTTPException
app = FastAPI()
seen = set() # back this with Redis/DB in production
def verify_hubspot_v3(req: Request, raw: bytes):
sig = req.headers.get("X-HubSpot-Signature-v3", "")
ts = req.headers.get("X-HubSpot-Request-Timestamp", "0")
if abs(time.time() * 1000 - int(ts)) > 5 * 60 * 1000: # reject stale (>5 min)
raise HTTPException(400, "stale timestamp")
base = f"POST{req.url}{raw.decode()}{ts}".encode()
digest = base64.b64encode(
hmac.new(APP_SECRET.encode(), base, hashlib.sha256).digest()).decode()
if not hmac.compare_digest(digest, sig):
raise HTTPException(401, "bad signature")
@app.post("/hubspot-webhook")
async def on_ticket(req: Request):
raw = await req.body()
verify_hubspot_v3(req, raw)
for event in await req.json(): # HubSpot batches events in an array
eid = event["eventId"]
if eid in seen: # idempotency — HubSpot retries on failure
continue
seen.add(eid)
run_agent(event["objectId"]) # the ticket id
return {"ok": True}
Then the rest: rate-limit handling — HubSpot's public API caps private apps at roughly 100–190 requests per 10 seconds depending on subscription (per the API reference; verify against your own tier), so you back off on 429s and honor the X-HubSpot-RateLimit-Remaining header — plus grounding in your knowledge base (embed the articles and re-index when they change), guardrails (escalate refunds, redact PII, treat ticket text as untrusted input), hosting 24/7, observability, and an eval harness over real historical tickets. That's weeks of work plus permanent upkeep — the undifferentiated infrastructure every support agent needs.
What about HubSpot Service Hub's own AI?
HubSpot ships its own AI under the Breeze brand — including a customer agent that answers tickets and chats no-code from your knowledge base, configured inside Service Hub and priced on HubSpot's terms. It's a real option. Here's a quick rule of thumb for the three routes:
- HubSpot Service Hub's native AI (Breeze) — fastest no-code setup, you're happy on HubSpot's model, and its pricing works for your volume. Least control, least effort.
- Build on the HubSpot Service Hub API yourself — you need a specific model, custom tools wired to your own systems (orders, billing), or full control of the runtime, and you have the engineering to own it. Most control; weeks to build plus permanent upkeep (hosting, evals, maintenance).
- Connect a model-agnostic platform (Macha) — the control, model choice, and custom-tool reach of building, but live in days instead of weeks, with the hosting, observability, and eval harness handled for you.
The rest of this guide is about the second and third routes — where you want more than Breeze's native automation gives you.
Option 2: Connect HubSpot Service Hub via Macha
If the goal is a working agent on your HubSpot — not a project to maintain — a platform that connects natively is far faster. Macha layers on top of HubSpot Service Hub (it's not a HubSpot replacement or a marketplace app you install — it connects via OAuth and works autonomously) with a native HubSpot Service Hub connector:
- One-click connect — authorize HubSpot and the agent can read tickets and post replies on the conversation thread, with a full set of ticket tools ready to use.
- Ground on your knowledge base — add your HubSpot knowledge base as a Source so replies quote real articles.
- Any other system as a tool — Custom Tools turn your order/billing APIs into agent capabilities by describing them.
Custom Tools are how you give the agent everything beyond the help desk: describe the endpoint once, and the model can call it mid-conversation — exactly the model-agnostic, custom-tool control that pushes teams past a native no-code bot.
- Grade before go-live — Studies run the agent against your real historical tickets as a batch evaluation, so you see how it would have answered before it ever touches a live customer, then widen its autonomy as it earns trust.
Build vs. connect — for HubSpot Service Hub
| Build on the HubSpot API | Connect Macha | |
|---|---|---|
| Read/reply to tickets | You write the API client | Native connector (OAuth) |
| Trigger on new tickets | You build a webhook endpoint | Handled |
| Ground on knowledge base | You embed + host a vector store | Add it as a Source |
| Hosting, retries, observability | Your infrastructure | Built in |
| Evaluate before go-live | You build a harness | Studies |
| Time to a live agent | Weeks + ongoing | Same day |
So which should you build?
Build on the API if you need a fully custom runtime, have strict data-residency needs, or the agent is your product. For most HubSpot Service Hub teams who just want tickets resolved, a native connector gets you a measurable agent on your real tickets far faster — and you keep your model of choice. You can start free on Macha, connect HubSpot, and test an agent on your own tickets the same day.
FAQ
Is a HubSpot AI agent the same as HubSpot's own AI (Breeze)? Not necessarily. HubSpot offers built-in AI, but you can also run a model-agnostic agent on top of Service Hub (via its API or a platform like Macha) — useful if you want a specific model, custom tools, or to grade the agent your own way.
Do I need to install a HubSpot marketplace app? No — Macha connects to HubSpot via OAuth and works autonomously; it's an AI layer on top of Service Hub, not a marketplace app you install and manage.
Can the agent take actions, not just answer? Yes — via the HubSpot API (update ticket stage, owner, properties, route) plus your own systems' APIs as tools (order lookups, refunds) through Custom Tools, with guardrails on what it can do unattended.
How do I make sure it's accurate before it replies to customers? Ground it in your knowledge base and grade it against real historical tickets first (Macha's Studies do this), start in a draft/approve mode, and widen autonomy per ticket type as it earns trust.
Resolve tickets automatically with AI agents
Macha's AI agents work on top of the help desk you already use — no code.
Shopify
Stripe
Slack
Notion
Google Workspace
Confluence

