Skip to main content

Automations — Technical Reference

Reference for technically-minded readers. Plain-language guides: start at the overview.

Model

An automation is a directed graph of typed steps rendered on a canvas. The trigger is step 0; every other step declares which step(s) it follows. Two step families:

  • AI stepsagent and router. Each executes one full agent turn (tools, files, reasoning) and is billed in credits. The agent is selected per step; a step can only ever execute an agent the automation's owner has access to.
  • Deterministic stepscondition, filter, switch, tool, database, code, for_each, loop. Pure rule-based execution, never billed. for_each and loop accept only deterministic sub-steps — that constraint is what makes their cost guarantee possible.

Data passes between steps as JSON item lists. Variables ({{trigger.*}}, {{steps.N.output.*}}, {{item.*}}, {{loop.*}}) are resolved against those outputs at execution time; a whole-field expression resolves to the native value (list, object, number), while an expression embedded in text interpolates as a string.

Condition model

Event filters and the condition/filter/switch/loop steps share one condition engine: a combinator (and/or) over typed comparisons — string (equals, contains, starts/ends with, regex, empty checks), number (equality and ordering), boolean, date-time (before/after), list (contains, length), object (exists, empty). Case sensitivity and loose/strict type checking are options. The database step's match rules are separate and simpler: column / operation / value against the selected database's real columns.

Triggers

ModeDelivery
ManualStarted from the UI, by agents, or via Nirvai Connect; optional JSON input, overridable per run
ScheduleCron-based
WebhookA per-automation HTTPS address secured with a private key header
App triggerDeclarative templates per provider: automatic webhook subscription, periodic polling with cursor + dedup semantics, or paste-the-URL registration

Inbound app events pass through a fixed pipeline: signature verification → event match (exact, comma list, *, prefix wildcard) → normalization into items → the event filter. A failure at any stage acknowledges the delivery and drops it silently — providers are never given an error response, and dropped events never create a run or bill anything. Batched deliveries are matched per element.

Execution

The runtime computes waves of steps whose dependencies are satisfied and runs each wave in parallel. Branching steps make their decision binding: the not-taken branch's downstream closure is marked skipped with a reason. A failed step fails the run and skips its downstream closure; independent branches still finish. Loop passes run sequentially (each pass may depend on the previous); for-each iterations run with bounded concurrency.

Every run is recorded step-by-step: status, timing, inputs, outputs, per-type detail (filter in/out counts, switch match, database rows, code stdout, loop passes), and warnings — including unresolved variable expressions on tool/database steps.

Retry-from-step creates a new run that reuses the original run's inputs and every upstream result verbatim — upstream agent steps are not re-executed or re-billed — and re-executes only the chosen step's downstream closure.

Versions and concurrency

Versions are explicit, immutable snapshots with optional aliases, saved on demand. Restore replaces the draft (never deleting newer versions); each version's steps can be validated against currently-existing agents, tools, and databases. Editor saves use optimistic concurrency: a save carrying a stale token is rejected and surfaced as a conflict dialog rather than overwriting.

Limits & guarantees

Limit / guaranteeValue
Deterministic steps billedNever, including for-each/loop shells and filtered-out events
Loop passesCapped at 100; reaching the cap ends the loop as a normal completion, flagged in results
Database readUp to 500 rows per read
Database update/deleteRequire non-empty match rules
Unresolved variablesNever crash a run; reported as warnings, excluded from database writes
Webhook back-compatPre-existing webhook addresses and scheduled automations keep working unchanged

What's next