Skip to content
Docs

Trigger Workflows

You can trigger Workflows both programmatically and via the Workflows APIs, including:

  1. With Workers via HTTP requests in a fetch handler, or bindings from a queue or scheduled handler
  2. On a recurring interval by defining schedules on a Workflow binding in your Wrangler configuration
  3. Using the Workflows REST API
  4. Via the wrangler CLI in your terminal

Workers API (Bindings)

You can interact with Workflows programmatically from any Worker script by creating a binding to a Workflow. A Worker can bind to multiple Workflows, including Workflows defined in other Workers projects (scripts) within your account.

You can trigger a Workflow:

  • Directly over HTTP via the fetch handler
  • From a Queue consumer inside a queue handler
  • On a recurring schedule by defining schedules on the Workflow binding in wrangler.jsonc
  • From a Cron Trigger inside a scheduled handler
  • Within a Durable Object

To bind to a Workflow from your Workers code, you need to define a binding to a specific Workflow. For example, to bind to the Workflow defined in the get started guide, you would configure the Wrangler configuration file with the below:

JSONC
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "workflows-tutorial",
"main": "src/index.ts",
// Set this to today's date
"compatibility_date": "2026-06-04",
"workflows": [
{
// The name of the Workflow
"name": "workflows-tutorial",
// The binding name, which must be a valid JavaScript variable name. This will
// be how you call (run) your Workflow from your other Workers handlers or
// scripts.
"binding": "MY_WORKFLOW",
// Must match the class defined in your code that extends the Workflow class
"class_name": "MyWorkflow"
}
]
}

The binding = "MY_WORKFLOW" line defines the JavaScript variable that our Workflow methods are accessible on, including create (which triggers a new instance) or get (which returns the status of an existing instance).

Schedule a Workflow directly

If you want to create Workflow instances on a recurring interval, add a schedules array to the Workflow binding in your Wrangler configuration:

JSONC
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "workflows-tutorial",
"main": "src/index.ts",
// Set this to today's date
"compatibility_date": "2026-06-04",
"workflows": [
{
"name": "workflows-tutorial",
"binding": "MY_WORKFLOW",
"class_name": "MyWorkflow",
"schedules": ["0 * * * *"]
}
]
}

Each matching cron expression creates a new Workflow instance automatically. Use this when you want to run a Workflow on a schedule without defining top-level triggers.crons and a separate scheduled handler.

Scheduled instances include the matching cron expression and scheduled trigger time on event.schedule:

TypeScript
export class MyWorkflow extends WorkflowEntrypoint<Env> {
async run(event: WorkflowEvent<unknown>, step: WorkflowStep) {
if (event.schedule) {
console.log(event.schedule.cron);
console.log(new Date(event.schedule.scheduledTime));
}
}
}

On Workers Paid, Workflow instances created by schedules can run for up to one hour per cron firing without consuming a Workflow concurrency slot. If the instance pauses or sleeps after that window, the instance yields and enters the normal concurrency queue upon resume. It resumes when a concurrency slot is available.

Use the latest Wrangler release when configuring Workflow schedules. If your local Wrangler schema does not recognize schedules yet, update Wrangler before deploying.

The following example shows how you can manage Workflows from within a Worker, including:

  • Retrieving the status of an existing Workflow instance by its ID
  • Creating (triggering) a new Workflow instance
  • Returning the status of a given instance ID
src/index.ts
interface Env {
MY_WORKFLOW: Workflow;
}
export default {
async fetch(req: Request, env: Env) {
// Get instanceId from query parameters
const instanceId = new URL(req.url).searchParams.get("instanceId");
// If an ?instanceId=<id> query parameter is provided, fetch the status
// of an existing Workflow by its ID.
if (instanceId) {
let instance = await env.MY_WORKFLOW.get(instanceId);
return Response.json({
status: await instance.status(),
});
}
// Else, create a new instance of our Workflow, passing in any (optional)
// params and return the ID.
const newId = crypto.randomUUID();
let instance = await env.MY_WORKFLOW.create({ id: newId });
return Response.json({
id: instance.id,
details: await instance.status(),
});
},
};

Inspect a Workflow's status

You can inspect the status of any running Workflow instance by calling status against a specific instance ID. This allows you to programmatically inspect whether an instance is queued (waiting to be scheduled), actively running, paused, or errored.

TypeScript
let instance = await env.MY_WORKFLOW.get("abc-123");
let status = await instance.status(); // Returns an InstanceStatus

The possible values of status are as follows:

TypeScript
status:
| "queued" // means that instance is waiting to be started (see concurrency limits)
| "running"
| "paused"
| "errored"
| "terminated" // user terminated the instance while it was running
| "complete"
| "waiting" // instance is hibernating and waiting for sleep or event to finish
| "waitingForPause" // instance is finishing the current work to pause
| "unknown";
error?: {
name: string,
message: string
};
output?: unknown;

Explicitly pause a Workflow

You can explicitly pause a Workflow instance (and later resume it) by calling pause against a specific instance ID.

TypeScript
let instance = await env.MY_WORKFLOW.get("abc-123");
await instance.pause(); // Returns Promise<void>

Resume a Workflow

You can resume a paused Workflow instance by calling resume against a specific instance ID.

TypeScript
let instance = await env.MY_WORKFLOW.get("abc-123");
await instance.resume(); // Returns Promise<void>

Calling resume on an instance that is not currently paused will have no effect.

Stop a Workflow

You can stop/terminate a Workflow instance by calling terminate against a specific instance ID.

TypeScript
let instance = await env.MY_WORKFLOW.get("abc-123");
await instance.terminate(); // Returns Promise<void>

Once stopped/terminated, the Workflow instance cannot be resumed.

Restart a Workflow

TypeScript
let instance = await env.MY_WORKFLOW.get("abc-123");
await instance.restart(); // Returns Promise<void>

Restarting an instance will immediately cancel any in-progress steps, erase any intermediate state, and treat the Workflow as if it was run for the first time.

To restart an instance from a specific step instead of the beginning, refer to restart in the Workers API reference.

Trigger a Workflow from another Workflow

You can create a new Workflow instance from within a step of another Workflow. The parent Workflow will not block waiting for the child Workflow to complete — it continues execution immediately after the child instance is successfully created.

JavaScript
export class ParentWorkflow extends WorkflowEntrypoint {
async run(event, step) {
// Perform initial work
const result = await step.do("initial processing", async () => {
// ... processing logic
return { fileKey: "output.pdf" };
});
// Trigger a child workflow for additional processing
const childInstance = await step.do("trigger child workflow", async () => {
return await this.env.CHILD_WORKFLOW.create({
id: `child-${event.instanceId}`,
params: { fileKey: result.fileKey },
});
});
// Parent continues immediately - not blocked by child workflow
await step.do("continue with other work", async () => {
console.log(`Started child workflow: ${childInstance.id}`);
// This runs right away, regardless of child workflow status
});
}
}

If the child Workflow fails to start, the step will fail and be retried according to your retry configuration. Once the child instance is successfully created, it runs independently from the parent.

REST API (HTTP)

Refer to the Workflows REST API documentation.

Command line (CLI)

Refer to the CLI quick start to learn more about how to manage and trigger Workflows via the command-line.