Custom Code Action

Run JavaScript/TypeScript code within your workflow to transform data, make API calls, or perform custom logic.

Overview

The Custom Code action lets you run JavaScript/TypeScript code within your workflow to transform data, make API calls, or perform custom logic.

How It Works

  1. Input: Access all workflow data via inputData
  2. Execute: Your code runs in a secure sandbox
  3. Output: Store results in output for subsequent actions

Input Data

The inputData object contains all data available at this point in your workflow - including data from previous actions, user context, and system variables.

1
2
3
4
5
6
// Access workflow data
const userName = inputData.user_name;
const previousResult = inputData.api_response;

// Use optional chaining for nested data
const city = inputData.address?.city;

Output

Assign values to the output object to pass data to subsequent actions:

1
2
3
4
5
6
output.result = "processed";
output.total = inputData.items.length;
output.summary = {
  success: true,
  count: 42
};

Handling Sensitive Data

When working with sensitive values like API keys, client secrets, or tokens, use the redact() function to prevent them from appearing in execution logs.

1
2
3
4
5
6
7
8
9
10
const clientSecret = redact('client_secret');

const response = await fetch('https://api.example.com/oauth/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: `grant_type=client_credentials&client_id=${inputData.client_id}&client_secret=${clientSecret}`
});

const data = await response.json();
output.access_token = data.access_token;

How it works:

  • redact('field_name') returns the value from inputData just like inputData.field_name
  • The value is automatically scrubbed from execution logs
  • Use this for any sensitive data that shouldn't appear in workflow execution logs
Important

The redact() function only works with top-level fields in inputData. Pass the field name as a string, not the value itself.

1
2
3
4
5
// ✅ Correct
const secret = redact('client_secret');

// ❌ Incorrect - this won't redact anything
const secret = redact(inputData.client_secret);

Runtime & Limits

RuntimeDeno 1.46.1 (not Node.js)
Timeout5 seconds
Memory64 MB
Fetch requests5 per execution
External librariesNone available

Full ES support: async/await, optional chaining, nullish coalescing, etc.

Examples

Basic Transformation

1
2
3
4
5
6
7
8
const items = inputData.raw_items ?? [];

output.processed = items.map(item => ({
  id: item.id,
  name: item.name.toUpperCase()
}));

output.count = items.length;

API Call

1
2
3
4
5
6
7
8
9
10
11
12
13
try {
  const response = await fetch("https://api.example.com/data", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ id: inputData.user_id })
  });

  output.result = await response.json();
  output.success = true;
} catch (error) {
  output.error = error.message;
  output.success = false;
}

Common Gotchas

Important
  • Deno, not Node: Node-specific APIs (like require()) won't work
  • No libraries: lodash, axios, etc. are not available - use native JS
  • 5 fetch limit: Scripts making more than 5 HTTP requests will fail
  • 5 second timeout: Long-running operations will be killed
  • Always use redact() for sensitive data: If your code handles API keys, secrets, or tokens, wrap them with redact('field_name') to prevent them from appearing in execution logs