Last modified: September 3, 2025
If you have an Operations Hub Professional or Enterprise account, use the Custom code action in workflows to write and execute JavaScript or Python (beta). With custom code actions, you can extend workflow functionality within and outside of HubSpot.
- Custom code actions support JavaScript using the Node.js runtime framework.
- If you’re using Python for your custom code action, the custom code action will use Python runtime framework.
Custom Code Action Examples
To see examples of custom code actions, review HubSpot’s Programmable Automation Use Cases Library. Some examples include, but are not limited to:- Weighted lead rotation with custom weights
- Formatting international phone numbers
- Archiving or deleting contacts
- Deduplicating contacts
- Completing all tasks for a closed deal
Supported libraries
Node.js supported libraries
If you’re using Node.js, the following libraries are available for use within the code action. These libraries can be loaded using the normalrequire() function at the top of your code.
@hubspot/api-client:^10async:^3.2.0aws-sdk:^2.744.0axios:^1.2.0lodash:^4.17.20mongoose:^6.8.0mysql:^2.18.1redis:^4.5.1request:^2.88.2bluebird:^3.7.2random-number-csprng:^1.0.2googleapis:^67.0.0
Please note:The v4 Associations API is supported in Version 9.0.0 or later of the NodeJS HubSpot Client and in Version 8 of the NodeJS HubSpot Client.
Python supported libraries
If you’re using Python, load the following libraries with an import statement at the top of your code. The import statement should be formatted asfrom [libraryname] import [item], such as from redis.client import redis.
requests 2.28.2@hubspot/api-client ^8google-api-python-client 2.74.0mysql-connector-python 8.0.32redis 4.4.2nltk 3.8.1
import, such as import os.
Add a custom code action
To add a custom code action to a workflow:- In your HubSpot account, navigate to Automation > Workflows.
- Click the name of a workflow, or create a new workflow.
- Click the + plus icon to add a workflow action.
- In the left panel, search for and select Custom code.

Set up your custom code action
After adding your custom code action, configure the action:- Language: by default, custom code actions will use Node.js. If you’re in the Python beta and want to build your action with Python, click the Language dropdown menu, then select Python.
- Description: enter a description for your custom workflow action. This description will appear in the corresponding workflow action card.
- Secret: use a secret with your custom code action, such as a private app access token. The app must include the respective scopes of any data that you’re trying to pull from HubSpot, such as
contactsorforms. Learn more about HubSpot private apps.- To use an existing secret, click Add secret. Then, select the checkbox next to the secret that you’d like to add.
- To add a new secret, click Add secret. In the dialog box, enter the Secret name and Secret value. Then, click Save. You can now select this secret in future custom code actions.
- To edit or delete existing secrets, click Manage secrets.
- Properties to include in code: to include properties in your custom code:
- Click the Select a property, then select a property from the data panel. You can use existing properties or previously formatted property values in the workflow.
- After selecting your property, enter a Property name to use in your code. Learn how to reference a property in your custom code.
- To add another property, click Add property. Each property can only be added once and must have a unique Variable ID. You can use up to 50 properties with your custom code.
- To delete a property, click the delete icon.
- Code: enter your JavaScript or Python. To see examples of custom code, review HubSpot’s Programmable Automation Use Cases Library.
- Data outputs: define data outputs that can be used as inputs later in the workflow, for example with an Edit records action:
- Under Data outputs, click Add output.
- Click the Data type dropdown menu, and select a type of data.
- In the Name field, enter a name for the data output.
- To add multiple outputs, click Add output.
Please note:The code field will not display lint errors when using Python.

- The
def main(event):function is called when the code snippet action is executed. - The event argument is an object containing details for the workflow execution.
- The
callback()function is used to pass data back to the workflow. It should be called in theexports.mainfunction. This can only be used with Node.js.
event object will contain the following data:
Secrets
Use secrets in your code to reference information that shouldn’t be widely shared. Typically, a means of authentication, such as a private app access token. You can manage the secrets your function has access to directly in the workflow action definition.- When using multiple secrets within a custom code, the total length of all secret values must not exceed 1000 characters.
- If you’re using a test account, you must use Oauth or a private app token. Developer API keys will not work for test accounts, and will result in the following error: Authentication credentials not found. This API supports OAuth 2.0 authentication…

