Skip to content

Programmable automation for HubSpot

Workflows that can do the hard part.

HubSpot workflows branch, set properties and send email. Turbyn adds the step that does everything else: your own JavaScript or Python, running for minutes against live CRM data, with any package you need.

Runtime
minutes, not seconds
Languages
JavaScript, Python
Data Hub
not required
enrich-company.jspublished
exports.main = async (event, ctx) => {
  const { domain } = event.inputFields

  // 40s enrichment call. No 20-second ceiling.
  const company = await enrich(domain)

  await ctx.hubspot.companies.update(
    event.object.objectId,
    { industry: company.industry }
  )

  return { outputFields: { output1: company.industry } }
}
finished in 41.2s · 2 properties updated

The ceiling

Where HubSpot workflows run out of room

Minutes, not 20 seconds

The limit is the same on every tier and support cannot raise it. Turbyn pauses the enrollment instead. Your code runs for as long as it needs, and the workflow picks up where it left off.

native
20s
turbyn
15m

Any npm or pip package

The native runtime ships about a dozen and has no install step. Here your imports are the manifest.

import date-fns
import libphonenumber-js
import httpx

Test without writing

HubSpot's test action writes to the real record. It then reports success with empty outputs. Turbyn builds the event from a record you pick and intercepts every write.

would write industry = "Software" → company 4471

Every run is recorded

Payload, console output, timing, stack trace. Replay a single run or every failure from the last day.

successenrich-company41.2s
failedsync-invoice12.4s
runningscore-lead18.0s

Migration

Paste it in. It just runs.

Turbyn uses HubSpot's handler signature verbatim. The same exports.main, the same event object. Existing actions move across without a rewrite.

  • The older (event, callback) style is detected automatically. There is no migration step.
  • Both return and callback() work, so an action can't silently produce empty outputs.
  • ctx is the only addition, and it's optional. Ignore it and your code is unchanged.
Pasted from HubSpot
// Your existing HubSpot action, unchanged.
const hubspot = require('@hubspot/api-client');

exports.main = async (event, callback) => {
  const email = event.inputFields['email'];

  callback({
    outputFields: { normalized: email.trim().toLowerCase() }
  });
};

How it works

From zero to a live workflow step

The whole loop, start to finish. Most people publish their first action in under ten minutes.

  1. 01

    Connect your portal

    Install the app and authorise it. Tokens are encrypted at rest and refreshed server-side. You never handle them.

  2. 02

    Write and test the action

    Write JavaScript or Python in the editor. Pull a real record from your portal to build the event, then dry-run it and read the console before anything is written.

  3. 03

    Publish it

    Publishing snapshots an immutable version and pins its dependency tree. Roll back to any earlier version with one click.

  4. 04

    Place it in a workflow

    Add the Run Code step in HubSpot, pick your saved action from the dropdown, and map inputs from CRM properties or earlier steps.

  5. 05

    It runs, and you can watch it

    Every execution is recorded with its payload, console output and timing. Failures are readable in workflow history and replayable from the run list.

Side by side

Next to the native action

Where the two genuinely differ. Two of these rows go to HubSpot.

Native custom codeTurbyn
Execution time limit20 secondsMinutes
Memory limit128 MBConfigurable per action
Packages~12 built in, no additionsAny npm or pip package
LanguagesJavaScript, PythonJavaScript, Python
TestingWrites to the real recordDry-run against a real record
Run historyWorkflow history lineFull payload, console, timing
ReplayRe-enroll the recordOne-click, single or bulk
Version controlNoneImmutable versions, rollback
SecretsPer-action secretsEncrypted vault, shared across actions
Where the code livesIn the HubSpot editorIn Turbyn, referenced by the step

The native action also requires Data Hub Professional. App-provided actions work on any Professional hub, and the gating is worth understanding properly.

FAQ

Common questions

Do I need Data Hub Professional to use this?

No. Turbyn provides its own workflow action through HubSpot's app platform, and app-provided actions are not gated by Data Hub. You do need the workflow tool itself, which means Professional or Enterprise on some hub.

How is this different from the native custom code action?

The native action stops at 20 seconds and 128 MB. It ships about a dozen packages with no install step, and its test mode writes to the real record. Turbyn has none of those three limits.

Will my existing HubSpot custom code work?

Usually yes, unchanged. Turbyn uses HubSpot's handler signature verbatim, including the same exports.main and event object. Both the modern return style and the older callback style work.

Where does my code actually run?

In an isolated sandbox on Turbyn's infrastructure, one micro-VM per execution. Code from different customers never shares a runtime. Secrets are decrypted at the moment of invocation and injected as environment variables.

What happens to running actions if I disconnect the portal?

In-flight runs are parked rather than lost, and their workflow enrollments stay paused. Reconnect and they resume. HubSpot's pause window is about a week, which is the practical outer bound.

Does it work in the new Agent Hub workflow builder?

Yes. Actions from connected apps appear on HubSpot's new canvas-based builder alongside the native ones. The same saved action works in both the legacy tool and the new one.

Start with one workflow step

Connect a portal, write one action, and put it in a workflow. About ten minutes, and the free tier doesn't ask for a card.