Call Workflows from Pages
Last updated Apr 22, 2026 Use Static Assets
To call Workflows from Pages, you are required to deploy a separate Worker containing your Workflows. We recommend using Static Assets instead, as this allows you to add your Workflows directly to your Static Assets Worker.
If you wish to migrate your Pages project to Static Assets, follow this guide.
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.
Note
You will need to deploy your Workflow as a standalone Workers project first before your Pages Function can call it. If you have not yet deployed a Workflow, refer to the Workflows get started guide.
Use Service Bindings
Service Bindings allow you to call a Worker from another Worker or a Pages Function without needing to expose it directly.
To do this, you will need to:
- Deploy your Workflow in a Worker
- Create a Service Binding to that Worker in your Pages project
- Call the Worker remotely using the binding
For example, if you have a Worker called workflows-starter, you would create a new Service Binding in your Pages project as follows, ensuring that the service name matches the name of the Worker your Workflow is defined in:
{
"services": [
{
"binding": "WORKFLOW_SERVICE",
"service": "workflows-starter"
}
]
}
[[services]]
binding = "WORKFLOW_SERVICE"
service = "workflows-starter"
Your Worker can expose a specific method (or methods) that only other Workers or Pages Functions can call over the Service Binding.
In the following example, we expose a specific createInstance method that accepts our Payload and returns the InstanceStatus from the Workflows API:
index.jsjs
import { WorkerEntrypoint } from "cloudflare:workers";
export default class WorkflowsService extends WorkerEntrypoint {
// Currently, entrypoints without a named handler are not supported
async fetch() {
return new Response(null, { status: 404 });
}
async createInstance(payload) {
let instance = await this.env.MY_WORKFLOW.create({
params: payload,
});
return Response.json({
id: instance.id,
details: await instance.status(),
});
}
}
index.tsts
import { WorkerEntrypoint } from "cloudflare:workers";
interface Env {
MY_WORKFLOW: Workflow;
}
type Payload = {
hello: string;
};
export default class WorkflowsService extends WorkerEntrypoint<Env> {
// Currently, entrypoints without a named handler are not supported
async fetch() {
return new Response(null, { status: 404 });
}
async createInstance(payload: Payload) {
let instance = await this.env.MY_WORKFLOW.create({
params: payload,
});
return Response.json({
id: instance.id,
details: await instance.status(),
});
}
}
Your Pages Function would resemble the following:
functions/request.jsjs
export const onRequest = async (context) => {
// This payload could be anything from within your app or from your frontend
let payload = { hello: "world" };
return context.env.WORKFLOWS_SERVICE.createInstance(payload);
};
functions/request.tsts
interface Env {
WORKFLOW_SERVICE: Service;
}
export const onRequest: PagesFunction<Env> = async (context) => {
// This payload could be anything from within your app or from your frontend
let payload = { hello: "world" };
return context.env.WORKFLOWS_SERVICE.createInstance(payload);
};
To learn more about binding to resources from Pages Functions, including how to bind via the Cloudflare dashboard, refer to the bindings documentation for Pages Functions.
Using fetch
Service Bindings vs. fetch
We recommend using Service Bindings when calling a Worker in your own account.
Service Bindings don't require you to expose a public endpoint from your Worker, don't require you to configure authentication, and allow you to call methods on your Worker directly, avoiding the overhead of managing HTTP requests and responses.
An alternative to setting up a Service Binding is to call the Worker over HTTP by using the Workflows Workers API to create a new Workflow instance for each incoming HTTP call to the Worker:
index.jsjs
// This is in the same file as your Workflow definition
export default {
async fetch(req, env) {
let instance = await env.MY_WORKFLOW.create({
params: payload,
});
return Response.json({
id: instance.id,
details: await instance.status(),
});
},
};
index.tsts
// This is in the same file as your Workflow definition
export default {
async fetch(req: Request, env: Env): Promise<Response> {
let instance = await env.MY_WORKFLOW.create({
params: payload,
});
return Response.json({
id: instance.id,
details: await instance.status(),
});
},
};
Your Pages Function can then make a regular fetch call to the Worker:
functions/request.jsjs
export const onRequest = async (context) => {
// Other code
let payload = { hello: "world" };
const instanceStatus = await fetch("https://YOUR_WORKER.workers.dev/", {
method: "POST",
body: JSON.stringify(payload), // Send a payload for our Worker to pass to the Workflow
});
return Response.json(instanceStatus);
};
functions/request.tsts
export const onRequest: PagesFunction<Env> = async (context) => {
// Other code
let payload = { hello: "world" };
const instanceStatus = await fetch("https://YOUR_WORKER.workers.dev/", {
method: "POST",
body: JSON.stringify(payload), // Send a payload for our Worker to pass to the Workflow
});
return Response.json(instanceStatus);
};
You can also choose to authenticate these requests by passing a shared secret in a header and validating that in your Worker.
Next steps
- Learn more about how to programmatically call and trigger Workflows from the Workers API
- Understand how to send events and parameters when triggering a Workflow
- Review the Rules of Workflows and best practices for writing Workflows
Was this helpful?
YesNo
On this page
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/workflows/build/call-workflows-from-pages/#page","headline":"Call Workflows from Pages","description":"Bind and trigger Cloudflare Workflows from Pages Functions using service bindings or fetch calls.","url":"https://developers.cloudflare.com/workflows/build/call-workflows-from-pages/","inLanguage":"en","image":"https://developers.cloudflare.com/workflows/build/call-workflows-from-pages/og.png?v=35eefabb8939af53","dateModified":"2026-04-22","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}
description: Pass data to Workflows using events and parameters, including request details, database records, and webhook payloads. title: Events and parameters image: https://developers.cloudflare.com/workflows/build/events-and-parameters/og.png?v=30bff0231c8494dc
Documentation Index
Fetch the complete documentation index at: https://developers.cloudflare.com/workflows/llms.txt
Use this file to discover all available pages before exploring further.
Docs