Server workflows are your backend: API endpoints, webhook handlers, scheduled jobs and reactions to data changes. They use the same visual editor and step model as client workflows, but run on Cloudflare’s edge, can use secrets, write to tables and send email.
Triggers
Build one
In the Logic workspace, switch to server workflows and create one. Pick a trigger and add steps. Inside, input, user and steps are in scope. Return ends the run; for endpoints its value is the response body.
{
"name": "Create order",
"runtime": "server",
"trigger": { "type": "http", "method": "POST", "path": "/orders", "auth": "user" },
"input": { "schema": { "items": "array", "couponCode": "string?" } },
"steps": [
{ "id": "order", "action": "core.tableInsert",
"params": { "table": "orders", "values": { "userId": { "$expr": "user.id" }, "items": { "$expr": "input.items" } } } },
{ "id": "mail", "action": "core.sendEmail",
"params": { "to": { "$expr": "user.email" }, "subject": "Order received", "text": "Thanks!" } },
{ "id": "done", "action": "core.return", "params": { "value": { "$expr": "{ orderId: steps.order.id }" } } }
]
}
Once published, the endpoint is live on every domain of the environment:
curl -X POST https://shop.example.com/api/orders \
-H 'content-type: application/json' \
-d '{ "items": [{ "sku": "mug", "qty": 2 }] }'
Endpoint auth
public: anyone can call it. Public endpoints are rate limited.user: only signed-in visitors;useris the caller.apiKey: reserved for server-to-server calls (not available yet).
Call it from a page
Integration steps (OpenAI, Stripe, Resend…) need your secret keys, so they only run in server workflows. To use one from a button or a form:
- Create a server workflow with the trigger Called from pages. Choose who can call it: anyone, or only signed-in visitors.
- Add the integration step. Read what the page sends from
input, then end with Return. - In the client workflow, add Run server workflow and pick it. Its input becomes
input; the returned value lands insteps.<id>.
Run in preview runs the draft as you. Published pages run the published version. A plugin step left in a client workflow shows Move to a server workflow, which does these steps for you.
Test runs and history
Press Test run with a sample input. Steps stream into the run panel live, with each result and duration. Test runs use the draft; published runs use the version that was published, so in-flight runs never see your edits. Every run is kept in the run history with its status: running, waiting, succeeded or failed.
Long-running workflows
Add Sleep (minutes to days) or Wait for event and the workflow becomes durable automatically. Durable runs survive restarts, retry failed steps with backoff and can wait for an approval link or a payment confirmation. Resume a waiting run with Emit event from another workflow. An endpoint that starts a durable run answers with its runId right away.
Server-only steps
- HTTP request: call any HTTPS API; private addresses are blocked, 15 s timeout, 1 MB cap.
- Send email: a transactional email with text or HTML.
- Query, get, insert, update, delete row: work with native tables.
- Set visitor roles: grant or remove roles of a signed-up visitor.
- Run JavaScript: sandboxed code with
inputandstepsin scope, no network, no secrets. - Run operation: call an integration operation with its secrets. To use one from a page, see Call it from a page.
- Run server workflow, Return, Sleep, Wait for event, Emit event.
Each step can set retries (up to 5) with a constant, linear or exponential delay.
Limits
Your site plan sets the runs per month and the steps per run; see Plans. Inline runs give up after 30 seconds. Table events that trigger workflows that write tables stop after three levels, so a workflow cannot loop on itself.