Building Workflows
Workflows are the core of your automation. They connect individual steps together to move data, make decisions, and interact with external systems.
In the @culvii/kit SDK, you build workflows by creating Step instances and connecting them, then wrapping them in a Workflow.
Create your first workflow
Every workflow needs steps. Let's start with a simple manual trigger that passes data to an output step.
import { Step, Workflow } from '@culvii/kit';
// 1. Create the trigger
const trigger = new Step({
name: 'Manual Trigger',
type: 'manualTrigger',
});
// 2. Create an action step
const output = new Step({
name: 'Set Output Data',
type: 'core.set',
params: {
values: {
triggered: true,
source: 'sdk',
},
},
});
// 3. Connect them
trigger.connectTo(output);
// 4. Group them into a workflow
const workflow = new Workflow({
name: 'My First Workflow',
steps: [trigger, output],
});
Step IDs and Names
By default, the SDK generates a unique ID for each step. If you want stable snapshots for testing, you can provide your own id.
The name must be unique within the workflow. Don't put dynamic runtime data in the step name. Use params for that.
const step = new Step({
id: 'enrich-lead-step',
name: 'Enrich Lead',
type: 'core.set',
});
Chaining steps and passing data
When you call source.connectTo(target), you create a connection from the main output of the first step to the main input of the second. Data flows automatically along this path.
trigger.connectTo(enrichLead);
enrichLead.connectTo(notifySales);
Conditional logic and multiple outputs
Some steps have multiple outputs, like an "If" node that routes data based on a condition. You can specify exactly which output connects to which input using connection options.
// Connect the "true" branch (output index 0) to the success step
checkCondition.connectTo(handleSuccess, {
fromPort: 'main',
fromOutputIndex: 0,
toInputIndex: 0,
});
// Connect the "false" branch (output index 1) to the fallback step
checkCondition.connectTo(handleFallback, {
fromPort: 'main',
fromOutputIndex: 1,
toInputIndex: 0,
});
Handling errors
Things break. APIs go down. You can tell the workflow how to handle step failures using the onError property.
const step = new Step({
name: 'Notify Sales',
type: 'http',
onError: 'stopWorkflow', // Stops execution if this step fails
});
Supported error behaviors:
'stopWorkflow': Halts the entire workflow.'continueErrorOutput': Routes the error data to a specific error output branch.'continueRegularOutput': Ignores the error and continues down the main path.
Adding credentials
When a step needs to talk to an authenticated API, pass the credential details directly to the step.
const step = new Step({
name: 'Call CRM',
type: 'http',
credentials: {
name: 'CRM API',
id: 'credential-id',
},
});
Adding steps later
You don't have to define everything upfront. You can create an empty workflow and add steps as you build them.
const workflow = new Workflow({
name: 'Lead Workflow',
});
// Add steps dynamically
workflow.addSteps(trigger, enrichLead, notifySales);
Just remember: if you connect a step, you must add it to the workflow's steps array. If a step connects to a missing step, the workflow will throw an error when validated.