Node catalog
Every node type a flow can use, with its config fields, defaults and output branches.
This page is rendered from NODE_SPECS in packages/core/src/catalog.ts when the docs are built,
the same objects the editor’s palette, the inspector’s forms and the engine’s validation read. Each
node’s anchor is its type, for example #commerce.policy.
A node’s outputs are the branches it can take. An edge leaves a node from one output (its
sourceHandle; none means out), and the edges on the branches a node did not take are skipped
(see Planner). Field kinds decide how the inspector edits a value and how
it is validated: duration is a string like "2 days", logic is a
JSON Logic expression, list is a non-empty list of strings, and text
fields interpolate {{path}} templates.
Every node also takes two optional settings outside its config: retries (0–10, default 3 unless
the node type sets its own) and timeout (default "5 minutes"), applied to its step.
Triggers
Section titled “Triggers”A flow has exactly one trigger. Triggers pass the order through; they mark how the order started.
Manual / API
trigger.manualStarted from the dashboard or POST /api/v1/orders.
- Outputs
out
Webhook
trigger.webhookStarted by an inbound webhook (storefront checkout, marketplace order).
- Outputs
out
| Field | Kind | Default | Notes |
|---|---|---|---|
source | text | storefront | Source |
Inbound PO email
trigger.email_poA purchase order arrives by email or upload; the document is stored in R2.
- Outputs
out
| Field | Kind | Default | Notes |
|---|---|---|---|
mailbox | text | orders@ | Mailbox |
Schedule
trigger.scheduleStarted on a cadence (reorder runs, subscription renewals).
- Outputs
out
| Field | Kind | Default | Notes |
|---|---|---|---|
cron | text | 0 6 * * * | Cron |
Inventory threshold
trigger.inventory_thresholdStarted when a SKU falls below its reorder point.
- Outputs
out
Commerce
Section titled “Commerce”Commerce nodes call the connectors. Every write is keyed by its step, so a retried step never reserves, charges or ships twice.
Validate order
commerce.validateNormalises lines, resolves SKUs and the customer, rejects empty orders.
- Outputs
out
Price & quote
commerce.pricePrices each line through the pricing chain (price books, contract prices, volume tiers, then list price) and computes the subtotal.
- Outputs
out
| Field | Kind | Default | Notes |
|---|---|---|---|
useContracts | boolean | true | Contract pricing. Use the customer’s negotiated prices |
usePriceRules | boolean | true | Price books and volume tiers. Use the price-book and volume entries in the back office |
Calculate tax
commerce.taxComputes tax on the subtotal (mock tax engine).
- Outputs
out
| Field | Kind | Default | Notes |
|---|---|---|---|
rate | number | 0.08 | Rate |
Policy check
commerce.policyChecks order rules: minimum or maximum total, per-SKU limits, business hours, PO boxes, restricted SKUs.
- Outputs
passfail
| Field | Kind | Default | Notes |
|---|---|---|---|
rules (required) | json | [{"rule":"min_order_amount","amount":25},{"rule":"max_qty_per_sku","qty":500}] | Rules. min_order_amount, max_order_amount, max_qty_per_sku, business_hours, no_po_box, restricted_skus |
Validate address
commerce.address_validateChecks and normalises the ship-to in order.meta.shipTo. A correction is offered in vars.suggestedAddress.
- Outputs
validcorrectedinvalid
Credit check
commerce.credit_checkCompares the order total plus open balance with the customer’s credit limit.
- Outputs
okover_limit
Budget check
commerce.budget_checkChecks a purchase request against the department budget.
- Outputs
withinover
| Field | Kind | Default | Notes |
|---|---|---|---|
budget | number | 25000 | Budget |
Reserve inventory
commerce.reserve_inventoryHolds stock for every line. Released automatically if the order later fails.
- Outputs
okbackorder - Undocompensated when the order fails or is cancelled
| Field | Kind | Default | Notes |
|---|---|---|---|
allowBackorder | boolean | false | Allow backorder |
Authorize payment
commerce.authorize_paymentPlaces an authorization hold. Voided automatically if the order later fails.
- Outputs
okdeclined - Undocompensated when the order fails or is cancelled
| Field | Kind | Default | Notes |
|---|---|---|---|
method | select | card | Method. One of card, ach, terms |
Capture payment
commerce.capture_paymentCaptures a previous authorization.
- Outputs
okfailed
Charge
commerce.chargeCharges the stored payment method (subscription renewal).
- Outputs
okfailed - Retries0 by default
Refund
commerce.refundRefunds captured or charged money, all of it or an amount computed from the context.
- Outputs
okfailed
| Field | Kind | Default | Notes |
|---|---|---|---|
amount | logic | Amount (expression). Empty refunds everything still refundable | |
reason | text | Customer return | Reason |
Generate invoice
commerce.invoiceRenders the invoice to R2 with the configured payment terms.
- Outputs
out
| Field | Kind | Default | Notes |
|---|---|---|---|
terms | select | net_30 | Terms. One of due_on_receipt, net_15, net_30, net_60 |
Generate PO
commerce.generate_poRenders a purchase order for the supplier to R2.
- Outputs
out
| Field | Kind | Default | Notes |
|---|---|---|---|
supplier | text | {{vars.supplier}} | Supplier |
Create shipment
commerce.shipBuys a label and books the carrier. Cancelled automatically if the order fails.
- Outputs
out - Undocompensated when the order fails or is cancelled
| Field | Kind | Default | Notes |
|---|---|---|---|
carrier | select | ups | Carrier. One of ups, fedex, dhl, freight |
Return label
commerce.return_labelIssues a prepaid return label (an RMA) and sends it to the customer.
- Outputs
out
| Field | Kind | Default | Notes |
|---|---|---|---|
carrier | select | ups | Carrier. One of ups, fedex, dhl, freight |
3-way match
commerce.three_way_matchMatches the PO, the goods receipt and the supplier invoice.
- Outputs
matchmismatch
| Field | Kind | Default | Notes |
|---|---|---|---|
tolerance | number | 0.02 | Tolerance |
Pay supplier
commerce.pay_supplierSchedules the supplier payment.
- Outputs
out
Restock
commerce.restockAdds received or returned quantities to on-hand inventory.
- Outputs
out
| Field | Kind | Default | Notes |
|---|---|---|---|
lines | logic | Lines (expression). A list of { sku, qty }; empty restocks every order line. Capped at the ordered quantity. |
ERP sync
commerce.erp_syncPosts the order to the ERP (mock).
- Outputs
out
| Field | Kind | Default | Notes |
|---|---|---|---|
system | text | netsuite | System |
Notify
commerce.notifySends a message to the customer, a supplier or the team.
- Outputs
out
| Field | Kind | Default | Notes |
|---|---|---|---|
to | select | customer | To. One of customer, supplier, team |
subject | text | Order {{order.id}} update | Subject |
body | textarea | "" | Body |
Control
Section titled “Control”Condition
control.conditionBranches on a JSON Logic expression over the run context.
- Outputs
truefalse
| Field | Kind | Default | Notes |
|---|---|---|---|
expression (required) | logic | {">":[{"var":"order.total"},1000]} | Expression |
Approval
control.approvalWaits for a person to approve or reject. Escalates when the timeout passes.
- Outputs
approvedrejectedescalated - Waitsfor a person or an event
| Field | Kind | Default | Notes |
|---|---|---|---|
title | text | Approve order {{order.id}} | Title |
assignee | text | manager | Assignee |
timeout | duration | 2 days | Escalate after |
Wait for event
control.wait_eventWaits for an external event (payment received, supplier ack, goods received).
- Outputs
receivedtimeout - Waitsfor a person or an event
| Field | Kind | Default | Notes |
|---|---|---|---|
event (required) | text | payment.received | Event |
timeout | duration | 30 days | Timeout |
Wait
control.waitSleeps for a duration, or until a timestamp computed from the context.
- Outputs
out
| Field | Kind | Default | Notes |
|---|---|---|---|
duration | duration | 1 day | Duration |
until | logic | Until (expression). Epoch ms; overrides duration |
Set variables
control.setAssigns run variables from JSON Logic expressions.
- Outputs
out
| Field | Kind | Default | Notes |
|---|---|---|---|
assign | json | {"cycle":{"+":[{"var":"vars.cycle"},1]}} | Assignments. { name: expression } |
Loop
control.loopRepeats its body while the condition holds, up to a limit. Connect the end of the body back to the “next” input.
- Outputs
bodydone - Loopaccepts a
nextback-edge
| Field | Kind | Default | Notes |
|---|---|---|---|
while | logic | true | While |
maxIterations | number | 12 | Max iterations |
Continue as new
control.continue_as_newEnds this run and starts a fresh one on the same flow, carrying the variables forward.
- Outputsnone: ends the run
End
control.endFinishes the order. “declined” is a policy or approval no; “failed” rolls back every compensable step.
- Outputsnone: ends the run
| Field | Kind | Default | Notes |
|---|---|---|---|
outcome | select | completed | Outcome. One of completed, declined, cancelled, failed |
reason | text | "" | Reason |
Each AI node has a schema-checked model call and a heuristic fallback; see AI nodes and the copilot.
Extract order
ai.extractReads an email or PO document and extracts the customer and line items.
- Outputs
out
Classify
ai.classifyAssigns one label from a list (spend category, urgency, intent).
- Outputs
out
| Field | Kind | Default | Notes |
|---|---|---|---|
labels | list | ["it_hardware","software","office_supplies","services","travel"] | Labels |
into | text | category | Store as var |
Risk score
ai.risk_scoreScores fraud and credit risk from 0 to 100; branches above the threshold.
- Outputs
lowhigh
| Field | Kind | Default | Notes |
|---|---|---|---|
threshold | number | 70 | High risk at |
Demand forecast
ai.forecastSuggests reorder quantities for SKUs at or below their reorder point.
- Outputs
out
| Field | Kind | Default | Notes |
|---|---|---|---|
horizonDays | number | 30 | Horizon (days) |
Summarize
ai.summarizeWrites a short summary of the order so far into a variable.
- Outputs
out
| Field | Kind | Default | Notes |
|---|---|---|---|
into | text | summary | Store as var |
Agent router
ai.routerAn LLM reads the order and context, then chooses exactly one route. Each route is an output.
- Outputsone per entry in Routes
| Field | Kind | Default | Notes |
|---|---|---|---|
instructions | textarea | Decide how to handle this order. | Instructions |
routes | list | ["auto_approve","needs_approval","ask_customer"] | Routes |