Data and research
HubSpot
A HubSpot integration connects a HubSpot portal to Mobius with HubSpot OAuth so loops can search the CRM, read and write contacts, companies, and deals, and react to HubSpot webhook events.
Use HubSpot when a run needs current CRM context, when an agent should create or update records, or when a record change should start a durable run. Mobius keeps one HubSpot portal connection per project and matches inbound webhook events to that portal.
Capability map
| Capability | Value |
|---|---|
| Provider ID | hubspot |
| Auth kind | oauth2_user |
| Connect flow | HubSpot OAuth user grant |
| Actions | Yes |
| Events | Yes |
| Webhook delivery | Yes, through HubSpot app webhook subscriptions |
| Event samples | No |
| Live status | No |
Connect HubSpot
| Surface | Support |
|---|---|
| App | Open Govern > Integrations, choose HubSpot, then continue through HubSpot OAuth and pick the portal to authorize. |
| CLI | The mobius CLI does not connect HubSpot integrations yet. Use the app or API. |
| API | Call POST /v1/projects/{project}/integrations/providers/hubspot/connect with an empty JSON body, then redirect the user to the returned HubSpot OAuth URL. |
curl -X POST \
"$MOBIUS_API_URL/v1/projects/platform/integrations/providers/hubspot/connect" \
-H "Authorization: Bearer $MOBIUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"default"}'The connect call returns a redirect_url. Send the user there to grant access,
and HubSpot redirects back to Mobius to finish the connection. The default grant
requests read and write scopes for contacts, companies, and deals:
crm.objects.contacts.read
crm.objects.contacts.write
crm.objects.companies.read
crm.objects.companies.write
crm.objects.deals.read
crm.objects.deals.writeHubSpot appears in the catalog only on deployments that have HubSpot OAuth credentials configured. The OAuth button is hidden until the deployment supplies a HubSpot app client ID and secret.
Actions
hubspot.crm.search
hubspot.crm.get
hubspot.crm.create
hubspot.crm.update
hubspot.contact.upsertEach CRM action takes an object_type of contacts, companies, or deals.
Use hubspot.crm.search for free-text or filtered discovery, then the get,
create, and update actions once the loop has stable record IDs.
Search by query and return selected properties:
{
"object_type": "contacts",
"query": "ada@example.com",
"properties": ["email", "firstname", "lastname", "company"],
"limit": 10
}Resolve a record by a unique property instead of its ID with id_property:
{
"object_type": "contacts",
"record_id": "ada@example.com",
"id_property": "email",
"properties": ["email", "lifecyclestage"]
}Use hubspot.contact.upsert when a run should create a contact or update the
existing one keyed on email. It uses email as the identifier, so set the rest of
the contact under properties and leave email out of that object:
{
"email": "ada@example.com",
"properties": {
"firstname": "Ada",
"lastname": "Lovelace",
"company": "Acme"
}
}hubspot.crm.create, hubspot.crm.update, and hubspot.contact.upsert mutate
upstream records, so a retry can repeat the write. Prefer upsert and stable
id_property lookups for idempotent record writes, or add an
interaction before a destructive change. HubSpot
caps most CRM object requests at 100 records per call.
Events
HubSpot webhook callbacks become provider events with the hubspot. prefix.
Mobius emits seven event suffixes for each of the three CRM objects:
hubspot.contact.created
hubspot.contact.deleted
hubspot.contact.property_changed
hubspot.contact.merged
hubspot.contact.restored
hubspot.contact.privacy_deleted
hubspot.contact.association_changed
hubspot.company.created
hubspot.company.deleted
hubspot.company.property_changed
hubspot.company.merged
hubspot.company.restored
hubspot.company.privacy_deleted
hubspot.company.association_changed
hubspot.deal.created
hubspot.deal.deleted
hubspot.deal.property_changed
hubspot.deal.merged
hubspot.deal.restored
hubspot.deal.privacy_deleted
hubspot.deal.association_changedMobius maps HubSpot subscription types to these names: contact.creation
becomes hubspot.contact.created, deal.propertyChange becomes
hubspot.deal.property_changed, and so on. Each event payload includes the
HubSpot object ID, portal ID, subscription type, occurrence time, the changed
property name and value for property_changed events, and the original HubSpot
event under raw.
Use a property_changed event when a loop should react to a specific field
update, and read property_name to filter inside the run. Match a trailing
wildcard such as hubspot.contact.* only when every contact change should start
the run.
Set up webhook delivery
HubSpot webhook subscriptions are configured on the HubSpot app, not per portal, so they are a one-time setup for the deployment rather than a per-project step.
-
In the HubSpot developer app, open Webhooks and set the target URL to the Mobius HubSpot endpoint:
$MOBIUS_API_URL/v1/provider/hubspot/events -
Create the contact, company, and deal subscriptions you want to receive (creation, deletion, property change, and the rest).
-
Connect the portal in Mobius so an active integration row exists for it.
When HubSpot delivers an event, Mobius verifies the X-HubSpot-Signature-v3
header with the app client secret, matches the event's portal to the connected
integration, persists the canonical integration event, and fans it out as a
source event for triggers and waiting runs. A callback signed more than five
minutes ago is rejected to bound replay.
Note: A single delivery can carry a batch of events. Mobius splits the batch and deduplicates on the HubSpot event ID, or a property fingerprint when no ID is present, so a redelivered batch does not start duplicate runs.
Next
- Match HubSpot events in triggers.
- Call CRM actions from action steps.
- Inspect event payloads from the event catalog.
- Add approval pauses before record writes with interactions.