I would like to create a workflow that extracts some information from a deal when it is created. I would need the deal name, deal ID and its primary company ID and company name...
when i checked the boards and asked the AI assistant it told me i should connect via the hubspot API in a code action. So i tried...
I created a new PAT and used it in a secret...
then i created a client instance as :
const hsClient = new hubspot.Client({ accessToken: HSAPIKey });
unfortunately i get this error when trying to connect
"The OAuth token used to make this call expired 20384 day(s) ago." if i used the developer Token and used the developerapitoken parameter this also does not work.
Hi @JanMoser78 , nice use case, and good instinct using a code action for this.
The “OAuth token used to make this call expired 20384 day(s) ago” error usually means HubSpot isn’t actually seeing your private app token, but some other string. In workflow custom code you can’t use a developer key or legacy API key, and you also can’t pass the name of the secret as if it were the value.
The pattern is: create a Private App with the right scopes (at least crm.objects.deals.read, crm.objects.companies.read, crm.objects.companies.associations.read), copy the access token, then in the workflow action add it as a secret like HS_PRIVATE_TOKEN. In code you read it as const token = process.env.HS_PRIVATE_TOKEN; and then const hsClient = new hubspot.Client({ accessToken: token }); No OAuth dance is needed inside a workflow, just that static token. (https://developers.hubspot.com/docs/apps/legacy-apps/private-apps/overview )
From there your associations call is on the right track. Using the v4 associations client with fromObjectType: 'deals', toObjectType: 'companies' will give you the primary company ID, and you can fetch the company name with a follow-up crm.companies.basicApi.getById call. If the Node client ever feels behind, you can always hit the REST endpoint directly shown in the CRM associations guide (https://developers.hubspot.com/docs/api-reference/crm-associations-v4/guide )
If the reason you’re pulling deal + primary company into code is to mirror them into another platform or database, Stacksync keeps HubSpot and that external system aligned in near real time so you don’t have to maintain custom sync logic in each workflow.
Did my answer help? Please mark it as a solution to help others find it too.
Ruben Burdin HubSpot Advisor Founder @ Stacksync Real-Time Data Sync between any CRM and Database
The error The OAuth token used to make this call expired 20384 day(s) ago indicates that the token being used isn’t valid for HubSpot’s workflow runtime. In workflow custom code actions, you should always use a Private App Access Token stored as a secret, not a literal token or developer key.
Possible causes • The secret name was passed directly instead of reading it from process.env['SECRET_NAME']. • A developer token or legacy API key was used instead of a private app token. • The Node client or endpoint version doesn’t match the v4 associations API.
How to fix it
Create a Private App with the required scopes: crm.objects.deals.read, crm.objects.companies.read, and association scopes if needed.
Copy the Access Token and add it as a secret (for example, HS_PRIVATE_TOKEN) in your custom code action.
In your code, read it using process.env['HS_PRIVATE_TOKEN'] and send it in the header as Authorization: Bearer <token>.
If your client library doesn’t support the latest endpoints, call the REST APIs directly.
To confirm everything’s working Check the Private App’s logs for any 401 or 403 errors. If you see them, verify that your token and scopes are correct. Always use the environment secret, never the literal token or variable name.