Skip to content
The Whenever SDK is open source.Explore the SDK on GitHub
On this page

Workflow steps and context

Define named steps, read the runtime context and handle failures without implying automatic retries.

Steps

A step is an exported const built by defineStep. You call it from the run function, context first.

CallWhat happens
defineStep(name, operation)Names a unit of work. The operation receives the context, then the step's own arguments. An empty name throws.
await readRate(ctx, …args)Runs the operation through the runtime's step boundary, which records the invocation under that name.
step.stepNameThe name the step was declared with, readable on the returned function.

WorkflowContext

The single argument your run function and every step receives.

MemberPurpose
ctx.inputThe typed workflow input: the delivery's body on a webhook or event run. A scheduled run is handed none, so type it void.
ctx.config.NAMENon-sensitive workflow values the owner supplies. The names are fixed at build time from the ones your source spells out.
ctx.secrets.NAMEThe plaintext secrets the owner stored, named the same way. Never log one or return it in output.
ctx.triggerThe trigger that started this run, on every run: its type and key, plus what that type delivers, in the table below.
ctx.log(message, data?)A human-readable annotation in the run timeline. Observational only — it never changes control flow.
ctx.now()Runtime-provided current time, in milliseconds.
ctx.random()Runtime-provided randomness.
ctx.integrationsThe integration ports.
ctx.trigger.typeAlways carriesWhen known
manualkeynothing else
schedulekey, cron, expectedAttimeZone
oncekey, expectedAtnothing else
webhookkey, integration, deliveryIdeventType, signedAt
eventkey, integration, deliveryId, sourceeventType, signedAt, acquisitionKind

Errors

Throwing the right one is how you record whether the failure was worth waiting on. Nothing retries it for you.

ClassMeaning
RetryableError(message, { retryAfterMs?, code?, detail?, operation? })The failure is transient, and retryAfterMs records how long a caller should wait. It does not schedule a retry.
NonRetryableError(message, { code?, detail?, operation? })The failure will not clear on its own. Use it for bad input, bad shapes, and permission failures.
WorkflowErrorThe abstract base both extend, carrying retryable, code, detail and operation.

Neither class causes a retry, and nothing replays a workflow: a failed step ends its run, and a step is a recorded boundary rather than a resume point. So make a step's work safe to repeat, express the waiting and the duplicate check you need in the workflow itself, and never report an outcome the provider did not confirm.

Start with the complete module example, choose workflow triggers, and review runtime limits and responsibilities.

Ready to deploy?