Add HubSpot properties
To fetch object properties in your custom code action, instead of using HubSpot’s API, you can add these properties directly in the workflow action definition. Add properties and set property names to reference properties in your code. Once added, the property can be referenced in the custom code. You can add up to 50 properties in each custom code action.
Data Outputs
In the function, define output fields to be used later in the workflow. Then, select the data output type (e.g., number, string, boolean, datetime, enum, date phone number) and input the field you want to output. The output fields should be part of a json object formatted accordingly, depending on the language used:
- If your data output type is in string format, the limit for string output values is 65,000 characters. Exceeding this limit will result in an
OUTPUT_VALUES_TOO_LARGEerror. - If you’re using the Edit records action, take note of compatible source and target properties.
- When updating date properties:
- If you’re using an output to update a datetime property, the output will need to be in UNIX millisecond format.
- If you’re using an output to update a date property instead of a datetime, the output will need to be in UNIX millisecond format and the time on the date will need to be set to midnight UTC.
currentDate.setUTCHours(0,0,0,0)

Set a rate limit for your action
Set a rate limit to determine how often the custom code action should execute. The rate limit will also impact all following actions in the workflow after the custom code action.- In the workflow editor, click the custom code action.
- At the bottom, click Configure rate limit to expand the rate limit section.
- Click to toggle the Turn on rate limiting switch on. By default, this setting is turned off.
- Set up your rate limit:
- Action executions: set the maximum number of executions per time period.
- Time frame: set the time frame for your rate limit. You can set this time frame to Seconds, Minutes, or Hours.

Test the action
When adding a custom code action to a workflow, test the action to ensure that your code runs as expected before turning the workflow on. When testing a custom code action, you’ll start by selecting a record to test the code with, then run the code. This test will run only the code in your custom action, not any of the other actions in the workflow. When the code is finished running, you can view the code outputs and the log of your test.Please note:When testing your custom code, the code will run and any changes will apply to the selected test record. It’s recommended to create a dedicated test record if you want to avoid updating your live records.
- In the workflow editor, click the custom code action.
- At the bottom, click Test action to expand the testing section.
- Click the Object dropdown menu, then select a record to test your code with.
- If you’re using previously formatted property values in the workflow, enter a test value for the formatted data.

- To run the code, click Test.
- In the dialog box, confirm that you want to test your code against the selected record by clicking Test.
-
Once your code is done running, the results of your test will appear:
- Status: the success or failure status of your custom code action.
- Data outputs: the values that resulted for your defined data outputs. An alert will display next to any outputs that the code generated which weren’t defined either in the Data outputs section or in the code editor. You’ll need to add those outputs in order to use them later in the workflow.
- Logs: information about the test itself, such as how much memory the action took to execute and the total runtime.
- After testing the action, click Save.

Logging
After setting up your custom code action, and turning on the workflow, to see the output of the logs from your custom code action, learn how to review your workflow’s action logs.Custom code action execution details
Limitations
Custom code actions must:- Finish running within 20 seconds.
- Can only use up to 128 MB of memory.
- Use Oauth or a private app token, if you’re using a test account. Developer API keys will not work for test account.
Retries
You may need to fetch object properties using the HubSpot API or to call other HubSpot API endpoints in your custom code action. Similar to other API calls, you must comply with HubSpot’s API rate limits.- If you’re using Node.js and encounter a rate limiting error but you want HubSpot to retry your call, you’ll need to throw the error in the
catchblock of your custom code action.

- If you’re using Python and encounter a rate limiting error but you want HubSpot to retry your call, you’ll need to raise the error in the
exceptblock of your custom code action.

Please note:If the call fails due to a rate limiting error, or a 429 or 5XX error from axios or @hubspot/api-client, HubSpot will reattempt to execute your action for up to three days, starting one minute after failure. Subsequent failures will be retried at increasing intervals, with a maximum gap of eight hours between tries.
Caveats
If you’re using Node.js for your custom code, take note of the following:- Generating random numbers: if you’re using Math.random to generate random numbers, users may see the same numbers generated across different executions. This is because Math.random is seeded by the current time. Since HubSpot may enroll many objects into a workflow at the same time and clear the state on every execution, different executions end up seeding Math.random in the same way. Instead, you can use of random-number-csprng 1.0.2 library which guarantees cryptographically secure pseudo-random number generation.
- Variable re-use: to save memory, any variables declared outside the
exports.mainfunction may be re-used for future executions of the custom code action. This is useful when connecting to external services like a database, but any logic or information that needs to be unique to each execution of the custom code action should be inside theexports.mainfunction.
- Variable re-use: similar to the above, any variables declared outside the
def mainfunction may be re-used for future executions of the custom code action.- If you’ve declared a variable outside the
def mainfunction but do not plan on altering it, you can reference the variable directly. - If you plan on altering a variable, you can declare the variable within the
def mainfunction with a global keyword before referencing it.
- If you’ve declared a variable outside the
Code samples
Use the code samples below to begin using custom code workflow actions. Alternatively, review HubSpot’s Programmable Automation Use Cases Library.- Python