Skip to content

HubSpot

Integration with the HubSpot CRM API v3. The family covers the whole lifecycle of a CRM record: create it, read it by id, update its properties, list a page of records, search it with filters, and archive it.

All six nodes work on a generic CRM object: instead of one node per entity, you choose the object type (contacts, companies, deals, tickets) in a parameter, and the same node covers the entire CRM.

Authentication is handled by the credentials module (provider hubspot) using a Private App token sent as a Bearer token. The base URL https://api.hubapi.com is built in, so you never type an endpoint.

NodeInternal nameHTTP call
HubSpot: Create objecthubspotCreateObjectPOST /crm/v3/objects/{object_type}
HubSpot: Get objecthubspotGetObjectGET /crm/v3/objects/{object_type}/{id}
HubSpot: Update objecthubspotUpdateObjectPATCH /crm/v3/objects/{object_type}/{id}
HubSpot: List objectshubspotListObjectsGET /crm/v3/objects/{object_type}
HubSpot: Search objectshubspotSearchObjectsPOST /crm/v3/objects/{object_type}/search
HubSpot: Delete objecthubspotDeleteObjectDELETE /crm/v3/objects/{object_type}/{id}

Every node in the family shares these two parameters; the rest are documented on each operation page.

ParameterTypeRequiredDescription
credentials_idcredentialsYesHubSpot credential (provider hubspot)
object_typetextYesObject type: contacts, companies, deals, tickets. Defaults to contacts

Provider: hubspot. Create it in Credentials → Add → HubSpot.

FieldDescription
tokenPrivate App token, from HubSpot → Settings → Integrations → Private Apps. It starts with pat-. Masked in logs.
timeoutOptional. Request timeout in milliseconds (default 20000).

The token travels in the Authorization header with the Bearer prefix. The Test button on the credential calls GET /crm/v3/objects/contacts?limit=1, so the Private App needs at least the crm.objects.contacts.read scope for the test to pass — and the scopes matching whatever else you plan to automate.

This is the part that trips people up. object_type is a free-text field, not a dropdown. Whatever you type is URL-encoded and appended to /crm/v3/objects/, so it has to be the lowercase, plural API name HubSpot uses in its endpoints — not the label shown in the UI.

What you manage in HubSpotobject_type
Contacts (people)contacts
Companiescompanies
Deals (opportunities)deals
Tickets (service)tickets

Two consequences worth knowing:

  • If you leave the field empty, the node falls back to contacts.
  • The value is not validated before the call. A wrong spelling (contact, Contacts, company) is sent to HubSpot as-is and comes back as a 404.

The field accepts dynamic variables, so {{data.objectType}} works when the type is decided earlier in the flow. Because the value is passed through untouched, any other object type served under the same endpoint — a custom object referenced by its object type id — also reaches HubSpot, but the four types above are the ones the nodes document and default to.

HubSpot represents a record as a flat map of properties: no nesting, no arrays of field objects.

{ "email": "ana@acme.com", "firstname": "Ana", "phone": "+34600111222" }

The keys are HubSpot’s internal property names, which are not the labels you see in the UI. Look them up in HubSpot → Settings → Properties. Common ones:

ObjectFrequent properties
contactsemail, firstname, lastname, phone, company, lifecyclestage
companiesname, domain, industry, phone, city
dealsdealname, amount, dealstage, pipeline, closedate
ticketssubject, content, hs_pipeline, hs_pipeline_stage

The Create, Update and Search nodes take this JSON as a parameter. Dynamic variables are resolved inside the JSON string before it is parsed, so {"email":"{{data.email}}"} works.

Create, Get and Update return the HubSpot object in data, plus a _meta object with the module version and timing:

{
"data": {
"id": "701",
"properties": {
"email": "ana@acme.com",
"firstname": "Ana",
"createdate": "2026-08-05T10:00:00.000Z"
},
"createdAt": "2026-08-05T10:00:00.000Z",
"updatedAt": "2026-08-05T10:00:00.000Z",
"archived": false
},
"_meta": { "moduleVersion": "1.0.0", "success": true, "id": "701", "objectType": "contacts", "totalMs": 240 }
}

List and Search return the results array directly in data (not the envelope), which makes them ready to iterate. Delete returns a small confirmation object.

On failure the node stops the branch and returns an error object instead:

{
"data": {},
"error": { "message": "Property \"emai\" does not exist", "type": "validation", "status": 400 }
}
  • Dynamic variables such as {{data.email}} are resolved in every text parameter (object_type, object_id, properties, limit, after) and inside the JSON parameters, because the JSON is resolved as text first and parsed afterwards. If the result is not valid JSON, the node fails with a validation error instead of sending a partial payload — watch out for values that contain double quotes.
  • Retries are automatic, capped at 3 attempts with exponential backoff, for network errors, timeouts, 429 (honouring Retry-After) and 5xx. Validation (400/409), 404 and authentication errors are not retried.
  • The default request timeout is 20 seconds; raise it with the timeout field in the credential.
  • The token is never written in full to the logs — only a masked form such as pat-…wxyz.
  • Deleting archives: the record can still be restored from HubSpot.
SituationRetryableWhat to do
Validation (400/409)NoHubSpot returns the reason in message (unknown property, duplicate contact…). Fix the data.
Not found (404)NoThe object or the object type does not exist. Check the id and object_type.
Authentication (401/403)NoInvalid token or missing scopes in the Private App. Check the credential.
Rate limit (429)YesRetry-After is honoured and the call retried.
Server (5xx)YesTemporary HubSpot error; retried automatically.
Network / TimeoutYesTransient issue; retried automatically.
  • Salesforce — the other CRM family, based on SOQL and sObjects.
  • Monday — work management with a CRM-like board model.
  • CRM integrations — end-to-end use cases across CRMs.
  • Dynamic variables — how {{data.field}} is resolved.
  • HTTP node — for HubSpot endpoints these nodes do not cover (associations, pipelines, properties…).