Workers API
This guide details the Workflows API within Cloudflare Workers, including methods, types, and usage examples.
The WorkflowEntrypoint class is the core element of a Workflow definition. A Workflow must extend this class and define a run method with at least one step call to be considered a valid Workflow.
export class MyWorkflow extends WorkflowEntrypoint<Env, Params> { async run(event: WorkflowEvent<Params>, step: WorkflowStep) { // Steps here }}-
run(event: WorkflowEvent<T>, step: WorkflowStep): Promise<T>event- the event passed to the Workflow, including an optionalpayloadcontaining data (parameters)step- theWorkflowSteptype that provides the step methods for your Workflow
The run method can optionally return data, which is available when querying the instance status via the Workers API, REST API and the Workflows dashboard. This can be useful if your Workflow is computing a result, returning the key to data stored in object storage, or generating some kind of identifier you need to act on.
export class MyWorkflow extends WorkflowEntrypoint<Env, Params> { async run(event: WorkflowEvent<Params>, step: WorkflowStep) { // Steps here let someComputedState = await step.do("my step", async () => {});
// Optional: return state from our run() method return someComputedState; }}The WorkflowEvent type accepts an optional type parameter ↗ that allows you to provide a type for the payload property within the WorkflowEvent.
Refer to the events and parameters documentation for how to handle events within your Workflow code.
Finally, any JS control-flow primitive (if conditions, loops, try-catches, promises, etc) can be used to manage steps inside the run method.
export type WorkflowEvent<T> = { payload: Readonly<T>; timestamp: Date; instanceId: string;};- The
WorkflowEventis the first argument to a Workflow'srunmethod, and includes an optionalpayloadparameter and atimestampproperty.payload- a default type ofanyor typeTif a type parameter is provided.timestamp- aDateobject set to the time the Workflow instance was created (triggered).instanceId- the ID of the associated instance.
Refer to the events and parameters documentation for how to handle events within your Workflow code.
-
step.do(name: string, callback: (): RpcSerializable): Promise<T> -
step.do(name: string, config?: WorkflowStepConfig, callback: (): RpcSerializable): Promise<T>name- the name of the step.config(optional) - an optionalWorkflowStepConfigfor configuring step specific retry behaviour.callback- an asynchronous function that optionally returns serializable state for the Workflow to persist.
-
step.sleep(name: string, duration: WorkflowDuration): Promise<void>name- the name of the step.duration- the duration to sleep until, in either seconds or as aWorkflowDurationcompatible string.- Refer to the documentation on sleeping and retrying to learn more about how Workflows are retried.
-
step.sleepUntil(name: string, timestamp: Date | number): Promise<void>name- the name of the step.timestamp- a JavaScriptDateobject or seconds from the Unix epoch to sleep the Workflow instance until.
-
step.waitForEvent(name: string, options: ): Promise<void>name- the name of the step.options- an object with properties fortype, which determines which event type thiswaitForEventcall will match on when callinginstance.sendEvent, and an optionaltimeoutproperty, which defines how long thewaitForEventcall will block for before throwing a timeout exception. The default timeout is 24 hours.
export class MyWorkflow extends WorkflowEntrypoint { async run(event, step) { // Other steps in your Workflow let event = await step.waitForEvent( "receive invoice paid webhook from Stripe", { type: "stripe-webhook", timeout: "1 hour" }, ); // Rest of your Workflow }}export class MyWorkflow extends WorkflowEntrypoint<Env, Params> { async run(event: WorkflowEvent<Params>, step: WorkflowStep) { // Other steps in your Workflow let event = await step.waitForEvent<IncomingStripeWebhook>( "receive invoice paid webhook from Stripe", { type: "stripe-webhook", timeout: "1 hour" }, ); // Rest of your Workflow }}Review the documentation on events and parameters to learn how to send events to a running Workflow instance.
export type WorkflowStepConfig = { retries?: { limit: number; delay: string | number; backoff?: WorkflowBackoff; }; timeout?: string | number;};- A
WorkflowStepConfigis an optional argument to thedomethod of aWorkflowStepand defines properties that allow you to configure the retry behaviour of that step.
Refer to the documentation on sleeping and retrying to learn more about how Workflows are retried.
throw new NonRetryableError(message: string, name string optional): NonRetryableError- Throws an error that forces the current Workflow instance to fail and not be retried.
- Refer to the documentation on sleeping and retrying to learn more about how Workflows are retried.
Workflows exposes an API directly to your Workers scripts via the bindings concept. Bindings allow you to securely call a Workflow without having to manage API keys or clients.
You can bind to a Workflow by defining a [[workflows]] binding within your Wrangler configuration.
For example, to bind to a Workflow called workflows-starter and to make it available on the MY_WORKFLOW variable to your Worker script, you would configure the following fields within the [[workflows]] binding definition:
{ "name": "workflows-starter", "main": "src/index.ts", "compatibility_date": "2024-10-22", "workflows": [ { "name": "workflows-starter", "binding": "MY_WORKFLOW", "class_name": "MyWorkflow" } ]}#:schema node_modules/wrangler/config-schema.jsonname = "workflows-starter"main = "src/index.ts"compatibility_date = "2024-10-22"
[[workflows]]# name of your workflowname = "workflows-starter"# binding name env.MY_WORKFLOWbinding = "MY_WORKFLOW"# this is class that extends the Workflow class in src/index.tsclass_name = "MyWorkflow"You can bind and trigger Workflows from Pages Functions by deploying a Workers project with your Workflow definition and then invoking that Worker using service bindings or a standard fetch() call.
Visit the documentation on calling Workflows from Pages for examples.
You can also bind to a Workflow that is defined in a different Worker script from the script your Workflow definition is in. To do this, provide the script_name key with the name of the script to the [[workflows]] binding definition in your Wrangler configuration.
For example, if your Workflow is defined in a Worker script named billing-worker, but you are calling it from your web-api-worker script, your Wrangler configuration file would resemble the following:
{ "name": "web-api-worker", "main": "src/index.ts", "compatibility_date": "2024-10-22", "workflows": [ { "name": "billing-workflow", "binding": "MY_WORKFLOW", "class_name": "MyWorkflow", "script_name": "billing-worker" } ]}#:schema node_modules/wrangler/config-schema.jsonname = "web-api-worker"main = "src/index.ts"compatibility_date = "2024-10-22"
[[workflows]]# name of your workflowname = "billing-workflow"# binding name env.MY_WORKFLOWbinding = "MY_WORKFLOW"# this is class that extends the Workflow class in src/index.tsclass_name = "MyWorkflow"# the script name where the Workflow is defined.# required if the Workflow is defined in another script.script_name = "billing-worker"If you're using TypeScript, run wrangler types whenever you modify your Wrangler configuration file. This generates types for the env object based on your bindings, as well as runtime types.
The Workflow type provides methods that allow you to create, inspect the status, and manage running Workflow instances from within a Worker script.
It is part of the generated types produced by wrangler types.
interface Env { // The 'MY_WORKFLOW' variable should match the "binding" value set in the Wrangler config file MY_WORKFLOW: Workflow;}The Workflow type exports the following methods:
Create (trigger) a new instance of the given Workflow.
-
create(options?: WorkflowInstanceCreateOptions): Promise<WorkflowInstance>options- optional properties to pass when creating an instance, including a user-provided ID and payload parameters.
An ID is automatically generated, but a user-provided ID can be specified (up to 64 characters 1). This can be useful when mapping Workflows to users, merchants or other identifiers in your system. You can also provide a JSON object as the params property, allowing you to pass data for the Workflow instance to act on as its WorkflowEvent.
// Create a new Workflow instance with your own ID and pass params to the Workflow instancelet instance = await env.MY_WORKFLOW.create({ id: myIdDefinedFromOtherSystem, params: { hello: "world" },});return Response.json({ id: instance.id, details: await instance.status(),});Returns a WorkflowInstance.
You can also provide a type parameter to the Workflows type when creating (triggering) a Workflow instance using the create method of the Workers API. Note that this does not propagate type information into the Workflow itself, as TypeScript types are a build-time construct. To provide the type of an incoming WorkflowEvent, refer to the TypeScript and type parameters section of the Workflows documentation.
To provide an optional type parameter to the Workflow, pass a type argument with your type when defining your Workflow bindings:
interface User { email: string; createdTimestamp: number;}
interface Env { // Pass our User type as the type parameter to the Workflow definition MY_WORKFLOW: Workflow<User>;}
export default { async fetch(request, env, ctx) { // More likely to come from your database or via the request body! const user: User = { email: user@example.com, createdTimestamp: Date.now() }
let instance = await env.MY_WORKFLOW.create({ // params expects the type User params: user })
return Response.json({ id: instance.id, details: await instance.status(), }); }}Create (trigger) a batch of new instance of the given Workflow, up to 100 instances at a time.
This is useful when you are scheduling multiple instances at once. A call to createBatch is treated the same as a call to create (for a single instance) and allows you to work within the instance creation limit.
-
createBatch(batch: WorkflowInstanceCreateOptions[]): Promise<WorkflowInstance[]>batch- list of Options to pass when creating an instance, including a user-provided ID and payload parameters.
Each element of the batch list is expected to include both id and params properties:
// Create a new batch of 3 Workflow instances, each with its own ID and pass params to the Workflow instancesconst listOfInstances = [ { id: "id-abc123", params: { hello: "world-0" } }, { id: "id-def456", params: { hello: "world-1" } }, { id: "id-ghi789", params: { hello: "world-2" } },];let instances = await env.MY_WORKFLOW.createBatch(listOfInstances);Returns an array of WorkflowInstance.
Get a specific Workflow instance by ID.
-
get(id: string): Promise<WorkflowInstance>id- the ID of the Workflow instance.
Returns a WorkflowInstance. Throws an exception if the instance ID does not exist.
// Fetch an existing Workflow instance by ID:try { let instance = await env.MY_WORKFLOW.get(id); return Response.json({ id: instance.id, details: await instance.status(), });} catch (e: any) { // Handle errors // .get will throw an exception if the ID doesn't exist or is invalid. const msg = `failed to get instance ${id}: ${e.message}`; console.error(msg); return Response.json({ error: msg }, { status: 400 });}Optional properties to pass when creating an instance.
interface WorkflowInstanceCreateOptions { /** * An id for your Workflow instance. Must be unique within the Workflow. */ id?: string; /** * The event payload the Workflow instance is triggered with */ params?: unknown;}Represents a specific instance of a Workflow, and provides methods to manage the instance.
declare abstract class WorkflowInstance { public id: string; /** * Pause the instance. */ public pause(): Promise<void>; /** * Resume the instance. If it is already running, an error will be thrown. */ public resume(): Promise<void>; /** * Terminate the instance. If it is errored, terminated or complete, an error will be thrown. */ public terminate(): Promise<void>; /** * Restart the instance. */ public restart(): Promise<void>; /** * Returns the current status of the instance. */ public status(): Promise<InstanceStatus>;}Return the id of a Workflow.
-
id: string
Return the status of a running Workflow instance.
-
status(): Promise<InstanceStatus>
Pause a running Workflow instance.
-
pause(): Promise<void>
Resume a paused Workflow instance.
-
resume(): Promise<void>
Restart a Workflow instance.
-
restart(): Promise<void>
Terminate a Workflow instance.
-
terminate(): Promise<void>
Send an event to a running Workflow instance.
-
sendEvent(): Promise<void>options- the eventtypeandpayloadto send to the Workflow instance. Thetypemust match thetypein the correspondingwaitForEventcall in your Workflow.
Return void on success; throws an exception if the Workflow is not running or is an errored state.
export default { async fetch(req, env) { const instanceId = new URL(req.url).searchParams.get("instanceId"); const webhookPayload = await req.json();
let instance = await env.MY_WORKFLOW.get(instanceId); // Send our event, with `type` matching the event type defined in // our step.waitForEvent call await instance.sendEvent({ type: "stripe-webhook", payload: webhookPayload, });
return Response.json({ status: await instance.status(), }); },};export default { async fetch(req: Request, env: Env) { const instanceId = new URL(req.url).searchParams.get("instanceId"); const webhookPayload = await req.json<Payload>();
let instance = await env.MY_WORKFLOW.get(instanceId); // Send our event, with `type` matching the event type defined in // our step.waitForEvent call await instance.sendEvent({ type: "stripe-webhook", payload: webhookPayload, });
return Response.json({ status: await instance.status(), }); },};You can call sendEvent multiple times, setting the value of the type property to match the specific waitForEvent calls in your Workflow.
This allows you to wait for multiple events at once, or use Promise.race to wait for multiple events and allow the first event to progress the Workflow.
Details the status of a Workflow instance.
type InstanceStatus = { 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?: string; output?: object;};-
Match pattern:
^[a-zA-Z0-9_][a-zA-Z0-9-_]*$↩
Was this helpful?
- Resources
- API
- New to Cloudflare?
- Directory
- Sponsorships
- Open Source
- Support
- Help Center
- System Status
- Compliance
- GDPR
- Company
- cloudflare.com
- Our team
- Careers
- © 2025 Cloudflare, Inc.
- Privacy Policy
- Terms of Use
- Report Security Issues
- Trademark