Provenance
Dashboard UI

Custom Functions

Create and manage JavaScript functions for subscription lifecycle hooks.

Custom Functions let you write JavaScript functions that execute during notification processing. They're used as lifecycle hooks in subscriptions — filtering, transforming, or validating interaction data before or after delivery.

Custom functions landing

Function categories

Each function belongs to one of three categories:

CategoryBadge colorPurpose
FilterPrimaryReturn true/false to allow or block notification delivery
TransformSecondaryReturn a modified interaction object before delivery
ValidatorAccentReturn true/false to validate interaction data

Function list

Functions are displayed as a card grid. Each card shows:

  • Category badge (color-coded)
  • Function name and description
  • Parameter list as small badges
  • Created date
  • Actions: Edit, Test, Delete (via dropdown menu)

Filtering

Use the filter bar to narrow down functions:

  • Category dropdown — filter by Filter, Transform, or Validator
  • Search — search by name or description

Creating a function

Click Create Function to open the editor modal.

Custom function editor

Basic fields

FieldRequiredDescription
Function NameYesIdentifier (e.g. filter.highValue, transform.enrichPayload)
CategoryYesFilter, Transform, or Validator
DescriptionNoWhat this function does

Parameters

Click Add Parameter to define input parameters your function accepts. Each parameter has:

FieldDescription
NameParameter name (used in the function code)
TypeString, Number, Boolean, Array, or Object
DefaultDefault value if not provided at runtime
RequiredWhether the parameter must be supplied

Parameters are passed to the function when it's invoked by a lifecycle hook. You define the parameter values in the subscription's lifecycle hook configuration.

Code editor

The function body is written in JavaScript using an embedded Monaco editor (the same editor as VS Code) with syntax highlighting and autocomplete.

Available variables inside the function:

  • interaction — the full interaction object
  • config — the subscription configuration
  • context.utils — utility functions

Click Template to insert a starter template for the selected category. Click Validate to check for basic syntax issues.

Filter template

// Return true/false to allow/deny execution
return interaction.amount > threshold;

Transform template

// Return modified interaction object
return {
  ...interaction,
  processedAt: new Date().toISOString(),
  customField: 'value'
};

Validator template

// Return true/false for valid/invalid
return requiredFields.every(field =>
  interaction[field] != null && interaction[field] !== ''
);

Testing a function

Click Test on any function card to open the test modal.

Custom function test

Test inputs

FieldDescription
Sample Interaction DataJSON object simulating an interaction payload. Click Load Sample for example data.
Function ParametersInput fields for each defined parameter, typed according to the parameter definition.

Click Run Test to execute the function server-side in a sandboxed environment. The result shows:

  • Success — green alert with the function's return value
  • Failure — red alert with the error message

Using functions in subscriptions

Custom functions are referenced in subscription lifecycle hooks. When creating or editing a subscription, Step 3 (Lifecycle Hooks) lets you attach functions to different stages of notification processing:

  • Pre-send — runs before the notification is sent (use filters to block, transforms to modify)
  • Post-send — runs after successful delivery
  • On-error — runs when delivery fails

Each hook specifies the function name and parameter values. See Notifications → Creating a subscription for the full workflow.

Security

Custom functions execute in a sandboxed environment on the server. The API performs additional validation beyond what the client-side editor checks:

  • Dangerous patterns are detected and blocked
  • Functions must contain a return statement
  • Code length is limited to 50,000 characters
  • Execution is time-limited to prevent infinite loops