Skip to main content
Workflows

Automate agent work that outlives a process.

Durable workflows built on Rivet Actors. Steps record their results, wait for people or systems, and resume after crashes and deploys.

run_01JQ6R8T

  1. Issue received

    Recording event input

    Active
  2. Agent edits repository

    Not started

    Pending
  3. Run test suite

    Not started

    Pending
  4. Wait for approval

    Not started

    Pending
  5. Record result

    Not started

    Pending

Workflow is running.

Regular TypeScript, durable progress.

import { actor, setup } from "rivetkit";
import { type WorkflowStepContextOf, workflow } from "rivetkit/workflow";
 
export const invoiceActor = actor({
  state: {
    invoiceId: null as string | null,
    subtotal: 0,
    tax: 0,
    total: 0,
    status: "idle" as "idle" | "complete",
  },
  run: workflow(async (ctx) => {
    const subtotal = await ctx.step("load-subtotal", async (ctx) =>
      loadSubtotal(),
    );
 
    const tax = await ctx.step("calculate-tax", async (ctx) =>
      calculateTax(subtotal),
    );
 
    await ctx.step("save-invoice", async (step) =>
      saveInvoice(step, subtotal, tax),
    );
  }),
  actions: {
    getState: (c) => c.state,
  },
});
 
async function loadSubtotal(): Promise<number> {
  const response = await fetch("https://api.example.com/carts/main");
  if (!response.ok) {
    throw new Error(`load subtotal failed: ${response.status}`);
  }
  const cart = (await response.json()) as { subtotal: number };
  return cart.subtotal;
}
 
async function calculateTax(subtotal: number): Promise<number> {
  const response = await fetch("https://api.example.com/tax/quote", {
    method: "POST",
    headers: {
      "content-type": "application/json",
    },
    body: JSON.stringify({ subtotal }),
  });
  if (!response.ok) {
    throw new Error(`tax quote failed: ${response.status}`);
  }
  const quote = (await response.json()) as { tax: number };
  return quote.tax;
}
 
async function saveInvoice(
  ctx: WorkflowStepContextOf<typeof invoiceActor>,
  subtotal: number,
  tax: number,
): Promise<void> {
  const total = subtotal + tax;
  const response = await fetch("https://api.example.com/invoices", {
    method: "POST",
    headers: {
      "content-type": "application/json",
    },
    body: JSON.stringify({ subtotal, tax, total }),
  });
  if (!response.ok) {
    throw new Error(`save invoice failed: ${response.status}`);
  }
  const invoice = (await response.json()) as { id: string };
  ctx.state.invoiceId = invoice.id;
  ctx.state.subtotal = subtotal;
  ctx.state.tax = tax;
  ctx.state.total = total;
  ctx.state.status = "complete";
}
 
export const registry = setup({ use: { invoiceActor } });

A run per user, session, or agent

Address each workflow by key; every run keeps its own state, queue, and history.

State beside the steps

Steps read and write the run's durable state in-process.

Waiting costs nothing

A run blocked on a queue wait or timer sleeps until the message or deadline arrives.

Progress in realtime

Broadcast step progress to connected clients as it happens.

Wait, branch, and recover.

Pause for approval, fan out, retry. Every step is recorded.

StepWaitApprovedretryStep

Read about queue waits, timers and concurrency, and failure and recovery.

Automate agent work.

The workflow gives an agent a computer and records every step.

Agent’s computer

filesshellnetwork

Every step recorded

Read about agent patterns or view the source.

Evolve running work.

Deploy new code mid-run. Old runs keep their version; new runs take the latest.

deploy v2
Running before the deploy
v1
Started after
v2

Read about versioning.

See the history behind every run.

Open a run in the Rivet dashboard, or inspect it from your AI client with Rivet MCP.

Run Inspector

Trace every step's status, timing, attempts, inputs, outputs, and errors; replay eligible steps after a fix.

Rivet MCP

Ask your AI client to inspect the Actor behind a run and diagnose failures from its workflow history.

Rivet workflow inspector showing a build pipeline run: plan, provision, checkpoint, write, verify, publish, and smoke-test steps with durations, and the publish step's recorded output

Develop locally. Deploy your way.

Local

Install Workflows and run it locally while you build.

Open the quickstart

Rivet Cloud

Deploy Workflows on Rivet Cloud with managed infrastructure and persisted Actor data.

Open the dashboard

Self-Host

Run the open-source Rivet control plane as a Rust binary or container on your infrastructure.

Read self-hosting docs

Frequently asked questions

Ship a workflow that survives its first restart.

Read the documentation or explore the Apache 2.0 source.