Platform
Workflows
Modify workflow function

Modify workflow function

Learn more about the modify workflow function within Knock's notification engine.

A modify workflow function updates properties on the workflow data state as a step in a workflow. Any data set by a modify workflow function is merged into the original trigger data provided on workflow trigger and made available to all subsequent steps in the workflow.

Configuring data properties

#

To configure a modify workflow function, you can add key-value pairs in the step editor or use the code editor to input a JSON object directly. Each key represents a property name that will be set on the workflow data, and each value can be either a static value or a Liquid expression.

Each value field is a Liquid-compatible input. This means you can use Liquid variables and control flow to inject variable data, access Knock-controlled workflow state attributes (e.g., recipient), and dynamically compute values per workflow run.

Here are some example configurations:

KeyValueDescription
full_name{{ data.first_name }} {{ data.last_name }}Combines first and last name into a single property
greetingHelloSets a static greeting value
item_count{{ data.items | size }}Computes the count of items in an array
is_premium{{ recipient.plan | equals: "premium" }}Sets a boolean flag based on recipient data
formatted_date{{ "now" | date: "%B %d, %Y" }}Adds the current date in a specific format

See the Knock template editor reference for detailed information on working with Liquid templates in Knock.

Merging data

#

When a modify workflow function executes, Knock will merge the configured properties into the data you originally passed to the workflow trigger call. Knock uses a shallow-merge strategy where:

  • Data from the modify workflow step overwrites the original workflow run data.
  • Top-level attributes are merged, and nested attributes are completely overwritten.

The merged data result from a modify workflow function step then becomes the global trigger data for all subsequent steps in the workflow run.

The example below illustrates how this could look in practice.

Debugging modify workflow functions

#

You can use the workflow run logs to debug your modify workflow function steps. For each modify workflow function, you can expect to see in the logs:

  • The computed data that was merged into your workflow run state.

See the documentation on debugging workflows for more details about workflow debugging and run logs.

Frequently asked questions

#

Use a modify workflow function when you need to transform, compute, or restructure data that is already available in your workflow run. This is ideal for operations like combining fields, setting defaults, or pre-computing Liquid expressions.

Use a fetch function when you need to retrieve additional data from an external service that isn't available in your trigger data. The fetch function makes an HTTP request to your service and merges the response into your workflow data.

In some cases, you might use both: a fetch function to retrieve additional data, followed by a modify workflow function to transform or restructure the combined data for your templates.

You can set a top-level property to an object value, but you cannot directly set deeply nested properties (e.g., metadata.nested.value). If you need to update a nested property, you'll need to set the entire parent object, which will replace any existing nested data due to the shallow-merge behavior.

If a Liquid expression in your modify workflow function encounters an error (such as referencing a property that doesn't exist), the step will fail and halt your workflow run. You can use Liquid's default filter (e.g., {{ data.optional_field | default: "fallback" }}) to provide fallback values and avoid errors when data may be missing.

Yes. Since each modify workflow function merges its computed data into the workflow's global data state, subsequent steps (including other modify workflow functions) can reference that data using the data namespace. For example, if a previous step set data.full_name, a later step can reference it as {{ data.full_name }}.

New chat