Skip to main content
Real-world workflows often mix LLM-powered steps (parsing documents, analyzing data) with traditional steps (API calls, database writes, payments). Restate lets you chain these together in a single durable pipeline where each step is persisted. If the process crashes after step 2 of 4, recovery skips the completed steps and resumes from step 3. Chain agentic and traditional steps in sequence. Restate records the result of each step. On recovery:
  • Completed steps are replayed instantly from the journal
  • LLM calls are not repeated (saving cost and time)
  • Regular steps (API calls, payments) are not duplicated

Example: insurance claim reimbursement

This workflow processes an insurance claim through four steps: two agentic steps that use an LLM to understand unstructured data, and two traditional steps that call external APIs.
workflow-sequential.ts
const process = async (ctx: Context, {prompt}: {prompt: string}) => {
  const model = wrapLanguageModel({
    model: openai("gpt-5.4"),
    middleware: durableCalls(ctx, { maxRetryAttempts: 3 }),
  });

  // Step 1: Parse the claim document (LLM step)
  const { output } = await generateText({
    model,
    system:
      "Extract the claim amount, currency, category, and description.",
    prompt,
    output: Output.object({schema: ClaimData})
  });

  // Step 2: Analyze the claim (LLM step)
  const { output: valid } = await generateText({
    model,
    system:
      "You are a claims analyst. Assess whether this claim is valid and determine the approved amount.",
    prompt: `Claim: ${JSON.stringify(output)}`,
    output: Output.object({schema: z.object({valid: z.boolean()})}),
  });

  if (!valid) {
    return { analysis: "Claim is invalid", amountUsd: 0, confirmation: false };
  }

  // Step 3: Convert currency (regular step)
  const amountUsd = await ctx.run("Convert currency", async () =>
    convertCurrency(output.amount, output.currency, "USD"),
  );

  // Step 4: Process reimbursement (regular step)
  const confirmation = await ctx.run("Process payment", async () =>
    processPayment(ctx.rand.uuidv4(), amountUsd),
  );

  return { analysis: "Claim is valid", amountUsd, confirmation };
};
Install Restate and launch it:
npm install --global @restatedev/restate-server@latest @restatedev/restate@latest
restate-server
Get the example:
restate example typescript-vercel-ai-tour-of-agents && cd typescript-vercel-ai-tour-of-agents
npm install
Export your OpenAI API key and run the agent:
export OPENAI_API_KEY=sk-...
npx tsx ./src/workflow-sequential.ts
Register the agents with Restate:
restate deployments register http://localhost:9080 --force --yes # dev only: overrides previous registrations
Send a request to the agent:
curl localhost:8080/restate/call/ClaimReimbursement/process --json '{
    "prompt": "Process my hospital bill of 2024-10-01 for 3000USD for a broken leg at General Hospital."
}'
If the process crashes after the LLM analysis but before the payment, Restate recovers both LLM results from the journal and continues with the currency conversion. No LLM calls are repeated, no payments are duplicated.