Documentation Index
Fetch the complete documentation index at: https://openworkflow.dev/llms.txt
Use this file to discover all available pages before exploring further.
OpenWorkflow supports the Standard Schema spec,
which means you can use your preferred validation library to enforce type-safe
contracts on workflow inputs.
If the input doesnβt match the schema, the error is thrown before the workflow
is even enqueued β preventing invalid data from entering your system.
Overview
When you define a workflow, you can provide a schema. OpenWorkflow uses this
schema to:
- Validate inputs at runtime: When you start a run (for example, with
ow.runWorkflow(workflow.spec, input)), the input is validated immediately.
If validation fails, an error is thrown before the workflow is enqueued,
preventing invalid data from entering your system.
- Type Safety: The
input parameter in your workflow function is
automatically typed based on your schema.
Supported Libraries
Any library that implements the Standard Schema specification works out of the
box, including:
And many
more.
Examples
import { defineWorkflow } from "openworkflow";
import { z } from "zod";
const emailSchema = z.object({
to: z.string().email(),
subject: z.string().min(1),
body: z.string(),
});
export const sendEmail = defineWorkflow(
{
name: "send-email",
schema: emailSchema,
},
async ({ input, step }) => {
// `input` is fully typed as { to: string; subject: string; body: string }
await step.run({ name: "send-email" }, async () => {
await emailProvider.send({
to: input.to,
subject: input.subject,
body: input.body,
});
});
return { success: true, recipient: input.to };
},
);
Valibot
import { defineWorkflow } from "openworkflow";
import * as v from "valibot";
const emailSchema = v.object({
to: v.pipe(v.string(), v.email()),
subject: v.pipe(v.string(), v.minLength(1)),
body: v.string(),
});
export const sendEmail = defineWorkflow(
{
name: "send-email",
schema: emailSchema,
},
async ({ input, step }) => {
// `input` is fully typed as { to: string; subject: string; body: string }
await step.run({ name: "send-email" }, async () => {
await emailProvider.send({
to: input.to,
subject: input.subject,
body: input.body,
});
});
return { success: true, recipient: input.to };
},
);
ArkType
import { type } from "arktype";
import { defineWorkflow } from "openworkflow";
const emailSchema = type({
to: "string.email",
subject: "string>0",
body: "string",
});
export const sendEmail = defineWorkflow(
{
name: "send-email",
schema: emailSchema,
},
async ({ input, step }) => {
// `input` is fully typed as { to: string; subject: string; body: string }
await step.run({ name: "send-email" }, async () => {
await emailProvider.send({
to: input.to,
subject: input.subject,
body: input.body,
});
});
return { success: true, recipient: input.to };
},
);
Validation Errors
When validation fails, OpenWorkflow throws a detailed error that includes
information about what went wrong:
import { ow } from "./openworkflow/client";
import { sendEmail } from "./workflows/send-email";
try {
await ow.runWorkflow(sendEmail.spec, {
to: "invalid-email", // Invalid email format
subject: "", // Too short
body: "Hello",
});
} catch (error) {
console.error("Validation failed:", error);
}