Action Nodes
Perform operations on external systems. Require a connection for authentication.
App Nodes are integration-specific nodes provided by registered applications (Shopify, FedEx, WooCommerce, etc.). They are dynamically loaded based on which apps are installed.
App nodes are divided into two distinct types based on their role in a flow:
Action Nodes
Perform operations on external systems. Require a connection for authentication.
Trigger Nodes (Webhooks)
Start flows when external events occur. Require a webhook configuration.
Action nodes execute operations against external APIs (create order, get product, update shipment, etc.).
{app_prefix}.{action_name}
// Examples:app.shopify.create_orderapp.fedex.get_ratestenant.app.custom_integration.sync_inventory| Handle | Type | Position | Description |
|---|---|---|---|
input | target | left | Data from previous node |
output | source | right | Success response |
error | source | bottom | Error response |
Action nodes follow this structure:
{ // Only if app requires a connection (OAuth, API Key, etc.) connection_id?: string,
// Action-specific parameters parameters: { // Defined by the action's spec }}When an app requires authentication, the form includes a connection selector:
{ name: 'connection_id', type: 'select', label: 'Connection', placeholder: 'Select Connection', required: true, icon: app.icon, options: [ { label: 'My Shopify Store', value: 'conn_abc123' }, { label: 'Backup Store', value: 'conn_def456' } ], action: { label: 'Add', value: 'add_connection.app.shopify.create_order' }}Trigger nodes start flow execution when external events occur. They act as entry points for flows.
{app_prefix}.{trigger_name}
// Examples:app.shopify.order_createdapp.stripe.payment_receivedion.webhook // Custom webhook| Handle | Type | Position | Description |
|---|---|---|---|
output | source | right | Event data |
error | source | bottom | Processing error |
Trigger nodes require a webhook selector:
{ // Required: which webhook instance to use webhook_id: string,
// Event-specific parameters parameters: { // Defined by the trigger's spec }}{ name: 'webhook_id', type: 'select', label: 'Webhook', placeholder: 'Select Webhook', required: true, icon: app.icon, options: [ { label: 'Production Webhook', value: 'wh_abc123' }, { label: 'Testing Webhook', value: 'wh_def456' } ], action: { label: 'Add', value: 'add_webhook.app.shopify.order_created' }}This is how app nodes are constructed internally:
interface AppNode { label: string; // "Create Order" module: string; // "app.shopify.create_order" group: { icon: string; // App icon URL name: string; // "app.shopify" }; version: number; // 1 icon: string; // App icon URL spec: { type: 'collection', spec: Field[] // Form fields }; handle: Handle; // Input/output configuration}Action nodes:
{ source: [{ id: 'input', position: 'left' }], target: [ { id: 'output', position: 'right' }, { id: 'error', position: 'bottom' } ]}Trigger nodes:
{ source: [], // No input target: [ { id: 'output', position: 'right' }, { id: 'error', position: 'bottom' } ]}Apps come from two sources:
| Source | Prefix | Description |
|---|---|---|
| Global Apps | app.{type} | Platform-wide integrations (Shopify, FedEx) |
| Tenant Apps | tenant.app.{name} | Custom integrations per tenant |
App node configuration forms are built using the Spec Paradigm. Each action/trigger defines a spec that describes its parameters:
// Example: Shopify Create Order spec{ type: 'object', spec: [ { name: 'customer_id', type: 'string', label: 'Customer ID', required: true }, { name: 'email', type: 'email', label: 'Email' }, { name: 'line_items', type: 'array', label: 'Line Items' }, { name: 'note', type: 'textarea', label: 'Order Note' } ]}See Spec Paradigm for full documentation.
┌─────────────┐ ┌──────────────┐ ┌─────────────┐│ Shopify │ │ Mapper │ │ FedEx ││ Webhook │─────▶│ Transform │─────▶│ Get Rates ││ (trigger) │ │ │ │ (action) │└─────────────┘ └──────────────┘ └─────────────┘ │ │ └───────────────────┬───────────────────────┘ ▼ ┌─────────────┐ │ Condition │ └─────────────┘