DataFlow Policies
A DataFlowPolicy controls how data moves into and out of a node through a
specific field — which fields participate in the platform's automatic input/output mapping
pipeline, and which are isolated from it.
Structure
public sealed class DataFlowPolicy
{
public bool AcceptsUpstreamInput { get; init; } = false;
public bool EmitsToDownstream { get; init; } = false;
public bool PersistsToMemory { get; init; } = false;
public bool ExcludeFromInputMapping { get; init; } = false;
public bool ExcludeFromOutputMapping { get; init; } = false;
}
AcceptsUpstreamInput
When true, this field can receive its value from an upstream node's output.
The platform's input mapper automatically populates the field from the incoming data bag.
| Set to true | Set to false |
|---|---|
Email to (from customer lookup), Slack channel (from team config), form assignedTo (from role resolution) |
Credential fields (always from static config), output-only fields (no upstream provides them) |
EmitsToDownstream
When true, this field's value is included in the node's output data and can
be consumed by downstream nodes.
| Set to true | Set to false |
|---|---|
SMTP messageId, HTTP response.body, Slack slack.ts, approval approvalDecision |
Input / config fields consumed by this node — they should not propagate |
PersistsToMemory
When true, the field's value is written to the workflow's persistent memory store
after execution, available throughout the rest of the workflow lifetime.
Use when: The value must survive suspension/resumption cycles, is needed for audit, or other non-immediate downstream nodes may reference it.
| Set to true (persist) | Set to false (transient) |
|---|---|
HTTP response.body, approval approvalDecision, form form.submission, Slack slack.ts |
HTTP response.status — useful for immediate routing, not long-term storage |
ExcludeFromInputMapping
When true, this field is skipped by the automatic input mapper
even if upstream data contains a matching key. The field can only be set via its own static
config or expression evaluation.
Primary use case: Credentials and internal routing fields that must never be overwritten by upstream data regardless of name collisions.
// credentialId must never be overwritten by upstream
ExcludeFromInputMapping = true // defensive — even though AcceptsUpstreamInput is false
ExcludeFromOutputMapping
When true, this field is not included in the node's output data bag
sent to downstream nodes, even if EmitsToDownstream is set.
Use on all input/config fields to prevent them from leaking into downstream data.
Field Archetype Patterns
Static Config
Fixed in the workflow definition — does not flow in or out.
DataFlowPolicy = new DataFlowPolicy
{
AcceptsUpstreamInput = false,
EmitsToDownstream = false,
PersistsToMemory = false,
ExcludeFromInputMapping = true,
ExcludeFromOutputMapping = true
}
// Examples: strategy, method, host, resource, operation
Dynamic Input
Receives its value from upstream nodes at runtime.
DataFlowPolicy = new DataFlowPolicy
{
AcceptsUpstreamInput = true,
EmitsToDownstream = false,
PersistsToMemory = false,
ExcludeFromInputMapping = false,
ExcludeFromOutputMapping = true
}
// Examples: to, body, channel, actors, assignedTo
Output / Result
Produced by the executor; downstream nodes consume it.
DataFlowPolicy = new DataFlowPolicy
{
AcceptsUpstreamInput = false,
EmitsToDownstream = true,
PersistsToMemory = true,
ExcludeFromInputMapping = true,
ExcludeFromOutputMapping = false
}
// Examples: messageId, response.body, approvalDecision, form.submission, slack.ts
Transient Output (not persisted)
Flows downstream but not worth storing in workflow memory.
DataFlowPolicy = new DataFlowPolicy
{
AcceptsUpstreamInput = false,
EmitsToDownstream = true,
PersistsToMemory = false,
ExcludeFromInputMapping = true,
ExcludeFromOutputMapping = false
}
// Example: response.status
Data Flow Diagram
Upstream Node Output
│
▼ (AcceptsUpstreamInput = true AND ExcludeFromInputMapping = false)
┌───────────────────────────────┐
│ Node Execution │
│ │
│ [INPUT FIELDS] │ ← static config + expression eval + upstream mapping
│ [OUTPUT FIELDS] │ ← set by executor after running
└───────────────────────────────┘
│
├── Downstream nodes (EmitsToDownstream = true AND ExcludeFromOutputMapping = false)
│
└── Workflow Memory (PersistsToMemory = true)
AcceptsUpstreamInput: trueon a credential field — allows upstream to overwrite the vault reference. Alwaysfalsefor credentials.EmitsToDownstream: true+ExcludeFromOutputMapping: true— field says it emits but is blocked from the output bag. SetExcludeFromOutputMapping: falsefor output fields.