HubSpot – Gotchas
HubSpot is your all-in-one stop for all of your marketing software needs.
16 gotchas across 10 resources
These are connector-specific behaviors and limitations to be aware of when integrating.
Activities2 gotchas
activitiesAllHubspot will only return activities from the last 30 days when using the filter[updated_since] parameter, with a maximum of 10.000 records. More info here. Use filter[type]=call to get custom fields for call activities. When using both filter[type]=call and filter[updated_since] together, you will get partial response data as the calls search endpoint does not support many data fields. Use only one filter to get better data fields. filter[contact_id] returns all activity types (calls, emails, meetings, notes, and tasks) associated with the contact, served by HubSpot's legacy associated-engagements API. Two interactions to note: combining filter[contact_id] with filter[updated_since] is not supported — the contact filter takes precedence and the date filter is silently ignored (the associated-engagements endpoint has no date filter). And filter[type] narrows the result only when type=call (returning that contact's calls); any other type value is ignored and all activity types are still returned.
activitiesUpdateTo update custom fields for call activities, use "type": "call" in the request body.
Companies3 gotchas
companiesAllWhen using a filter or sorting for companies, Hubspot will only return a maximum of 10.000 companies.
companiesAddparent_id sets the company's parent at creation. In HubSpot the parent is a
relationship between two companies rather than a stored field, so it is set by
supplying the parent company's id here.
If parent_id names a company that does not exist, the entire create is rejected and
no company is created — you will not get a company back with the parent silently
dropped.
A company cannot be made its own ancestor. HubSpot rejects a parent_id that would
close a loop, at any depth, not just a direct self-reference.
After a successful create, reading the company straight back may briefly return
parent_id: null. HubSpot derives the field from the underlying relationship and
updates it a few seconds later; re-read the company if you need to confirm the parent.
Be careful not to feed that early read into a follow-up update — on the update endpoint
an explicit parent_id is an instruction, so echoing a stale value back will apply it.
companiesUpdateparent_id sets, changes or removes the company's parent. In HubSpot the parent is a
relationship between two companies rather than a stored field.
Send a company id to set or change the parent, null to remove it, and omit the field
to leave the current parent untouched. An empty string is treated as omitted, not as a
request to remove the parent.
Changing a parent replaces the hierarchy relationship, but the two companies stay associated in HubSpot under a plain, unlabelled relationship. The previous parent will therefore still appear as a related company in the HubSpot UI, without being the parent. Removing a parent likewise leaves any other relationship between the same two companies intact.
A company cannot be made its own ancestor. HubSpot rejects a parent_id that would
close a loop, at any depth, not just a direct self-reference.
If the parent itself cannot be applied — for example parent_id names a company that
does not exist — the whole update is rejected and none of the other fields in the
request are written.
The reverse is not true, and matters. The parent is applied before the rest of the
update. If the request then fails for an unrelated reason — most commonly an unknown or
mistyped custom_fields key — the parent change has already taken effect and is kept,
even though you receive an error. Do not treat a failed company update as "nothing
happened" when the request also carried parent_id: re-read the company to see the
current parent. Sending parent_id on its own, in a request that changes nothing else,
avoids this entirely.
Reading a company back immediately after any parent change returns the previous
parent_id, not the new one. HubSpot derives the field from the underlying
relationship and updates it a few seconds later. This is a trap for read-modify-write
code: if you read a company during that window and send the record back, you will be
sending the old parent as an explicit instruction, and it will be applied — silently
undoing the change you just made. Wait for the value to settle before echoing a company
back, or omit parent_id from updates that are not meant to change the parent.
An update that changes only parent_id still moves the company's updated_at, and so
does clearing a parent on a company that has none — even though no field changed. Two
consequences worth planning for: such a company will be returned again by a later
filter[updated_since] poll, with nothing visibly different from your previous copy;
and because this registers as a modification on HubSpot's side, it can trigger any of
your own HubSpot workflows that key on company property changes or last-modified date.
Contacts2 gotchas
contactsAllWhen using a filter or sorting for contacts, Hubspot will only return a maximum of 10.000 contacts.
contactsAddWhen creating a contact, it is advised to always include an unique email address since Hubspot uses it to prevent duplicate contacts in HubSpot. More info on the Hubspot developer docs.
Leads2 gotchas
leadsAllWhen using a filter or sorting for leads, Hubspot will only return a maximum of 10.000 leads.
leadsAddWhen creating a lead, it is advised to always include an unique email address since Hubspot uses it to prevent duplicate contacts in HubSpot. More info on the Hubspot developer docs.
List Members1 gotcha
listMembersAllHubSpot's list-memberships endpoint returns only the record id and the timestamp at which
the record joined the list, so object_type is always null for HubSpot members. The
record type is a property of the List itself, not of each member — read object_type from
GET /crm/lists/{id} and apply it to every member of that list.
Members are returned sorted by record id ascending, not by the order records were added to the list. For dynamic lists the membership is a saved segment evaluated by HubSpot, so the result is a point-in-time snapshot rather than a stored set.
Lists2 gotchas
listsAllHubSpot's Lists v3 API does not expose description, visibility, folder_id, owner_id, is_favorite, is_default, or is_system, and custom_fields and tags are not mapped, so these fields are not returned for HubSpot. filter_criteria is not mapped in v1 (HubSpot's filterBranch is available downstream via includeFilters=true but is not requested). HubSpot's three list processing types map onto type as follows: DYNAMIC lists are returned as dynamic; MANUAL and SNAPSHOT lists are both returned as static.
listsOneHubSpot's Lists v3 API does not expose description, visibility, folder_id, owner_id, is_favorite, is_default, or is_system, and custom_fields and tags are not mapped, so these fields are not returned for HubSpot. filter_criteria is not mapped in v1 (HubSpot's filterBranch is available downstream via includeFilters=true but is not requested). HubSpot's three list processing types map onto type as follows: DYNAMIC lists are returned as dynamic; MANUAL and SNAPSHOT lists are both returned as static. A list id that does not exist in HubSpot returns a 404 error from the downstream API.
Notes1 gotcha
notesAllHubspot will only return activities from the last 30 days when using the filter[updated_since] parameter, with a maximum of 10.000 records. More info here. Use filter[type]=call to get custom fields for call activities. When using both filter[type]=call and filter[updated_since] together, you will get partial response data as the calls search endpoint does not support many data fields. Use only one filter to get better data fields.
Opportunities1 gotcha
opportunitiesAllWhen using a filter or sorting for opportunities, Hubspot will only return a maximum of 10.000 opportunities and omit the company_id, primary_contact_id, company_id, contact_ids, lead_id and contact_id.
HubSpot allows a deal to have no name, and its Search API omits blank properties from results. title is always returned, but it will be an empty string for such deals rather than a substituted placeholder — an empty title means the deal genuinely has no name in HubSpot, not that the value was unavailable. Treat title as possibly empty when using it as a display label.
Pipelines1 gotcha
pipelinesAllHubSpot does not expose a cross-page total record count on this endpoint. meta.total_count will not appear.
Users1 gotcha
usersAllHubSpot owners are mapped to CRM users in Apideck. HubSpot owners and HubSpot users (people who can log into HubSpot) aren't necessarily the same, as you may have owners created through an integration.