Skip to content

JsWorkflows provides a platform-managed HubSpot OAuth app. You do not need to create a HubSpot app or provide credentials.

ResourceOperationScope
ContactsRead contactscrm.objects.contacts.read
ContactsCreate/update/delete contactscrm.objects.contacts.read, crm.objects.contacts.write
CompaniesRead companiescrm.objects.companies.read
CompaniesCreate/update/delete companiescrm.objects.companies.read, crm.objects.companies.write
DealsRead dealscrm.objects.deals.read
DealsCreate/update/delete dealscrm.objects.deals.read, crm.objects.deals.write
Marketing EmailRead/send marketing emailsmarketing-email
FilesAccess file managerfiles
TicketsRead/manage ticketstickets
AutomationManage workflows & sequencesautomation
  1. Go to OAuth Connections → Add Connection → HubSpot.
  2. Select the resources and operations your workflow needs.
  3. Sign in with your HubSpot account and grant the requested permissions.
  4. Give the connection a handle (e.g., my-hubspot).

Use lowercase letters, numbers, and hyphens only for the handle.

Access tokens are refreshed automatically when they expire.

Example: create a contact from a Shopify order

Section titled “Example: create a contact from a Shopify order”
export class Workflow {
async start(data, _headers, api) {
const { token, error } = await api.getOAuthToken('my-hubspot');
if (error || !token) throw new Error(error || 'Missing HubSpot token');
const customer = data.customer;
const response = await fetch('https://api.hubapi.com/crm/v3/objects/contacts', {
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=utf-8',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
properties: {
email: customer.email,
firstname: customer.first_name,
lastname: customer.last_name,
},
}),
});
if (!response.ok) {
throw new Error(`HubSpot API ${response.status}: ${await response.text()}`);
}
}
}
const { token, error } = await api.getOAuthToken('my-hubspot');
if (error || !token) throw new Error(error || 'Missing HubSpot token');
const response = await fetch('https://api.hubapi.com/crm/v3/objects/deals', {
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=utf-8',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
properties: {
dealname: `Order ${data.name}`,
amount: data.total_price,
pipeline: 'default',
dealstage: 'closedwon',
},
}),
});
if (!response.ok) {
throw new Error(`HubSpot API ${response.status}: ${await response.text()}`);
}

When creating deals, dealstage and pipeline must use HubSpot internal IDs or internal values, not the UI label text.