Steps

context.call

context.call() performs an HTTP request as a workflow step, supporting longer response times up to 12 hours.

The request is executed by Upstash on your behalf, so your application does not consume compute resources during the request duration.

If the endpoint responds with a non‑success status code (anything outside 200–299), context.call() still returns the response and the workflow continues. This allows you to inspect the response (via the status field) and decide how to handle failure cases in your logic.

If you want requests to retry automatically, you can explicitly pass a retry configuration.

Arguments

urlbodystring

The URL of the HTTP endpoint to call.

methodbodystring

TThe HTTP method to use (GET, POST, PUT, etc.). Defaults to GET.

bodybodystring

The request body as a string.

headersbodyobject

A map of headers to include in the request.

retriesbody

Number of retry attempts if the request fails. Defaults to 0 (no retries).

retryDelaybody

Delay between retries (in milliseconds). By default, uses exponential backoff. You can use mathematical expressions and the special variable retried (current retry attempt count starting from 0). Examples: 1000, pow(2, retried), max(10, pow(2, retried)).

flowControlbodyobject

Throttle outbound requests.

See Flow Control for details.

timeoutbodynumber

Maximum time (in seconds) to wait for a response. If retries are enabled, this timeout applies individually to each attempt.

workflowbody

When using serveMany, you can call another workflow defined in the same serveMany by passing it to this parameter.

Response

statusnumber

The HTTP response status code.

bodystring

The response body.

context.call() attempts to parse the body as JSON. If parsing fails, the raw body string is returned.

headersdictionary

The response headers.

In TypeScript, you can declare the expected result type for strong typing:

type ResultType = {  field1: string,  field2: number};const result = await context.call<ResultType>( ... );

Usage

TypeScript
import { serve } from "@upstash/workflow/nextjs";export const { POST } = serve<{ topic: string }>(async (context) => {  const { userId, name } = context.requestPayload;  const { status,  headers,  body } = await context.call("sync-user-data", {      url: "https://my-third-party-app", // Endpoint URL      method: "POST",      body: JSON.stringify({        userId,        name      }),      headers: {        authorization: `Bearer ${process.env.OPENAI_API_KEY}`,      },    }  );});
Python
from fastapi import FastAPIfrom upstash_workflow.fastapi import Servefrom upstash_workflow import AsyncWorkflowContextapp = FastAPI()serve = Serve(app)@dataclassclass Request:    topic: str@serve.post("/api/example")async def example(context: AsyncWorkflowContext[Request]) -> None:    request: Request = context.request_payload    result = await context.call(        "generate-long-essay",        url="https://api.openai.com/v1/chat/completions",        method="POST",        body={            "model": "gpt-4o",            "messages": [                {                    "role": "system",                    "content": "You are a helpful assistant writing really long essays that would cause a normal serverless function to timeout.",                },                {"role": "user", "content": request["topic"]},            ],        },        headers={            "authorization": f"Bearer {os.environ['OPENAI_API_KEY']}",        },    )    status, headers, body = result.status, result.headers, result.body

We provide integrations for OpenAI, Anthropic, and Resend, allowing you to call their APIs with strongly typed request bodies using context.call. See context.api for details.

The context.call() function can make requests to any public API endpoint. However, it cannot:

  • Make requests to localhost (unless you set up a local tunnel, here's how)
  • Make requests to internal Upstash QStash endpoints.
Loading search…