Skip to main content
Use the serve() function to define an endpoint that runs a workflow. It accepts two arguments:
  1. Route Function: an async function that receives the workflow context and defines the workflow steps.
  2. Options: configuration options for the workflow.
import { serve } from "@upstash/workflow/nextjs";

export const { POST } = serve(async (context) => {
  // Route function
}, {
  // Options
});
from fastapi import FastAPI
from upstash_workflow.fastapi import Serve
from upstash_workflow import AsyncWorkflowContext

app = FastAPI()
serve = Serve(app)


@serve.post("/api/example")
async def example(context: AsyncWorkflowContext[str]) -> None:
    async def _step1() -> str:
        # define a piece of business logic as step 1
        return "step 1 result"

    result = await context.run("step-1", _step1)

    async def _step2() -> None:
        # define another piece of business logic as step 2
        pass

    await context.run("step-2", _step2)

Route Function

The route function defines the execution logic of the workflow. It is an async function that receives a context object, which is automatically created and passed by Upstash Workflow. The context object provides:
  • Workflow APIs – functions for defining workflow steps.
  • Workflow Run Properties – request payload, request headers, and other metadata.
For a full list of available APIs and properties, see the Workflow Context documentation.
import { serve } from "@upstash/workflow/nextjs";

export const { POST } = serve(
  async (context) => {
    // 👇 Access context properties
    const { userId } = context.requestPayload;
    // 👇 Define a workflow step
    await context.run("step-1", async () => {})
  }
);
from fastapi import FastAPI
from upstash_workflow.fastapi import Serve
from upstash_workflow import AsyncWorkflowContext

app = FastAPI()
serve = Serve(app)


@serve.post("/api/example")
async def example(context: AsyncWorkflowContext[str]) -> None:
    async def _step1() -> str:
        # define a piece of business logic as step 1
        return "step 1 result"

    result = await context.run("step-1", _step1)

    async def _step2() -> None:
        # define another piece of business logic as step 2
        pass

    await context.run("step-2", _step2)

Options

Options provide additional configuration for workflow runs. Most of them are advanced settings and are not required for typical use cases. See Advanced Options for more details.
import { serve } from "@upstash/workflow/nextjs";

export const { POST } = serve(
    async (context) => { ... },
    // 👇 Workflow options
    {
        failureFunction: async ({ ... }) => {}
    }
);
from fastapi import FastAPI
from upstash_workflow.fastapi import Serve
from upstash_workflow import AsyncWorkflowContext

app = FastAPI()
serve = Serve(app)


@serve.post("/api/example")
async def example(context: AsyncWorkflowContext[str]) -> None:
    async def _step1() -> str:
        # define a piece of business logic as step 1
        return "step 1 result"

    result = await context.run("step-1", _step1)

    async def _step2() -> None:
        # define another piece of business logic as step 2
        pass

    await context.run("step-2", _step2)