Skip to content

Updating visuals

If you see any images containing outdated UI, please bear with us.

We are updating all content as quickly as possible to mirror our new UI.

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.

  1. In HubSpot, go to DevelopmentKeysService keys (on some portals, SettingsIntegrationsService Keys) and click Create service key.
  2. Under Scopes, grant the CRM scopes for the records you use, read and write: crm.objects.contacts, crm.objects.companies, crm.objects.deals, plus tickets. Add crm.lists.read and crm.lists.write for list membership, crm.schemas.contacts.read / crm.schemas.companies.read / crm.schemas.deals.read so property and pipeline metadata resolves, crm.objects.owners.read to assign owners, and forms for the form actions.
  3. Copy the access token (pat-...).
  4. In WeWeb, open the Data & API tab, open the Integrations subtab, add HubSpot, create a connection, and paste the token into Access Token. Do this for each environment you use (Editor, Staging, Production).
  5. Test with a simple action such as List Contacts to confirm the token works. If you get a 403, 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 Create and Update, the named fields (e.g. Email, First Name) and the Additional properties object 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 emptying Email does not erase the contact's email. To clear a property, pass it in Additional properties with an empty string ("").
  • Internal ids, not labels. Fields like a deal's Pipeline and Stage, or a contact's Lifecycle 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.

  1. In WeWeb, add a table and choose HubSpot as the source, then select your connection.
  2. Choose the Resource: Contacts, Companies, Deals, Tickets, or Engagements. For Engagements, also choose the engagement Type. You pick both per view and they cannot be bound to data, so one table always points at the object you choose here.
  3. Configure a view: pick the Properties (columns) to return, and optionally Filter groups and Sorts. Set a Limit (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 groups Is 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, an operator, and a value. Operators: EQ, NEQ, LT, LTE, GT, GTE, BETWEEN (uses highValue), IN / NOT_IN (use values), HAS_PROPERTY, NOT_HAS_PROPERTY, CONTAINS_TOKEN, NOT_CONTAINS_TOKEN.
  • Date filters take millisecond epoch strings. The "recently modified" property is lastmodifieddate for contacts and hs_lastmodifieddate for companies, deals, and tickets; "created" is createdate.
  • query Is a free-text search (max 3,000 characters) across default searchable properties, used instead of or alongside filterGroups.

All Actions

Actions are grouped by the HubSpot object they act on. Each action name links to its details below.

Contacts

ActionDescription
Create ContactCreate a new contact in HubSpot; named fields and the Additional properties object merge into one payload (named fields win).
Update ContactUpdate an existing contact by record ID; only the properties you set change.
Upsert ContactCreate-or-update a contact keyed on email: updates the existing contact when the email is known, creates one otherwise.
Get ContactRetrieve one contact by record ID (404 if archived or missing).
List ContactsList contacts page by page with no filtering; reflects writes immediately.
Search ContactsSearch contacts with a free-text query and/or structured filters. Note: new/updated records are indexed a few seconds after writes.
Delete ContactArchive (delete) a contact by record ID; recoverable from the HubSpot recycle bin for 90 days.

Companies

ActionDescription
Create CompanyCreate a new company in HubSpot; named fields and the Additional properties object merge into one payload (named fields win).
Update CompanyUpdate an existing company by record ID; only the properties you set change.
Get CompanyRetrieve one company by record ID (404 if archived or missing).
List CompaniesList companies page by page with no filtering; reflects writes immediately.
Search CompaniesSearch companies with a free-text query and/or structured filters. Note: new/updated records are indexed a few seconds after writes.
Delete CompanyArchive (delete) a company by record ID; recoverable from the HubSpot recycle bin for 90 days.

Deals

ActionDescription
Create DealCreate a new deal in HubSpot; named fields and the Additional properties object merge into one payload (named fields win).
Update DealUpdate an existing deal by record ID; only the properties you set change.
Get DealRetrieve one deal by record ID (404 if archived or missing).
List DealsList deals page by page with no filtering; reflects writes immediately.
Search DealsSearch deals with a free-text query and/or structured filters. Note: new/updated records are indexed a few seconds after writes.
Delete DealArchive (delete) a deal by record ID; recoverable from the HubSpot recycle bin for 90 days.

Tickets

ActionDescription
Create TicketCreate a HubSpot ticket from named property fields plus any additional properties, optionally linking it to existing records.
Update TicketUpdate a HubSpot ticket by record ID; only the properties you set are changed.
Get TicketRetrieve one HubSpot ticket by record ID.
List TicketsList HubSpot tickets page by page, without filtering.
Search TicketsSearch HubSpot tickets with a free-text query and/or structured filters.
Delete TicketArchive (delete) a HubSpot ticket by record ID.

Engagements

ActionDescription
Create EngagementCreate a HubSpot engagement (meeting, call, email log, note, task, communication or postal mail) and optionally link it to records.
Update EngagementUpdate a HubSpot engagement by record ID; only the properties you set are changed.
Get EngagementRetrieve one HubSpot engagement by record ID.
List EngagementsList HubSpot engagements of one type page by page, without filtering.
Search EngagementsSearch HubSpot engagements of one type with a free-text query and/or structured filters.
Delete EngagementArchive (delete) a HubSpot engagement by record ID.

Lists

ActionDescription
Add Contacts to ListAdd contact records to a manual or snapshot HubSpot list.
Remove Contacts from ListRemove contact records from a manual or snapshot HubSpot list.

Associations

ActionDescription
Create AssociationLink two existing HubSpot records with the default (HubSpot-defined, unlabeled) association for their object-type pair.
Remove AssociationRemove all associations (default and labeled) between two HubSpot records.

Forms

ActionDescription
List FormsList the HubSpot marketing forms of the portal.
Get Form FieldsRetrieve one marketing form with its full definition, including every field name, label, type and required flag — call this before Submit Form.
Submit FormSubmit 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 KeyExample InputDescriptionRestrictions
Email
Optional
jane@example.comThe contact's email address; HubSpot's primary deduplication key.All values sent as strings
First name
Optional
JaneThe contact's first name.
Last name
Optional
DoeThe contact's last name.
Phone
Optional
+15551234567The contact's phone number.
Company name
Optional
Acme Inc.The contact's company name as plain text; does not associate a company record.
Lifecycle stage
Optional
leadLifecycle stage of the contact. Only moves forward; clear it first to move back.Valid: subscriber, lead, marketingqualifiedlead, salesqualifiedlead, opportunity, customer, evangelist, other
Owner
Optional
85161889HubSpot user (owner) ID for the contact.Owner user ID string
Additional properties
Optional
{ "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
Associations
Optional
[{ "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 KeyExample InputDescriptionRestrictions
Contact ID545486381788ID of the contact to update.Required
Email
Optional
jane@example.comThe contact's email address.All values sent as strings
First name
Optional
JaneThe contact's first name.
Last name
Optional
DoeThe contact's last name.
Phone
Optional
+15551234567The contact's phone number.
Company name
Optional
Acme Inc.The contact's company name as plain text; does not associate a company record.
Lifecycle stage
Optional
leadLifecycle stage of the contact. Only moves forward; clear it first to move back.Valid: subscriber, lead, marketingqualifiedlead, salesqualifiedlead, opportunity, customer, evangelist, other
Owner
Optional
85161889HubSpot user (owner) ID for the contact.Owner user ID string
Additional properties
Optional
{ "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 KeyExample InputDescriptionRestrictions
Emailjane@example.comEmail address used as the upsert key (idProperty: email).Required
First name
Optional
JaneThe contact's first name.
Last name
Optional
DoeThe contact's last name.
Phone
Optional
+15551234567The contact's phone number.
Company name
Optional
Acme Inc.The contact's company name as plain text; does not associate a company record.
Lifecycle stage
Optional
leadLifecycle stage of the contact. Only moves forward; clear it first to move back.Valid: subscriber, lead, marketingqualifiedlead, salesqualifiedlead, opportunity, customer, evangelist, other
Owner
Optional
85161889HubSpot user (owner) ID for the contact.Owner user ID string
Additional properties
Optional
{ "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 KeyExample InputDescriptionRestrictions
Contact ID545486381788ID of the contact to retrieve.Required
Properties to return
Optional
["email", "firstname", "lastname"]Contact properties to include; empty returns HubSpot's small default set only.Array of property names
Associations to return
Optional
["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 KeyExample InputDescriptionRestrictions
Limit
Optional
50Number of results per page (API default 10).Max 100
After (cursor)
Optional
NTI1Cg%3D%3DPagination cursor — pass paging.next.after from the previous response for the next page.
Properties to return
Optional
["email", "firstname", "lastname"]Contact properties to include; empty returns HubSpot's small default set only.Array of property names
Associations to return
Optional
["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 KeyExample InputDescriptionRestrictions
Search query
Optional
aliceFree-text search across the default searchable contact properties.Max 3,000 characters
Filter groups
Optional
[{ "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
Sort
Optional
[{ "propertyName": "createdate", "direction": "DESCENDING" }]Sort order of results.direction: ASCENDING or DESCENDING
Properties to return
Optional
["email", "firstname", "lastname"]Contact properties to include in each result.Array of property names
Limit
Optional
50Number of results per page (API default 10).Max 200
After (cursor)
Optional
NTI1Cg%3D%3DPagination 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 KeyExample InputDescriptionRestrictions
Contact ID545486381788ID 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 KeyExample InputDescriptionRestrictions
Name
Optional
Acme Inc.The company name.Provide at least name or domain when creating
Domain
Optional
acme.comThe company's primary domain; HubSpot's company deduplication key.Provide at least name or domain when creating
City
Optional
CambridgeThe company's city.
State / Region
Optional
MassachusettsThe company's state or region.
Country
Optional
United StatesThe company's country.
Industry
Optional
COMPUTER_SOFTWAREThe company industry as an internal enumeration value, not free text.Internal enumeration value
Phone
Optional
+18884827768The company's phone number.
Owner
Optional
85161889HubSpot user (owner) ID for the company.Owner user ID string
Additional properties
Optional
{ "numberofemployees": "50", "annualrevenue": "1000000" }Any other company properties as key-value pairs. Empty string clears a property.Object; named fields win on conflict
Associations
Optional
[{ "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 KeyExample InputDescriptionRestrictions
Company ID343713351398ID of the company to update.Required
Name
Optional
Acme Inc.The company name.
Domain
Optional
acme.comThe company's primary domain; HubSpot's company deduplication key.
City
Optional
CambridgeThe company's city.
State / Region
Optional
MassachusettsThe company's state or region.
Country
Optional
United StatesThe company's country.
Industry
Optional
COMPUTER_SOFTWAREThe company industry as an internal enumeration value, not free text.Internal enumeration value
Phone
Optional
+18884827768The company's phone number.
Owner
Optional
85161889HubSpot user (owner) ID for the company.Owner user ID string
Additional properties
Optional
{ "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 KeyExample InputDescriptionRestrictions
Company ID343713351398ID of the company to retrieve.Required
Properties to return
Optional
["name", "domain"]Company properties to include; empty returns HubSpot's small default set only.Array of property names
Associations to return
Optional
["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 KeyExample InputDescriptionRestrictions
Limit
Optional
50Number of results per page (API default 10).Max 100
After (cursor)
Optional
NTI1Cg%3D%3DPagination cursor — pass paging.next.after from the previous response for the next page.
Properties to return
Optional
["name", "domain"]Company properties to include; empty returns HubSpot's small default set only.Array of property names
Associations to return
Optional
["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 KeyExample InputDescriptionRestrictions
Search query
Optional
acmeFree-text search across the default searchable company properties.Max 3,000 characters
Filter groups
Optional
[{ "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
Sort
Optional
[{ "propertyName": "createdate", "direction": "DESCENDING" }]Sort order of results.direction: ASCENDING or DESCENDING
Properties to return
Optional
["name", "domain"]Company properties to include in each result.Array of property names
Limit
Optional
50Number of results per page (API default 10).Max 200
After (cursor)
Optional
NTI1Cg%3D%3DPagination 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 KeyExample InputDescriptionRestrictions
Company ID343713351398ID 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 KeyExample InputDescriptionRestrictions
Deal nameNew Enterprise DealName of the deal.Required
StageappointmentscheduledStage of the deal, as the internal stage ID (not the label).Required. Internal stage id; options depend on the chosen Pipeline
Pipeline
Optional
defaultPipeline 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
Amount
Optional
50000Deal amount as a numeric string.Numeric string
Close date
Optional
2026-12-31Expected close date.Format YYYY-MM-DD
Owner
Optional
85161889HubSpot user (owner) ID for the deal.Owner user ID string
Additional properties
Optional
{ "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
Associations
Optional
[{ "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 KeyExample InputDescriptionRestrictions
Deal ID345607784143ID of the deal to update.Required
Deal name
Optional
New Enterprise DealName of the deal.
Pipeline
Optional
defaultPipeline the deal belongs to, as the internal pipeline ID (not the label); drives the Stage options.Internal pipeline id
Stage
Optional
appointmentscheduledNew stage of the deal, as the internal stage ID (not the label).Internal stage id; options depend on the chosen Pipeline
Amount
Optional
50000Deal amount as a numeric string.Numeric string
Close date
Optional
2026-12-31Expected close date.Format YYYY-MM-DD
Owner
Optional
85161889HubSpot user (owner) ID for the deal.Owner user ID string
Additional properties
Optional
{ "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 KeyExample InputDescriptionRestrictions
Deal ID345607784143ID of the deal to retrieve.Required
Properties to return
Optional
["dealname", "dealstage", "amount"]Deal properties to include; empty returns HubSpot's small default set only.Array of property names
Associations to return
Optional
["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 KeyExample InputDescriptionRestrictions
Limit
Optional
50Number of results per page (API default 10).Max 100
After (cursor)
Optional
NTI1Cg%3D%3DPagination cursor — pass paging.next.after from the previous response for the next page.
Properties to return
Optional
["dealname", "dealstage", "amount"]Deal properties to include; empty returns HubSpot's small default set only.Array of property names
Associations to return
Optional
["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 KeyExample InputDescriptionRestrictions
Search query
Optional
enterpriseFree-text search across the default searchable deal properties.Max 3,000 characters
Filter groups
Optional
[{ "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
Sort
Optional
[{ "propertyName": "createdate", "direction": "DESCENDING" }]Sort order of results.direction: ASCENDING or DESCENDING
Properties to return
Optional
["dealname", "dealstage", "amount"]Deal properties to include in each result.Array of property names
Limit
Optional
50Number of results per page (API default 10).Max 200
After (cursor)
Optional
NTI1Cg%3D%3DPagination 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 KeyExample InputDescriptionRestrictions
Deal ID345607784143ID 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 KeyExample InputDescriptionRestrictions
SubjectCustomer login issueTicket name / subject.Required
Stage1Stage of the ticket. Internal stage id, not the label.Required / Valid: internal stage ids from the pipeline
Pipeline
Optional
0Pipeline the ticket belongs to. Internal pipeline id, not the label.Required when the portal has more than one pipeline
Priority
Optional
HIGHTicket priority.Valid: LOW, MEDIUM, HIGH, URGENT (URGENT only on four-tier portals)
Description
Optional
User cannot log in to their accountTicket description text.
Owner
Optional
85161889HubSpot user (owner) who owns the ticket.Valid: HubSpot owner id
Additional properties
Optional
{ "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.
Associations
Optional
[{ "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 KeyExample InputDescriptionRestrictions
Ticket ID331831822036ID of the ticket to update.Required
Subject
Optional
Login issue resolvedTicket name / subject.
Stage
Optional
4New stage of the ticket. Internal stage id, not the label.Valid: internal stage ids from the pipeline
Pipeline
Optional
0Pipeline the ticket belongs to. Internal pipeline id.
Priority
Optional
LOWTicket priority.Valid: LOW, MEDIUM, HIGH, URGENT
Description
Optional
Resolved by password resetTicket description text.
Owner
Optional
85161889HubSpot user (owner) who owns the ticket.Valid: HubSpot owner id
Additional properties
Optional
{ "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 KeyExample InputDescriptionRestrictions
Ticket ID331831822036ID of the ticket to retrieve.Required / 404 if archived or missing
Properties to return
Optional
["subject", "hs_pipeline_stage"]Ticket property names to include. Empty = HubSpot's default set only.Valid: ticket property names
Associations to return
Optional
["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 KeyExample InputDescriptionRestrictions
Limit
Optional
50Number of results per page.Max 100 (API default 10)
After (cursor)
Optional
NTI1Cg%3D%3DPagination cursor — pass paging.next.after from the previous response.
Properties to return
Optional
["subject", "hs_ticket_priority"]Ticket property names to include. Empty = default set only.Valid: ticket property names
Associations to return
Optional
["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 KeyExample InputDescriptionRestrictions
Search query
Optional
loginFree-text search across default searchable ticket properties.Max 3,000 characters
Filter groups
Optional
[{ "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
Sort
Optional
[{ "propertyName": "createdate", "direction": "DESCENDING" }]Sort order of results.direction: ASCENDING or DESCENDING
Properties to return
Optional
["subject", "hs_pipeline_stage"]Ticket property names to include. Empty = default set only.Valid: ticket property names
Limit
Optional
100Number of results per page.Max 200 (API default 10)
After (cursor)
Optional
NTI1Cg%3D%3DPagination 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 KeyExample InputDescriptionRestrictions
Ticket ID331831822036ID 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 KeyExample InputDescriptionRestrictions
Engagement typenotesWhich 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
Associations
Optional
[{ "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 KeyExample InputDescriptionRestrictions
Engagement typenotesWhich engagement object to target.Required / Valid: meetings, calls, emails, notes, tasks, communications, postal_mail
Engagement ID396595801835HubSpot 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 KeyExample InputDescriptionRestrictions
Engagement typenotesWhich engagement object to target.Required / Valid: meetings, calls, emails, notes, tasks, communications, postal_mail
Engagement ID396595801835HubSpot record ID of the engagement.Required / 404 if archived or missing
Properties to return
Optional
["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 return
Optional
["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 KeyExample InputDescriptionRestrictions
Engagement typenotesWhich engagement object to list.Required / Valid: meetings, calls, emails, notes, tasks, communications, postal_mail
Limit
Optional
50Number of results per page.Max 100 (API default 10)
After (cursor)
Optional
NTI1Cg%3D%3DPagination cursor from the previous response.
Properties to return
Optional
["hs_timestamp", "hs_note_body"]Engagement property names to include. Empty = default set only.Valid: engagement property names for the chosen type
Associations to return
Optional
["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 KeyExample InputDescriptionRestrictions
Engagement typenotesWhich engagement object to search.Required / Valid: meetings, calls, emails, notes, tasks, communications, postal_mail
Search query
Optional
proposalFree-text search across default searchable engagement properties.Max 3,000 characters
Filter groups
Optional
[{ "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
Sort
Optional
[{ "propertyName": "hs_createdate", "direction": "DESCENDING" }]Sort order of results.direction: ASCENDING or DESCENDING
Properties to return
Optional
["hs_timestamp", "hs_note_body"]Engagement property names to include.Valid: engagement property names for the chosen type
Limit
Optional
100Number of results per page.Max 200 (API default 10)
After (cursor)
Optional
NTI1Cg%3D%3DPagination 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 KeyExample InputDescriptionRestrictions
Engagement typenotesWhich engagement object to target.Required / Valid: meetings, calls, emails, notes, tasks, communications, postal_mail
Engagement ID396595801835HubSpot 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 KeyExample InputDescriptionRestrictions
List9The 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 KeyExample InputDescriptionRestrictions
List9The 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 KeyExample InputDescriptionRestrictions
From object typecontactsObject type of the first record.Required / Valid: contacts, companies, deals, tickets, meetings, calls, emails, notes, tasks
From record ID545486381788Record ID of the first record.Required
To object typecompaniesObject type of the second record.Required / Valid: same object-type enum
To record ID343713351398Record 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 KeyExample InputDescriptionRestrictions
From object typecontactsObject type of the first record.Required / Valid: contacts, companies, deals, tickets, meetings, calls, emails, notes, tasks
From record ID545486381788Record ID of the first record.Required
To object typecompaniesObject type of the second record.Required / Valid: same object-type enum
To record ID343713351398Record 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 KeyExample InputDescriptionRestrictions
Limit
Optional
50Number of results per page.Max 100 (API default 20)
After (cursor)
Optional
NTI1Cg%3D%3DPagination cursor from the previous response.
Include archived
Optional
falseReturn 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 KeyExample InputDescriptionRestrictions
Formc2319d5c-9b66-4e02-a589-148350ae3742The 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 KeyExample InputDescriptionRestrictions
Formc2319d5c-9b66-4e02-a589-148350ae3742The 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)
Context
Optional
{ "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 options
Optional
{ "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 typeReason
400 Bad RequestInvalid parameters, for example a label sent where an internal id is required, a malformed property value, or a bad filter.
401 UnauthorizedMissing or invalid access token.
403 ForbiddenThe token is missing the scope for this object or operation. Add the scope to the service key.
404 Not FoundThe record id does not exist (or has been archived). HubSpot may return an HTML error page rather than JSON for a missing record.
409 ConflictThe record conflicts with an existing one, for example creating a contact with an email that already exists (use Upsert Contact).
429 Too Many RequestsRate 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 DevelopmentKeysService 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.