Workflow API Overview
Every step method receives three arguments:
async start(data, headers, api) { ... }| Argument | Description |
|---|---|
data | The trigger payload (order object, HTTP body, scheduled context, etc.) |
headers | HTTP headers from the trigger request |
api | The JsWorkflows API object — platform capabilities |
api methods
Section titled “api methods”| Method | Description |
|---|---|
api.scheduleNextStep() | Schedule the next step (or fan-out to multiple steps) |
api.waitForEvent() | Pause a run and resume it when an external event arrives |
api.dedupe() | Prevent duplicate processing within a time window |
api.getOAuthToken() | Get a valid access token for a connected OAuth service |
api.google.getServiceAccountToken() | Get a Google access token using a service account key (cached 58 min) |
api.google.sheet.* | Google Sheets helpers — appendRows, readRows, updateRows, clearRange, and more |
api.csv.* | Import a CSV from a URL, split it into chunks, and process each chunk in a separate step |
api.runStore.* | Store and retrieve values scoped to the current run |
api.log() | Write debug output visible in the test runner and run history |
Global env object
Section titled “Global env object”All secret variables you store via More actions → Manage variables in the workflow editor are available as properties on the global env object:
class Workflow { async start(data, headers, api) { const apiKey = env.MY_API_KEY; // a secret you stored const shop = env.SHOPIFY_STORE; // auto-injected: "mystore.myshopify.com" const ver = env.SHOPIFY_API_VERSION; // auto-injected: e.g. "2024-01" }}Two values are always present regardless of your stored secrets:
| Key | Value |
|---|---|
env.SHOPIFY_STORE | Your store’s myshopify.com domain |
env.SHOPIFY_API_VERSION | The Shopify API version configured for your app |
Making HTTP requests
Section titled “Making HTTP requests”Use the global fetch() to call any URL. For Shopify Admin API requests, the platform automatically injects the X-Shopify-Access-Token header when the URL matches your store domain — no extra configuration needed:
// Shopify GraphQL — token injected automaticallyconst res = await fetch( `https://${env.SHOPIFY_STORE}/admin/api/${env.SHOPIFY_API_VERSION}/graphql.json`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: `query { orders(first: 10) { nodes { id name } } }` }), });const { data } = await res.json();For OAuth-connected services, retrieve the token with api.getOAuthToken() and add it yourself:
const { token } = await api.getOAuthToken('my-slack');const res = await fetch('https://slack.com/api/chat.postMessage', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, }, body: JSON.stringify({ channel: '#orders', text: 'Hello' }),});Lifecycle hooks
Section titled “Lifecycle hooks”Your Workflow class can optionally define two lifecycle hooks that run once when the entire run reaches a terminal state:
class Workflow { async start(data, headers, api) { ... }
// Called when the entire run (all branches) completes successfully async onWorkflowComplete(api) { ... }
// Called when a step throws an uncaught error that terminates the run async onWorkflowError(err, api) { ... }}Inside hooks, api is restricted to: getOAuthToken, google, slack, log, dedupe, and runStore. The methods scheduleNextStep, waitForEvent, and csv are not available.
See Lifecycle Hooks for full behavioral rules and examples.