How do you write HubSpot custom code actions with Claude?
Claude writes the first draft in minutes. The test on a record that does not matter is what keeps it off your live data.
Tell Claude the job in one sentence, the properties going in, the values coming out, and HubSpot's limits: 20 seconds to run, 128 MB of memory, up to 50 input properties, and secrets read from environment variables. Ask for the code and a list of every input that could break it. That gets you a working first draft in a few minutes.
Then test it in HubSpot on a record that does not matter. HubSpot's own documentation is clear that when you test a custom code action, the code runs and any changes apply to the record you picked. There is no dry run.
You need Data Hub Professional or Enterprise to use custom code actions. JavaScript runs on Node.js, and Python is in beta.
Our short video on setting up a CRM that keeps its own data current, which is where most custom code actions end up earning their keep.
If you are new to custom code in workflows, start with our explainer on what custom code blocks can do and when a standard action stops being enough. This post is the next step: getting Claude to write the code, and proving it works before it touches 40,000 contacts.
What do you need before you ask Claude anything?
- The right subscription. Data Hub Professional or Enterprise.
- One sentence describing the job. "Format every Australian mobile number on a contact as +61." If you cannot say it in one sentence, it is probably two actions.
- The exact internal names of the properties. Claude cannot see your portal. It will guess
mobile_phonewhen yours ismobilephone, and the code will read nothing without throwing a single error. - A test record. A contact you created for testing, clearly named, that nobody will email.
- A private app token, only if the code calls an API. Scoped to the objects it touches and nothing else, and stored as a secret.
The prompt we start from
Copy this, fill in the brackets, and paste it into Claude:
Write a HubSpot workflow custom code action in JavaScript (Node.js).
Job: [one sentence]
Workflow object: [contact / company / deal / ticket]
Input properties (internal names): [list]
Output fields I want back: [name and type of each]
Secrets available as environment variables: [names, or "none"]
HubSpot limits to respect:
- Must finish within 20 seconds and use under 128 MB of memory.
- Read inputs from event.inputFields.
- Return values with callback({ outputFields: { ... } }).
- Prefer returning output fields over writing to the record through the
API, so a normal workflow action does the update.
Then give me:
1. The code, with a comment on each block.
2. Every input that could break it (empty, wrong format, unexpected type).
3. A test plan: the values I should put on a test record, and what the
output should be for each.
4. Anything in the code that would run twice if HubSpot retries it.
Point 4 matters more than it looks. If the action fails because of a rate limit or a server error, HubSpot retries it for up to three days, starting one minute after the failure. Code that sends an email or creates a record on every run will do it again on every retry.
What does good code look like?
Here is the shape of code that prompt should get you for the mobile number job. It reads one property, returns two outputs, and never touches the API:
exports.main = async (event, callback) => {
const raw = event.inputFields['mobilephone'] || '';
const digits = raw.replace(/\D/g, '');
let formatted = '';
if (digits.length === 10 && digits.startsWith('04')) {
// 0412 345 678 becomes +61412345678
formatted = '+61' + digits.slice(1);
} else if (digits.length === 11 && digits.startsWith('614')) {
// 61412345678 becomes +61412345678
formatted = '+' + digits;
} else if (digits.length === 9 && digits.startsWith('4')) {
// 412345678 becomes +61412345678
formatted = '+61' + digits;
}
callback({
outputFields: {
formatted_mobile: formatted, status: formatted ? 'formatted' : 'unrecognised'
}
});
};
The next step in the workflow is a plain "Edit record" action that copies formatted_mobile into the mobile property, on a branch where status is formatted. Anything unrecognised goes to a list for a person to look at.
Returning outputs and letting a normal action do the write has three benefits. No token is needed. The change shows up in the record history like any other workflow edit. And if the logic is wrong, the damage stops at a branch you can see.
The test checklist
Run each of these on your test record, using the Test button in the action. Check the output and the record every time.
| Test | Put this on the test record | You should see |
|---|---|---|
| Normal value | 0412 345 678 | +61412345678, formatted |
| Already correct | +61412345678 | +61412345678, formatted (same value) |
| Empty | Nothing | unrecognised, no error |
| Landline | (07) 3123 4567 | unrecognised |
| Overseas number | +44 7700 900123 | unrecognised |
| Junk | call me after 5 | unrecognised, no error |
Then check three things in the test result itself:
- Runtime and memory. HubSpot shows both. If a simple action is anywhere near 20 seconds or 128 MB, something is wrong.
- The logs. Nothing personal should be printed there, and no secret should ever appear.
- The record history. Did anything change that you did not expect?
Paste any failure back into Claude with the input that caused it. That loop is where Claude earns its place: it is fast at explaining why undefined broke line 3.
What would you automate if you could write the code?
Most custom code actions start as a workaround somebody does by hand.
Where should you test it?
In order, from safest to closest to real:
- The Test button, on a dedicated test record. Remember it is a real run.
- A standard sandbox, if you have one. Sandboxes come with Enterprise subscriptions. Professional portals test in production, which is why the test record matters.
- A small live list. Turn the workflow on for 20 records you have checked by hand, and read every result.
- New records only, then the backfill. Let it run on new contacts for a week before you enrol the other 40,000.
Before step 4, know how you would reverse it. We wrote about what you can and cannot undo when automation changes records, and the same thinking applies to code you wrote yourself.
What should never go into the code, or into the chat?
Tokens in the code. Secrets exist for a reason. HubSpot passes them to your code as environment variables, and the total length of all secret values is capped at 1,000 characters.
Real customer records in the chat. When a test fails, it is tempting to paste the real contact into Claude to debug it. Make up an example with the same shape instead. If you do share real data, know where it goes when Claude reads it.
Personal information sent overseas without a plan. If your code sends a contact's details to an outside API, that may be a cross-border disclosure under Australian Privacy Principle 8, and APP 11 still requires reasonable steps to protect what you hold. Check where the API's servers are before you add the call, not after.
Claude or Breeze Assistant?
Both work. Since May 2026, Breeze Assistant in HubSpot workflows can write, test and iterate on custom code actions from a plain language description, on Data Hub Professional and Enterprise. It sits inside the editor, which is handy.
We still reach for Claude when the action is part of a bigger build, when we want the list of failure cases written down, or when someone other than the author has to review the code. Whichever writes it, the checklist above is yours to run.
So which of your workflows has a step someone still does by hand, because no standard action quite fits?
Frequently asked questions
Which HubSpot plan do you need for custom code actions? Data Hub Professional or Enterprise. The action supports JavaScript on Node.js, with Python available in beta.
Does testing a custom code action change the record? Yes. HubSpot runs the code for real when you test it, and any changes apply to the record you selected, so test on a dedicated test record.
Can Claude see your HubSpot portal while it writes the code? Not unless you have connected it. Claude writes from what you describe, so give it the exact internal property names and use made-up example values instead of real customer data.
What are the limits on a HubSpot custom code action? It must finish within 20 seconds and use no more than 128 MB of memory. It can take up to 50 input properties, and all secret values together must not exceed 1,000 characters.
Sources
- Custom code actions, HubSpot developer documentation, for subscriptions, limits, secrets, outputs, retries and how testing works.
- May 2026 rollup, HubSpot developer changelog, for Breeze Assistant writing and testing custom code actions.
- Australian Privacy Principles quick reference, OAIC, for APP 8 and APP 11.
Got a workflow that needs a step HubSpot does not have? Talk to us and we will help you build and test it.
Where do you test a custom code action today?
HubSpot's Test button runs it for real, on a real record.