Skip to documentation
Documentation

Build

Build a workflow

Define typed inputs, reliable steps, and useful run outputs.

Updated Aug 15, 2026

Define the contract

Start with a narrow input schema. Validation happens before the first step runs, which keeps malformed requests out of downstream systems.

import { z } from 'zod';
import { workflow } from '@compaos/sdk';

export default workflow('qualify-lead', {
  input: z.object({ email: z.string().email(), company: z.string() }),
  run: async ({ input, step }) => {
    const profile = await step('enrich-company', () => enrich(input.company));
    return { email: input.email, score: profile.score };
  },
});

Keep steps focused

A step should have one clear external effect or compute one reusable result. Smaller steps improve observability, but splitting pure in-memory operations too finely adds noise.

Return useful results

Run outputs are available to API callers, later workflows, and audit exports. Return identifiers and decisions needed by those consumers—not entire provider responses.

Test locally

Use fixture inputs for expected, edge, and failure cases. Stub remote integrations, but keep the workflow orchestration and validation real.