Introduction to Workflow Functions

Workflow Functions lets you run your own JavaScript or TypeScript code as a step inside Shopify Flow. When your workflow reaches the Run Function action, your code executes in a secure sandbox and its return value is handed back to Flow, so later steps in the same workflow can use it.

Use it whenever Flow's built-in actions cannot do what you need: custom calculations, reshaping data, calling an external API, or an Admin API operation that would otherwise take a dozen Flow steps.

What you can do with it

  • Run code on any Flow trigger. Anything Flow can trigger on (orders, products, customers, discounts, scheduled time, app triggers) can run your function.
  • Read and modify store data. Turn on Needs Shopify data and call the Shopify Admin GraphQL API from your code.
  • Call external APIs. Send data to your ERP, CRM, warehouse, or any HTTPS endpoint.
  • Use secrets safely. Store API keys once and read them in code as secrets.NAME. They are encrypted at rest and masked in run history.
  • Test instantly. Run your function against sample input from the editor, without touching Flow and without using your run quota.
  • See every run. Status, duration, input, output, logs, and errors are kept in run history.

How a run works

  1. Your Flow workflow triggers as usual.
  2. Flow reaches the Run Function action and sends the Input (JSON) you configured on that action.
  3. Workflow Functions loads the function you selected and executes it in an isolated sandbox.
  4. Your return value goes back to Flow as the action output, so the next steps can branch on it or use it.
  5. The run is recorded in History with its logs, timing, and result.

If the function fails or times out, the Flow action reports an error and the workflow stops on that branch. The failure is recorded in history with the error message.

What your code looks like

Every function exports one default async function that receives (input, ctx):

export default async function (input, ctx) {
  ctx.log("running with", input)

  return { ok: true, received: input }
}
  • input is the JSON you pass from the Flow action (or from the Variables tab when testing).
  • ctx.log(...) writes to the run logs.
  • ctx.fetch(url, options) makes outbound HTTP requests.
  • ctx.shopify.graphql(query, variables) calls the Shopify Admin API, when the function has Needs Shopify data enabled.
  • ctx.shop is your store domain.
  • secrets.NAME reads a secret you saved on the Secrets page.

Whatever you return becomes the action output in Flow. Return a plain object or value that can be serialized to JSON.

The sandbox

Your code runs in a fresh, isolated V8 sandbox for every single run. This is what that means in practice:

  • Nothing persists between runs. No global state, no files, no local database. If you need to remember something, write it to Shopify (metafields, tags) or to your own external system.
  • No Node.js APIs. There is no require, process, fs, or raw fetch. Network access goes through ctx.fetch only.
  • Outbound requests are filtered. ctx.fetch blocks internal and private network addresses, follows a limited number of redirects, and caps response size and time.
  • Limits per run. Timeout defaults to 10 seconds (max 30 seconds) and memory defaults to 128 MB (max 512 MB). Both are configurable per function on the Settings tab.
  • Your access token never reaches your code. Shopify Admin calls are proxied server side. The sandbox only holds a short-lived token that is valid for that one run and only for the permissions you granted.

Around the app

Page What it is for
Dashboard Setup guide, usage against your plan, run volume, recent runs
Functions Create, edit, test, and delete functions. Also has Browse templates
Permissions Grant or revoke the store data your functions may read and write
Secrets Encrypted values you read in code as secrets.NAME
History Every run with status, input, output, logs, and errors
Developer API keys plus REST and MCP connection details for external tools and AI agents
Help How it works, pricing, and support

Plans and run limits

Plan Included runs (rolling 30 days)
Free 500
Starter 5,000
Grow 15,000
Unlimited Unlimited

Every plan includes all features and an unlimited number of functions. Plans differ only in how many runs you can make.

Only runs triggered by Flow count against your quota. Test runs from the editor and runs triggered through the Developer API do not consume it, so you can iterate freely.

Next steps

  • How to create a function walks through the editor end to end.
  • Set up the Run Function action in Shopify Flow connects a function to a workflow.
  • Passing variables into your function covers moving Flow data into your code.
  • Creating and using secrets covers API keys and tokens.