Appearance
HubSpot integration
HubSpot is a CRM platform for marketing, sales, and service. This integration lets your WeWeb backend read and write HubSpot records (contacts, companies, deals, tickets, engagements), manage list membership and associations between records, and submit HubSpot forms, using a service key.
Use cases
- Sync signed-up users into HubSpot as contacts, and keep their properties up to date.
- Create deals and tickets from your app and move them through pipelines.
- Log activity (calls, meetings, notes, tasks) against a contact or company as engagements.
- Add or remove contacts from static lists for campaigns.
- Load CRM records into WeWeb tables to build dashboards and admin screens.
- Submit HubSpot marketing forms from a custom front end.
Setup
HubSpot authenticates with a service key (it starts with pat-). Create one in HubSpot, then add it to WeWeb.
- In HubSpot, go to
Development→Keys→Service keys(on some portals,Settings→Integrations→Service Keys) and clickCreate service key. - Under
Scopes, grant the CRM scopes for the records you use, read and write:crm.objects.contacts,crm.objects.companies,crm.objects.deals, plustickets. Addcrm.lists.readandcrm.lists.writefor list membership,crm.schemas.contacts.read/crm.schemas.companies.read/crm.schemas.deals.readso property and pipeline metadata resolves,crm.objects.owners.readto assign owners, andformsfor the form actions. - Copy the access token (
pat-...). - In WeWeb, open the
Data & APItab, open theIntegrationssubtab, addHubSpot, create a connection, and paste the token intoAccess Token. Do this for each environment you use (Editor,Staging,Production). - Test with a simple action such as
List Contactsto confirm the token works. If you get a403, add the missing scope to the service key and try again.
ONE KEY, ONE PORTAL
A service key is tied to one HubSpot portal (account). Objects created with a test portal's key do not exist under a production portal's key, so use a separate connection per environment if you keep test and live portals apart.
How records and properties work
Every HubSpot record is a set of properties, and every property value is a string, both when you send it and when it comes back (a number like an amount is "1999", a date is a string). Two rules follow from this:
- On
CreateandUpdate, the named fields (e.g.Email,First Name) and theAdditional propertiesobject are merged into one property set. If the same key appears in both, the named field wins. Named fields you leave empty are dropped before the request is sent, so emptyingEmaildoes not erase the contact's email. To clear a property, pass it inAdditional propertieswith an empty string (""). - Internal ids, not labels. Fields like a deal's
PipelineandStage, or a contact'sLifecycle Stage, expect HubSpot's internal ids or enum values, never the label you see in the UI. Use the property and pipeline helpers in the field dropdowns to pick the right value.
Get, List, and Search return only the properties you ask for, plus a small default set, so always request the properties you need to read.
Common pitfalls (setup & usage)
A 403 means a missing scope
If an action returns 403, the token is valid but the service key is missing the scope for that object or operation. Add the scope in HubSpot (for example crm.objects.deals.write to create deals) and retry.
Search lags writes by a few seconds
Search actions run against HubSpot's search index, which updates a few seconds after a write. A contact you just created may not appear in Search Contacts (or in a filtered table view) immediately. List actions read live data and reflect writes at once, so prefer List, or a short retry, right after creating a record.
A record with no properties is still created
HubSpot does not require any property on contacts and companies, so Create Contact or Create Company with every field left empty succeeds and creates a blank record. Always send something that identifies the record: Email (or a name and phone number) for a contact, Name or Domain for a company.
Pipeline and stage need internal ids
Deal Stage, Pipeline, and Ticket pipeline/stage take internal ids, not the labels shown in HubSpot. Passing a label returns a validation error. Read the ids from the field dropdowns (they call HubSpot's pipeline and property APIs) rather than typing them.
Lifecycle stage only moves forward
A contact's Lifecycle Stage only advances (e.g. lead → customer). Setting it to an earlier stage is silently ignored unless you first clear the property.
Delete is really archive
Delete archives the record: it returns 404 over the API afterwards, but it is restorable from the HubSpot UI recycle bin for 90 days. It is not an immediate permanent delete.
Engagements need a timestamp and an association
Create Engagement requires hs_timestamp (an ISO 8601 date or a millisecond epoch; for a task it is the due date). An engagement is also invisible on a record's timeline until you associate it with that record, so create the association (or use the engagement's association fields) after logging it.
List membership only works on static lists
Add Contacts to List and Remove Contacts from List work on MANUAL and SNAPSHOT (static) lists only. Dynamic (active) lists manage their own membership and reject writes. Ids that are already members, or not members, are reported in the response rather than raising an error.
Using HubSpot as a data source for tables
You can use HubSpot as a data source for tables in WeWeb, not just in workflow actions. A table linked to HubSpot loads records from the object you choose and exposes them to table components (e.g. Data Grid) and the Table View: Fetch action.
- In WeWeb, add a table and choose
HubSpotas the source, then select your connection. - Choose the
Resource:Contacts,Companies,Deals,Tickets, orEngagements. ForEngagements, also choose the engagementType. You pick both per view and they cannot be bound to data, so one table always points at the object you choose here. - Configure a view: pick the
Properties(columns) to return, and optionallyFilter groupsandSorts. Set aLimit(default 50; the maximum depends on the endpoint used, see below).
A view with no filters or sorts uses HubSpot's list endpoint (immediate, 100 records per page). Adding a filter or sort switches it to the search endpoint (200 per page, up to 10,000 results, and subject to the few-second indexing lag above). Pagination is cursor-based: the response carries an after token you feed into the next fetch.
Rows arrive flattened: the values inside HubSpot's properties object are lifted to the top level of each row. Bind a column to email, not to properties.email.
Searching with filters
Search actions and filtered table views share HubSpot's filter model:
Filter groupsIs an array of groups. Filters within a group are combined with AND; separate groups are combined with OR. HubSpot allows up to 5 groups of up to 6 filters, and 18 filters in total across all groups.- Each filter has a
propertyName, anoperator, and a value. Operators:EQ,NEQ,LT,LTE,GT,GTE,BETWEEN(useshighValue),IN/NOT_IN(usevalues),HAS_PROPERTY,NOT_HAS_PROPERTY,CONTAINS_TOKEN,NOT_CONTAINS_TOKEN. - Date filters take millisecond epoch strings. The "recently modified" property is
lastmodifieddatefor contacts andhs_lastmodifieddatefor companies, deals, and tickets; "created" iscreatedate. queryIs a free-text search (max 3,000 characters) across default searchable properties, used instead of or alongsidefilterGroups.
All Actions
Actions are grouped by the HubSpot object they act on. Each action name links to its details below.
Contacts
| Action | Description |
|---|---|
| Create Contact | Create a new contact in HubSpot; named fields and the Additional properties object merge into one payload (named fields win). |
| Update Contact | Update an existing contact by record ID; only the properties you set change. |
| Upsert Contact | Create-or-update a contact keyed on email: updates the existing contact when the email is known, creates one otherwise. |
| Get Contact | Retrieve one contact by record ID (404 if archived or missing). |
| List Contacts | List contacts page by page with no filtering; reflects writes immediately. |
| Search Contacts | Search contacts with a free-text query and/or structured filters. Note: new/updated records are indexed a few seconds after writes. |
| Delete Contact | Archive (delete) a contact by record ID; recoverable from the HubSpot recycle bin for 90 days. |
Companies
| Action | Description |
|---|---|
| Create Company | Create a new company in HubSpot; named fields and the Additional properties object merge into one payload (named fields win). |
| Update Company | Update an existing company by record ID; only the properties you set change. |
| Get Company | Retrieve one company by record ID (404 if archived or missing). |
| List Companies | List companies page by page with no filtering; reflects writes immediately. |
| Search Companies | Search companies with a free-text query and/or structured filters. Note: new/updated records are indexed a few seconds after writes. |
| Delete Company | Archive (delete) a company by record ID; recoverable from the HubSpot recycle bin for 90 days. |
Deals
| Action | Description |
|---|---|
| Create Deal | Create a new deal in HubSpot; named fields and the Additional properties object merge into one payload (named fields win). |
| Update Deal | Update an existing deal by record ID; only the properties you set change. |
| Get Deal | Retrieve one deal by record ID (404 if archived or missing). |
| List Deals | List deals page by page with no filtering; reflects writes immediately. |
| Search Deals | Search deals with a free-text query and/or structured filters. Note: new/updated records are indexed a few seconds after writes. |
| Delete Deal | Archive (delete) a deal by record ID; recoverable from the HubSpot recycle bin for 90 days. |
Tickets
| Action | Description |
|---|---|
| Create Ticket | Create a HubSpot ticket from named property fields plus any additional properties, optionally linking it to existing records. |
| Update Ticket | Update a HubSpot ticket by record ID; only the properties you set are changed. |
| Get Ticket | Retrieve one HubSpot ticket by record ID. |
| List Tickets | List HubSpot tickets page by page, without filtering. |
| Search Tickets | Search HubSpot tickets with a free-text query and/or structured filters. |
| Delete Ticket | Archive (delete) a HubSpot ticket by record ID. |
Engagements
| Action | Description |
|---|---|
| Create Engagement | Create a HubSpot engagement (meeting, call, email log, note, task, communication or postal mail) and optionally link it to records. |
| Update Engagement | Update a HubSpot engagement by record ID; only the properties you set are changed. |
| Get Engagement | Retrieve one HubSpot engagement by record ID. |
| List Engagements | List HubSpot engagements of one type page by page, without filtering. |
| Search Engagements | Search HubSpot engagements of one type with a free-text query and/or structured filters. |
| Delete Engagement | Archive (delete) a HubSpot engagement by record ID. |
Lists
| Action | Description |
|---|---|
| Add Contacts to List | Add contact records to a manual or snapshot HubSpot list. |
| Remove Contacts from List | Remove contact records from a manual or snapshot HubSpot list. |
Associations
| Action | Description |
|---|---|
| Create Association | Link two existing HubSpot records with the default (HubSpot-defined, unlabeled) association for their object-type pair. |
| Remove Association | Remove all associations (default and labeled) between two HubSpot records. |
Forms
| Action | Description |
|---|---|
| List Forms | List the HubSpot marketing forms of the portal. |
| Get Form Fields | Retrieve one marketing form with its full definition, including every field name, label, type and required flag — call this before Submit Form. |
| Submit Form | Submit data to a HubSpot marketing form, creating or updating the contact and firing the form's follow-ups. |
Action details
Create Contact
Create a new contact in HubSpot; named fields and the Additional properties object merge into one payload (named fields win).
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
EmailOptional | jane@example.com | The contact's email address; HubSpot's primary deduplication key. | All values sent as strings |
First nameOptional | Jane | The contact's first name. | — |
Last nameOptional | Doe | The contact's last name. | — |
PhoneOptional | +15551234567 | The contact's phone number. | — |
Company nameOptional | Acme Inc. | The contact's company name as plain text; does not associate a company record. | — |
Lifecycle stageOptional | lead | Lifecycle stage of the contact. Only moves forward; clear it first to move back. | Valid: subscriber, lead, marketingqualifiedlead, salesqualifiedlead, opportunity, customer, evangelist, other |
OwnerOptional | 85161889 | HubSpot user (owner) ID for the contact. | Owner user ID string |
Additional propertiesOptional | { "jobtitle": "CTO", "website": "https://example.com" } | Any other contact properties as key-value pairs (custom or standard). Empty string clears a property. | Object; named fields win on conflict |
AssociationsOptional | [{ "to": { "id": "123" }, "types": [{ "associationCategory": "HUBSPOT_DEFINED", "associationTypeId": 1 }] }] | Advanced — link the new contact to existing records at creation (raw v3 shape). | Array; associationTypeId is directional |
Example output
json
{ "id": "545486381788", "properties": { "email": "jane@example.com", "firstname": "Jane" }, "createdAt": "…", "updatedAt": "…", "archived": false }Documentation of API endpoint that powers action: HubSpot API – Create a contact (POST /crm/v3/objects/contacts)
Update Contact
Update an existing contact by record ID; only the properties you set change.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Contact ID | 545486381788 | ID of the contact to update. | Required |
EmailOptional | jane@example.com | The contact's email address. | All values sent as strings |
First nameOptional | Jane | The contact's first name. | — |
Last nameOptional | Doe | The contact's last name. | — |
PhoneOptional | +15551234567 | The contact's phone number. | — |
Company nameOptional | Acme Inc. | The contact's company name as plain text; does not associate a company record. | — |
Lifecycle stageOptional | lead | Lifecycle stage of the contact. Only moves forward; clear it first to move back. | Valid: subscriber, lead, marketingqualifiedlead, salesqualifiedlead, opportunity, customer, evangelist, other |
OwnerOptional | 85161889 | HubSpot user (owner) ID for the contact. | Owner user ID string |
Additional propertiesOptional | { "jobtitle": "CTO", "website": "https://example.com" } | Any other contact properties as key-value pairs. Empty string clears a property. | Object; named fields win on conflict |
Example output
json
{ "id": "545486381788", "properties": { "email": "jane@example.com", "lastname": "Doe" }, "createdAt": "…", "updatedAt": "…", "archived": false }Documentation of API endpoint that powers action: HubSpot API – Update a contact (PATCH /crm/v3/objects/contacts/{contactId})
Upsert Contact
Create-or-update a contact keyed on email: updates the existing contact when the email is known, creates one otherwise.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Email | jane@example.com | Email address used as the upsert key (idProperty: email). | Required |
First nameOptional | Jane | The contact's first name. | — |
Last nameOptional | Doe | The contact's last name. | — |
PhoneOptional | +15551234567 | The contact's phone number. | — |
Company nameOptional | Acme Inc. | The contact's company name as plain text; does not associate a company record. | — |
Lifecycle stageOptional | lead | Lifecycle stage of the contact. Only moves forward; clear it first to move back. | Valid: subscriber, lead, marketingqualifiedlead, salesqualifiedlead, opportunity, customer, evangelist, other |
OwnerOptional | 85161889 | HubSpot user (owner) ID for the contact. | Owner user ID string |
Additional propertiesOptional | { "jobtitle": "CTO", "website": "https://example.com" } | Any other contact properties as key-value pairs. Empty string clears a property. | Object; named fields win on conflict |
Example output
json
{ "id": "545486381788", "properties": { "email": "jane@example.com", "firstname": "Jane" }, "createdAt": "…", "updatedAt": "…" }Documentation of API endpoint that powers action: HubSpot API – Batch upsert contacts (POST /crm/v3/objects/contacts/batch/upsert)
Get Contact
Retrieve one contact by record ID (404 if archived or missing).
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Contact ID | 545486381788 | ID of the contact to retrieve. | Required |
Properties to returnOptional | ["email", "firstname", "lastname"] | Contact properties to include; empty returns HubSpot's small default set only. | Array of property names |
Associations to returnOptional | ["companies", "deals"] | Object types whose associated record IDs are returned with the contact. | Valid: contacts, companies, deals, tickets, meetings, calls, emails, notes, tasks |
Example output
json
{ "id": "545486381788", "properties": { "email": "jane@example.com", "firstname": "Jane", "lastname": "Doe" }, "createdAt": "…", "updatedAt": "…", "archived": false }Documentation of API endpoint that powers action: HubSpot API – Read a contact (GET /crm/v3/objects/contacts/{contactId})
List Contacts
List contacts page by page with no filtering; reflects writes immediately.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
LimitOptional | 50 | Number of results per page (API default 10). | Max 100 |
After (cursor)Optional | NTI1Cg%3D%3D | Pagination cursor — pass paging.next.after from the previous response for the next page. | — |
Properties to returnOptional | ["email", "firstname", "lastname"] | Contact properties to include; empty returns HubSpot's small default set only. | Array of property names |
Associations to returnOptional | ["companies", "deals"] | Object types whose associated record IDs are returned with each contact. | Valid: contacts, companies, deals, tickets, meetings, calls, emails, notes, tasks |
Example output
json
{ "results": [{ "id": "545486381788", "properties": { "email": "jane@example.com" } }], "paging": { "next": { "after": "NTI1Cg%3D%3D" } } }Documentation of API endpoint that powers action: HubSpot API – List contacts (GET /crm/v3/objects/contacts)
Search Contacts
Search contacts with a free-text query and/or structured filters. Note: new/updated records are indexed a few seconds after writes.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Search queryOptional | alice | Free-text search across the default searchable contact properties. | Max 3,000 characters |
Filter groupsOptional | [{ "filters": [{ "propertyName": "lastmodifieddate", "operator": "GTE", "value": "1704700800000" }] }] | Structured filters; groups are ORed, filters inside a group are ANDed. Recently modified: lastmodifieddate GTE ms-epoch. | Max 5 groups × 6 filters. Operators: EQ, NEQ, LT, LTE, GT, GTE, BETWEEN, IN, NOT_IN, HAS_PROPERTY, NOT_HAS_PROPERTY, CONTAINS_TOKEN, NOT_CONTAINS_TOKEN. Dates as ms-epoch strings |
SortOptional | [{ "propertyName": "createdate", "direction": "DESCENDING" }] | Sort order of results. | direction: ASCENDING or DESCENDING |
Properties to returnOptional | ["email", "firstname", "lastname"] | Contact properties to include in each result. | Array of property names |
LimitOptional | 50 | Number of results per page (API default 10). | Max 200 |
After (cursor)Optional | NTI1Cg%3D%3D | Pagination cursor — pass paging.next.after from the previous response. | — |
Example output
json
{ "total": 42, "results": [{ "id": "545486381788", "properties": { "email": "jane@example.com" } }], "paging": { "next": { "after": "NTI1Cg%3D%3D" } } }Documentation of API endpoint that powers action: HubSpot API – Search contacts (POST /crm/v3/objects/contacts/search)
Delete Contact
Archive (delete) a contact by record ID; recoverable from the HubSpot recycle bin for 90 days.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Contact ID | 545486381788 | ID of the contact to delete. | Required |
Example output
json
{ "deleted": true, "id": "545486381788" }Documentation of API endpoint that powers action: HubSpot API – Archive a contact (DELETE /crm/v3/objects/contacts/{contactId})
Create Company
Create a new company in HubSpot; named fields and the Additional properties object merge into one payload (named fields win).
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
NameOptional | Acme Inc. | The company name. | Provide at least name or domain when creating |
DomainOptional | acme.com | The company's primary domain; HubSpot's company deduplication key. | Provide at least name or domain when creating |
CityOptional | Cambridge | The company's city. | — |
State / RegionOptional | Massachusetts | The company's state or region. | — |
CountryOptional | United States | The company's country. | — |
IndustryOptional | COMPUTER_SOFTWARE | The company industry as an internal enumeration value, not free text. | Internal enumeration value |
PhoneOptional | +18884827768 | The company's phone number. | — |
OwnerOptional | 85161889 | HubSpot user (owner) ID for the company. | Owner user ID string |
Additional propertiesOptional | { "numberofemployees": "50", "annualrevenue": "1000000" } | Any other company properties as key-value pairs. Empty string clears a property. | Object; named fields win on conflict |
AssociationsOptional | [{ "to": { "id": "123" }, "types": [{ "associationCategory": "HUBSPOT_DEFINED", "associationTypeId": 1 }] }] | Advanced — link the new company to existing records at creation (raw v3 shape). | Array; associationTypeId is directional |
Example output
json
{ "id": "343713351398", "properties": { "name": "Acme Inc.", "domain": "acme.com" }, "createdAt": "…", "updatedAt": "…", "archived": false }Documentation of API endpoint that powers action: HubSpot API – Create a company (POST /crm/v3/objects/companies)
Update Company
Update an existing company by record ID; only the properties you set change.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Company ID | 343713351398 | ID of the company to update. | Required |
NameOptional | Acme Inc. | The company name. | — |
DomainOptional | acme.com | The company's primary domain; HubSpot's company deduplication key. | — |
CityOptional | Cambridge | The company's city. | — |
State / RegionOptional | Massachusetts | The company's state or region. | — |
CountryOptional | United States | The company's country. | — |
IndustryOptional | COMPUTER_SOFTWARE | The company industry as an internal enumeration value, not free text. | Internal enumeration value |
PhoneOptional | +18884827768 | The company's phone number. | — |
OwnerOptional | 85161889 | HubSpot user (owner) ID for the company. | Owner user ID string |
Additional propertiesOptional | { "numberofemployees": "50", "annualrevenue": "1000000" } | Any other company properties as key-value pairs. Empty string clears a property. | Object; named fields win on conflict |
Example output
json
{ "id": "343713351398", "properties": { "name": "Acme Inc.", "city": "Cambridge" }, "createdAt": "…", "updatedAt": "…", "archived": false }Documentation of API endpoint that powers action: HubSpot API – Update a company (PATCH /crm/v3/objects/companies/{companyId})
Get Company
Retrieve one company by record ID (404 if archived or missing).
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Company ID | 343713351398 | ID of the company to retrieve. | Required |
Properties to returnOptional | ["name", "domain"] | Company properties to include; empty returns HubSpot's small default set only. | Array of property names |
Associations to returnOptional | ["contacts", "deals"] | Object types whose associated record IDs are returned with the company. | Valid: contacts, companies, deals, tickets, meetings, calls, emails, notes, tasks |
Example output
json
{ "id": "343713351398", "properties": { "name": "Acme Inc.", "domain": "acme.com" }, "createdAt": "…", "updatedAt": "…", "archived": false }Documentation of API endpoint that powers action: HubSpot API – Read a company (GET /crm/v3/objects/companies/{companyId})
List Companies
List companies page by page with no filtering; reflects writes immediately.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
LimitOptional | 50 | Number of results per page (API default 10). | Max 100 |
After (cursor)Optional | NTI1Cg%3D%3D | Pagination cursor — pass paging.next.after from the previous response for the next page. | — |
Properties to returnOptional | ["name", "domain"] | Company properties to include; empty returns HubSpot's small default set only. | Array of property names |
Associations to returnOptional | ["contacts", "deals"] | Object types whose associated record IDs are returned with each company. | Valid: contacts, companies, deals, tickets, meetings, calls, emails, notes, tasks |
Example output
json
{ "results": [{ "id": "343713351398", "properties": { "name": "Acme Inc." } }], "paging": { "next": { "after": "NTI1Cg%3D%3D" } } }Documentation of API endpoint that powers action: HubSpot API – List companies (GET /crm/v3/objects/companies)
Search Companies
Search companies with a free-text query and/or structured filters. Note: new/updated records are indexed a few seconds after writes.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Search queryOptional | acme | Free-text search across the default searchable company properties. | Max 3,000 characters |
Filter groupsOptional | [{ "filters": [{ "propertyName": "hs_lastmodifieddate", "operator": "GTE", "value": "1704700800000" }] }] | Structured filters; groups are ORed, filters inside a group are ANDed. Recently modified: hs_lastmodifieddate GTE ms-epoch. | Max 5 groups × 6 filters. Operators: EQ, NEQ, LT, LTE, GT, GTE, BETWEEN, IN, NOT_IN, HAS_PROPERTY, NOT_HAS_PROPERTY, CONTAINS_TOKEN, NOT_CONTAINS_TOKEN. Dates as ms-epoch strings |
SortOptional | [{ "propertyName": "createdate", "direction": "DESCENDING" }] | Sort order of results. | direction: ASCENDING or DESCENDING |
Properties to returnOptional | ["name", "domain"] | Company properties to include in each result. | Array of property names |
LimitOptional | 50 | Number of results per page (API default 10). | Max 200 |
After (cursor)Optional | NTI1Cg%3D%3D | Pagination cursor — pass paging.next.after from the previous response. | — |
Example output
json
{ "total": 12, "results": [{ "id": "343713351398", "properties": { "name": "Acme Inc." } }], "paging": { "next": { "after": "NTI1Cg%3D%3D" } } }Documentation of API endpoint that powers action: HubSpot API – Search companies (POST /crm/v3/objects/companies/search)
Delete Company
Archive (delete) a company by record ID; recoverable from the HubSpot recycle bin for 90 days.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Company ID | 343713351398 | ID of the company to delete. | Required |
Example output
json
{ "deleted": true, "id": "343713351398" }Documentation of API endpoint that powers action: HubSpot API – Archive a company (DELETE /crm/v3/objects/companies/{companyId})
Create Deal
Create a new deal in HubSpot; named fields and the Additional properties object merge into one payload (named fields win).
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Deal name | New Enterprise Deal | Name of the deal. | Required |
Stage | appointmentscheduled | Stage of the deal, as the internal stage ID (not the label). | Required. Internal stage id; options depend on the chosen Pipeline |
PipelineOptional | default | Pipeline the deal belongs to, as the internal pipeline ID (not the label); drives the Stage options. | Internal pipeline id; required when the portal has more than one pipeline |
AmountOptional | 50000 | Deal amount as a numeric string. | Numeric string |
Close dateOptional | 2026-12-31 | Expected close date. | Format YYYY-MM-DD |
OwnerOptional | 85161889 | HubSpot user (owner) ID for the deal. | Owner user ID string |
Additional propertiesOptional | { "dealtype": "newbusiness", "description": "Renewal for 2027" } | Any other deal properties as key-value pairs. Empty string clears a property. | Object; named fields win on conflict |
AssociationsOptional | [{ "to": { "id": "123" }, "types": [{ "associationCategory": "HUBSPOT_DEFINED", "associationTypeId": 1 }] }] | Advanced — link the new deal to existing records at creation (raw v3 shape). | Array; associationTypeId is directional |
Example output
json
{ "id": "345607784143", "properties": { "dealname": "New Enterprise Deal", "dealstage": "appointmentscheduled", "pipeline": "default", "amount": "50000" }, "createdAt": "…", "updatedAt": "…", "archived": false }Documentation of API endpoint that powers action: HubSpot API – Create a deal (POST /crm/v3/objects/deals)
Update Deal
Update an existing deal by record ID; only the properties you set change.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Deal ID | 345607784143 | ID of the deal to update. | Required |
Deal nameOptional | New Enterprise Deal | Name of the deal. | — |
PipelineOptional | default | Pipeline the deal belongs to, as the internal pipeline ID (not the label); drives the Stage options. | Internal pipeline id |
StageOptional | appointmentscheduled | New stage of the deal, as the internal stage ID (not the label). | Internal stage id; options depend on the chosen Pipeline |
AmountOptional | 50000 | Deal amount as a numeric string. | Numeric string |
Close dateOptional | 2026-12-31 | Expected close date. | Format YYYY-MM-DD |
OwnerOptional | 85161889 | HubSpot user (owner) ID for the deal. | Owner user ID string |
Additional propertiesOptional | { "dealtype": "newbusiness", "description": "Renewal for 2027" } | Any other deal properties as key-value pairs. Empty string clears a property. | Object; named fields win on conflict |
Example output
json
{ "id": "345607784143", "properties": { "dealname": "New Enterprise Deal", "amount": "60000" }, "createdAt": "…", "updatedAt": "…", "archived": false }Documentation of API endpoint that powers action: HubSpot API – Update a deal (PATCH /crm/v3/objects/deals/{dealId})
Get Deal
Retrieve one deal by record ID (404 if archived or missing).
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Deal ID | 345607784143 | ID of the deal to retrieve. | Required |
Properties to returnOptional | ["dealname", "dealstage", "amount"] | Deal properties to include; empty returns HubSpot's small default set only. | Array of property names |
Associations to returnOptional | ["contacts", "companies"] | Object types whose associated record IDs are returned with the deal. | Valid: contacts, companies, deals, tickets, meetings, calls, emails, notes, tasks |
Example output
json
{ "id": "345607784143", "properties": { "dealname": "New Enterprise Deal", "dealstage": "appointmentscheduled", "amount": "50000" }, "createdAt": "…", "updatedAt": "…", "archived": false }Documentation of API endpoint that powers action: HubSpot API – Read a deal (GET /crm/v3/objects/deals/{dealId})
List Deals
List deals page by page with no filtering; reflects writes immediately.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
LimitOptional | 50 | Number of results per page (API default 10). | Max 100 |
After (cursor)Optional | NTI1Cg%3D%3D | Pagination cursor — pass paging.next.after from the previous response for the next page. | — |
Properties to returnOptional | ["dealname", "dealstage", "amount"] | Deal properties to include; empty returns HubSpot's small default set only. | Array of property names |
Associations to returnOptional | ["contacts", "companies"] | Object types whose associated record IDs are returned with each deal. | Valid: contacts, companies, deals, tickets, meetings, calls, emails, notes, tasks |
Example output
json
{ "results": [{ "id": "345607784143", "properties": { "dealname": "New Enterprise Deal" } }], "paging": { "next": { "after": "NTI1Cg%3D%3D" } } }Documentation of API endpoint that powers action: HubSpot API – List deals (GET /crm/v3/objects/deals)
Search Deals
Search deals with a free-text query and/or structured filters. Note: new/updated records are indexed a few seconds after writes.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Search queryOptional | enterprise | Free-text search across the default searchable deal properties. | Max 3,000 characters |
Filter groupsOptional | [{ "filters": [{ "propertyName": "hs_lastmodifieddate", "operator": "GTE", "value": "1704700800000" }] }] | Structured filters; groups are ORed, filters inside a group are ANDed. Recently modified: hs_lastmodifieddate GTE ms-epoch. | Max 5 groups × 6 filters. Operators: EQ, NEQ, LT, LTE, GT, GTE, BETWEEN, IN, NOT_IN, HAS_PROPERTY, NOT_HAS_PROPERTY, CONTAINS_TOKEN, NOT_CONTAINS_TOKEN. Dates as ms-epoch strings |
SortOptional | [{ "propertyName": "createdate", "direction": "DESCENDING" }] | Sort order of results. | direction: ASCENDING or DESCENDING |
Properties to returnOptional | ["dealname", "dealstage", "amount"] | Deal properties to include in each result. | Array of property names |
LimitOptional | 50 | Number of results per page (API default 10). | Max 200 |
After (cursor)Optional | NTI1Cg%3D%3D | Pagination cursor — pass paging.next.after from the previous response. | — |
Example output
json
{ "total": 7, "results": [{ "id": "345607784143", "properties": { "dealname": "New Enterprise Deal" } }], "paging": { "next": { "after": "NTI1Cg%3D%3D" } } }Documentation of API endpoint that powers action: HubSpot API – Search deals (POST /crm/v3/objects/deals/search)
Delete Deal
Archive (delete) a deal by record ID; recoverable from the HubSpot recycle bin for 90 days.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Deal ID | 345607784143 | ID of the deal to delete. | Required |
Example output
json
{ "deleted": true, "id": "345607784143" }Documentation of API endpoint that powers action: HubSpot API – Archive a deal (DELETE /crm/v3/objects/deals/{dealId})
Create Ticket
Create a HubSpot ticket from named property fields plus any additional properties, optionally linking it to existing records.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Subject | Customer login issue | Ticket name / subject. | Required |
Stage | 1 | Stage of the ticket. Internal stage id, not the label. | Required / Valid: internal stage ids from the pipeline |
PipelineOptional | 0 | Pipeline the ticket belongs to. Internal pipeline id, not the label. | Required when the portal has more than one pipeline |
PriorityOptional | HIGH | Ticket priority. | Valid: LOW, MEDIUM, HIGH, URGENT (URGENT only on four-tier portals) |
DescriptionOptional | User cannot log in to their account | Ticket description text. | — |
OwnerOptional | 85161889 | HubSpot user (owner) who owns the ticket. | Valid: HubSpot owner id |
Additional propertiesOptional | { "hs_ticket_category": "billing" } | Any other ticket properties as key-value pairs (custom or standard). Named fields win on conflict; all values sent as strings. | — |
AssociationsOptional | [{ "to": { "id": "123" }, "types": [{ "associationCategory": "HUBSPOT_DEFINED", "associationTypeId": 16 }] }] | Link the new ticket to existing records at creation. associationTypeId is directional. Prefer the Create Association action for the common case. | — |
Example output
json
{ "id": "331831822036", "properties": { "subject": "Customer login issue", "hs_pipeline_stage": "1" }, "createdAt": "…", "updatedAt": "…", "archived": false }Documentation of API endpoint that powers action: HubSpot API – Tickets (POST /crm/v3/objects/tickets)
Update Ticket
Update a HubSpot ticket by record ID; only the properties you set are changed.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Ticket ID | 331831822036 | ID of the ticket to update. | Required |
SubjectOptional | Login issue resolved | Ticket name / subject. | — |
StageOptional | 4 | New stage of the ticket. Internal stage id, not the label. | Valid: internal stage ids from the pipeline |
PipelineOptional | 0 | Pipeline the ticket belongs to. Internal pipeline id. | — |
PriorityOptional | LOW | Ticket priority. | Valid: LOW, MEDIUM, HIGH, URGENT |
DescriptionOptional | Resolved by password reset | Ticket description text. | — |
OwnerOptional | 85161889 | HubSpot user (owner) who owns the ticket. | Valid: HubSpot owner id |
Additional propertiesOptional | { "hs_ticket_category": "billing" } | Other ticket properties as key-value pairs. An empty-string value clears that property. All values sent as strings. | — |
Example output
json
{ "id": "331831822036", "properties": { "subject": "Login issue resolved", "hs_pipeline_stage": "4" }, "createdAt": "…", "updatedAt": "…", "archived": false }Documentation of API endpoint that powers action: HubSpot API – Tickets (PATCH /crm/v3/objects/tickets/{ticketId})
Get Ticket
Retrieve one HubSpot ticket by record ID.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Ticket ID | 331831822036 | ID of the ticket to retrieve. | Required / 404 if archived or missing |
Properties to returnOptional | ["subject", "hs_pipeline_stage"] | Ticket property names to include. Empty = HubSpot's default set only. | Valid: ticket property names |
Associations to returnOptional | ["contacts", "companies"] | Object types whose associated record IDs are returned with the ticket. | Valid: contacts, companies, deals, tickets, meetings, calls, emails, notes, tasks |
Example output
json
{ "id": "331831822036", "properties": { "subject": "Customer login issue" }, "createdAt": "…", "updatedAt": "…", "archived": false }Documentation of API endpoint that powers action: HubSpot API – Tickets (GET /crm/v3/objects/tickets/{ticketId})
List Tickets
List HubSpot tickets page by page, without filtering.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
LimitOptional | 50 | Number of results per page. | Max 100 (API default 10) |
After (cursor)Optional | NTI1Cg%3D%3D | Pagination cursor — pass paging.next.after from the previous response. | — |
Properties to returnOptional | ["subject", "hs_ticket_priority"] | Ticket property names to include. Empty = default set only. | Valid: ticket property names |
Associations to returnOptional | ["contacts"] | Object types whose associated record IDs are returned. | Valid: object-type names |
Example output
json
{ "results": [{ "id": "331831822036", "properties": { "subject": "Customer login issue" } }], "paging": { "next": { "after": "NTI1Cg%3D%3D" } } }Documentation of API endpoint that powers action: HubSpot API – Tickets (GET /crm/v3/objects/tickets)
Search Tickets
Search HubSpot tickets with a free-text query and/or structured filters.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Search queryOptional | login | Free-text search across default searchable ticket properties. | Max 3,000 characters |
Filter groupsOptional | [{ "filters": [{ "propertyName": "hs_lastmodifieddate", "operator": "GTE", "value": "1704700800000" }] }] | Structured filters. Groups ORed; filters within a group ANDed. Recently modified: hs_lastmodifieddate GTE ms-epoch. | Max 5 groups × 6 filters. Operators: EQ, NEQ, LT, LTE, GT, GTE, BETWEEN, IN, NOT_IN, HAS_PROPERTY, NOT_HAS_PROPERTY, CONTAINS_TOKEN, NOT_CONTAINS_TOKEN |
SortOptional | [{ "propertyName": "createdate", "direction": "DESCENDING" }] | Sort order of results. | direction: ASCENDING or DESCENDING |
Properties to returnOptional | ["subject", "hs_pipeline_stage"] | Ticket property names to include. Empty = default set only. | Valid: ticket property names |
LimitOptional | 100 | Number of results per page. | Max 200 (API default 10) |
After (cursor)Optional | NTI1Cg%3D%3D | Pagination cursor from the previous response. | — |
Example output
json
{ "total": 3, "results": [{ "id": "331831822036", "properties": { "subject": "Customer login issue" } }], "paging": { "next": { "after": "NTI1Cg%3D%3D" } } }Documentation of API endpoint that powers action: HubSpot API – Tickets Search (POST /crm/v3/objects/tickets/search)
Delete Ticket
Archive (delete) a HubSpot ticket by record ID.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Ticket ID | 331831822036 | ID of the ticket to delete. | Required / recoverable from the HubSpot recycle bin |
Example output
json
{ "deleted": true, "id": "331831822036" }Documentation of API endpoint that powers action: HubSpot API – Tickets (DELETE /crm/v3/objects/tickets/{ticketId})
Create Engagement
Create a HubSpot engagement (meeting, call, email log, note, task, communication or postal mail) and optionally link it to records.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Engagement type | notes | Which engagement object to target. | Required / Valid: meetings, calls, emails, notes, tasks, communications, postal_mail |
Properties | { "hs_timestamp": "2026-09-03T10:00:00Z", "hs_note_body": "Call went well, sending proposal next week" } | Engagement properties as key-value pairs. hs_timestamp is required (ISO 8601 or ms-epoch string; for tasks it is the due date). Property names are type-specific. | Required |
AssociationsOptional | [{ "to": { "id": "545486381788" }, "types": [{ "associationCategory": "HUBSPOT_DEFINED", "associationTypeId": 202 }] }] | Attach the engagement to contacts/companies/deals/tickets. An unassociated engagement is invisible on every record timeline. | — |
Example output
json
{ "id": "396595801835", "properties": { "hs_timestamp": "2026-09-03T10:00:00Z", "hs_note_body": "Call went well, sending proposal next week" }, "createdAt": "…", "updatedAt": "…", "archived": false }Type-specific property names: hs_meeting_title/hs_meeting_body (meetings), hs_call_title/hs_call_body (calls), hs_email_subject/hs_email_text (emails), hs_note_body (notes), hs_task_subject/hs_task_body/hs_task_status (tasks), hs_communication_channel_type/hs_communication_body (communications).
Documentation of API endpoint that powers action: HubSpot API – Engagements / Objects (POST /crm/v3/objects/{engagementType})
Update Engagement
Update a HubSpot engagement by record ID; only the properties you set are changed.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Engagement type | notes | Which engagement object to target. | Required / Valid: meetings, calls, emails, notes, tasks, communications, postal_mail |
Engagement ID | 396595801835 | HubSpot record ID of the engagement. | Required |
Properties | { "hs_note_body": "Updated note body" } | Engagement properties to change (type-specific names). | Required |
Example output
json
{ "id": "396595801835", "properties": { "hs_note_body": "Updated note body" }, "createdAt": "…", "updatedAt": "…" }Documentation of API endpoint that powers action: HubSpot API – Engagements / Objects (PATCH /crm/v3/objects/{engagementType}/{engagementId})
Get Engagement
Retrieve one HubSpot engagement by record ID.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Engagement type | notes | Which engagement object to target. | Required / Valid: meetings, calls, emails, notes, tasks, communications, postal_mail |
Engagement ID | 396595801835 | HubSpot record ID of the engagement. | Required / 404 if archived or missing |
Properties to returnOptional | ["hs_timestamp", "hs_note_body"] | Engagement property names to include. Empty = default set only. Names vary per type. | Valid: engagement property names for the chosen type |
Associations to returnOptional | ["contacts"] | Object types whose associated record IDs are returned. | Valid: object-type names |
Example output
json
{ "id": "396595801835", "properties": { "hs_timestamp": "2026-09-03T10:00:00Z", "hs_note_body": "Call went well" }, "createdAt": "…", "updatedAt": "…", "archived": false }Documentation of API endpoint that powers action: HubSpot API – Engagements / Objects (GET /crm/v3/objects/{engagementType}/{engagementId})
List Engagements
List HubSpot engagements of one type page by page, without filtering.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Engagement type | notes | Which engagement object to list. | Required / Valid: meetings, calls, emails, notes, tasks, communications, postal_mail |
LimitOptional | 50 | Number of results per page. | Max 100 (API default 10) |
After (cursor)Optional | NTI1Cg%3D%3D | Pagination cursor from the previous response. | — |
Properties to returnOptional | ["hs_timestamp", "hs_note_body"] | Engagement property names to include. Empty = default set only. | Valid: engagement property names for the chosen type |
Associations to returnOptional | ["contacts"] | Object types whose associated record IDs are returned. | Valid: object-type names |
Example output
json
{ "results": [{ "id": "396595801835", "properties": { "hs_note_body": "Call went well" } }], "paging": { "next": { "after": "NTI1Cg%3D%3D" } } }Documentation of API endpoint that powers action: HubSpot API – Engagements / Objects (GET /crm/v3/objects/{engagementType})
Search Engagements
Search HubSpot engagements of one type with a free-text query and/or structured filters.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Engagement type | notes | Which engagement object to search. | Required / Valid: meetings, calls, emails, notes, tasks, communications, postal_mail |
Search queryOptional | proposal | Free-text search across default searchable engagement properties. | Max 3,000 characters |
Filter groupsOptional | [{ "filters": [{ "propertyName": "hs_lastmodifieddate", "operator": "GTE", "value": "1704700800000" }] }] | Structured filters. Groups ORed; filters within a group ANDed. Recently created: hs_createdate GTE; recently modified: hs_lastmodifieddate GTE. | Max 5 groups × 6 filters. Operators: EQ, NEQ, LT, LTE, GT, GTE, BETWEEN, IN, NOT_IN, HAS_PROPERTY, NOT_HAS_PROPERTY, CONTAINS_TOKEN, NOT_CONTAINS_TOKEN |
SortOptional | [{ "propertyName": "hs_createdate", "direction": "DESCENDING" }] | Sort order of results. | direction: ASCENDING or DESCENDING |
Properties to returnOptional | ["hs_timestamp", "hs_note_body"] | Engagement property names to include. | Valid: engagement property names for the chosen type |
LimitOptional | 100 | Number of results per page. | Max 200 (API default 10) |
After (cursor)Optional | NTI1Cg%3D%3D | Pagination cursor from the previous response. | — |
Example output
json
{ "total": 2, "results": [{ "id": "396595801835", "properties": { "hs_note_body": "Call went well" } }], "paging": { "next": { "after": "NTI1Cg%3D%3D" } } }Documentation of API endpoint that powers action: HubSpot API – Engagements Search (POST /crm/v3/objects/{engagementType}/search)
Delete Engagement
Archive (delete) a HubSpot engagement by record ID.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Engagement type | notes | Which engagement object to target. | Required / Valid: meetings, calls, emails, notes, tasks, communications, postal_mail |
Engagement ID | 396595801835 | HubSpot record ID of the engagement to delete. | Required |
Example output
json
{ "deleted": true, "id": "396595801835", "type": "notes" }Documentation of API endpoint that powers action: HubSpot API – Engagements / Objects (DELETE /crm/v3/objects/{engagementType}/{engagementId})
Add Contacts to List
Add contact records to a manual or snapshot HubSpot list.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
List | 9 | The contact list to modify. Expects the ILS list id (a numeric string). | Required / MANUAL or SNAPSHOT lists only — DYNAMIC lists reject writes |
Contact record IDs | ["545486381788"] | Contact record IDs to add, as an array of strings. IDs already in the list are silently ignored. | Required |
Example output
json
{ "recordsIdsAdded": ["545486381788"], "recordIdsMissing": [], "recordsIdsAlreadyInList": [] }Documentation of API endpoint that powers action: HubSpot API – Lists (PUT /crm/v3/lists/{listId}/memberships/add)
Remove Contacts from List
Remove contact records from a manual or snapshot HubSpot list.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
List | 9 | The contact list to modify. Expects the ILS list id (a numeric string). | Required / MANUAL or SNAPSHOT lists only — DYNAMIC lists reject writes |
Contact record IDs | ["545486381788"] | Contact record IDs to remove, as an array of strings. IDs not in the list are silently ignored. | Required |
Example output
json
{ "recordIdsRemoved": ["545486381788"], "recordIdsMissing": [] }Documentation of API endpoint that powers action: HubSpot API – Lists (PUT /crm/v3/lists/{listId}/memberships/remove)
Create Association
Link two existing HubSpot records with the default (HubSpot-defined, unlabeled) association for their object-type pair.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
From object type | contacts | Object type of the first record. | Required / Valid: contacts, companies, deals, tickets, meetings, calls, emails, notes, tasks |
From record ID | 545486381788 | Record ID of the first record. | Required |
To object type | companies | Object type of the second record. | Required / Valid: same object-type enum |
To record ID | 343713351398 | Record ID of the second record. | Required |
Uses the default HubSpot association for the pair, so no association type id is needed.
Communications and Postal mail engagements are not in the object-type list here. To link one of those, pass the Associations field when you create the engagement.
Example output
json
{ "status": "COMPLETE", "results": [{ "from": { "id": "545486381788" }, "to": { "id": "343713351398" }, "associationSpec": { "associationCategory": "HUBSPOT_DEFINED", "associationTypeId": 1 } }] }Documentation of API endpoint that powers action: HubSpot API – Associations v4 (PUT /crm/v4/objects/{fromObjectType}/{fromObjectId}/associations/default/{toObjectType}/{toObjectId})
Remove Association
Remove all associations (default and labeled) between two HubSpot records.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
From object type | contacts | Object type of the first record. | Required / Valid: contacts, companies, deals, tickets, meetings, calls, emails, notes, tasks |
From record ID | 545486381788 | Record ID of the first record. | Required |
To object type | companies | Object type of the second record. | Required / Valid: same object-type enum |
To record ID | 343713351398 | Record ID of the second record. | Required |
Removes every association between the two records, both the default and any labeled ones.
Example output
json
{ "deleted": true, "fromObjectType": "contacts", "fromObjectId": "545486381788", "toObjectType": "companies", "toObjectId": "343713351398" }Documentation of API endpoint that powers action: HubSpot API – Associations v4 (DELETE /crm/v4/objects/{fromObjectType}/{fromObjectId}/associations/{toObjectType}/{toObjectId})
List Forms
List the HubSpot marketing forms of the portal.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
LimitOptional | 50 | Number of results per page. | Max 100 (API default 20) |
After (cursor)Optional | NTI1Cg%3D%3D | Pagination cursor from the previous response. | — |
Include archivedOptional | false | Return archived forms instead of active ones. | true = archived, false = active (default) |
Example output
json
{ "results": [{ "id": "c2319d5c-9b66-4e02-a589-148350ae3742", "name": "Contact Us", "formType": "hubspot", "fieldGroups": [] }], "paging": { "next": { "after": "NTI1Cg%3D%3D" } } }Documentation of API endpoint that powers action: HubSpot API – Marketing Forms (GET /marketing/v3/forms)
Get Form Fields
Retrieve one marketing form with its full definition, including every field name, label, type and required flag — call this before Submit Form.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Form | c2319d5c-9b66-4e02-a589-148350ae3742 | The form whose definition to retrieve. Expects a form GUID. | Required |
Example output
json
{ "id": "c2319d5c-9b66-4e02-a589-148350ae3742", "name": "Contact Us", "formType": "hubspot", "fieldGroups": [{ "fields": [{ "name": "email", "label": "Email", "fieldType": "email", "required": true }] }], "configuration": {}, "displayOptions": {} }Documentation of API endpoint that powers action: HubSpot API – Marketing Forms (GET /marketing/v3/forms/{formId})
Submit Form
Submit data to a HubSpot marketing form, creating or updating the contact and firing the form's follow-ups.
Inputs
| Display Key | Example Input | Description | Restrictions |
|---|---|---|---|
Form | c2319d5c-9b66-4e02-a589-148350ae3742 | The form to submit to. Expects a form GUID. | Required |
Fields | [{ "name": "email", "value": "jane@example.com" }, { "name": "firstname", "value": "Jane" }] | Form field values as [{ name, value }]. Each name must match the internal field name from the form definition. Include every required form field. | Required / names must match fieldGroups[].fields[].name (use Get Form Fields) |
ContextOptional | { "pageUri": "https://example.com/contact", "pageName": "Contact Us" } | Tracking context for attribution: { hutk, pageUri, pageName }. hutk is the visitor's hubspotutk cookie value. | — |
Legal consent optionsOptional | { "consent": { "consentToProcess": true, "text": "I agree to allow Example to store and process my data." } } | GDPR consent payload — only needed when the form has legal consent configured. | — |
The portal id is resolved automatically server-side, so it is never entered.
Example output
json
{ "inlineMessage": "Thanks for submitting the form." }or, depending on the form's configured post-submit action:
json
{ "redirectUri": "https://example.com/thank-you" }Documentation of API endpoint that powers action: HubSpot API – Forms Submissions (POST /submissions/v3/integration/submit/{portalId}/{formGuid})
Error handling
| Error code and type | Reason |
|---|---|
| 400 Bad Request | Invalid parameters, for example a label sent where an internal id is required, a malformed property value, or a bad filter. |
| 401 Unauthorized | Missing or invalid access token. |
| 403 Forbidden | The token is missing the scope for this object or operation. Add the scope to the service key. |
| 404 Not Found | The record id does not exist (or has been archived). HubSpot may return an HTML error page rather than JSON for a missing record. |
| 409 Conflict | The record conflicts with an existing one, for example creating a contact with an email that already exists (use Upsert Contact). |
| 429 Too Many Requests | Rate or search limit reached (search allows about 5 requests per second). Retry with backoff. |
FAQs
Which token type does WeWeb use, and where do I create it?
WeWeb uses a HubSpot service key (pat-...), not an API key or an OAuth app. Create it in HubSpot under Development → Keys → Service keys, add the scopes for the objects you use, and paste the key into the connection.
Service keys and private app tokens both start with pat-, so the prefix alone does not tell you which one you are holding. If a key is not working, check where it was created.
Why does a record I just created not show up in Search?
HubSpot's search index updates a few seconds after a write, so a brand-new record is not searchable immediately. Use a List action (which reads live data) right after creating, or add a short retry before searching.
How do I set a deal's pipeline and stage?
Use the internal ids, not the labels. Pick them from the Pipeline and Stage dropdowns on the deal actions, which load the ids from your portal. Passing the visible label returns a 400.
How do I log a call, meeting, or note against a contact?
Use Create Engagement, choose the Type (e.g. calls, meetings, notes, tasks), and set hs_timestamp. Then associate the engagement with the contact (or company) so it appears on the record timeline.
Why is my form submission rejected?
The field names you submit must match the form's definition exactly. Call Get Form Fields first to read the expected field names, then pass matching { name, value } entries to Submit Form.

