Skip to main content
The Store action node reads from and writes to a managed store: an append-only, timestamped series of values indexed by a key. Use it to carry state across pipeline runs, compare current values against historical ones, or accumulate a running series without building a dedicated external database.

When to use Store

  • You want to track how a value changes over time across runs: prices, quantities, scores.
  • You need to compare the current run’s data against the most recent previous value without calling an external API.
  • You want to accumulate a running total or average across multiple runs (e.g., daily volume, average invoice amount).
  • A downstream HTTP action or Validation node needs historical context that does not live in the current document.
For purely within-run named values, use Variable instead. Store is for values that must outlive a single run.

Prerequisites

Before using a Store node, create at least one store under Settings > Stores. If no store exists, the node cannot be configured. Every store carries a required value schema that describes the object held under each key. A Set node’s value must match that schema, so design the store first and the node second.

Modes

The Store node operates in one of two modes, selected in the node editor.

Set

Appends the resolved value under the given key. The write is idempotent per run and node: if the same Store node runs twice for one pipeline run, only one entry is written. The value must be a JSON object, not a scalar or an array: a pipeline whose Set value is anything else fails validation on save. The object must also match the store’s value schema. Ingestly adds a reserved key property carrying the entry key to every stored value, so never declare key in the schema or in the node’s value. A value larger than 256 KB is rejected and the step fails.

Fail on null value

By default, an expression that resolves to nothing renders as an empty string inside the stored object and the run succeeds. Turn Fail on null value on to make that a hard failure instead. The check covers three cases and names what went wrong:
  • An unresolved reference: the message quotes the token, for example the reference {{extract.payload.total}} did not resolve.
  • A JSON-null leaf, named by its dotted path, for example 'lines[0].sku' resolved to a null or empty value.
  • An empty or whitespace-only string leaf, named by that same dotted path.
Built-in helpers such as {{uuid}} and {{now}} always resolve, so they are never reported as unresolved. An empty object or an empty array is not a leaf and does not trip the check.

Set inside a Loop

A Set inside a Loop body is buffered, not written straight away. Buffered writes are committed together only after every item succeeds, so a loop that fails part-way persists nothing. A Get in the same loop reads committed entries only: it never sees the loop’s own pending writes.

Get

Reads the series for a key and returns the result as the node’s payload. Three operations are available.

Latest

Returns the single most recent entry for the key. The result lands at payload. Stored JSON is parsed back into structured data, so read its fields directly, for example {{getPrice.payload.unitPrice}}. metadata.store.found is false and payload is null when no entry matched.

Last N

Returns the most recent N entries as a list. The result lands at payload (array, newest first). Empty array when no entries matched.

Aggregate

Computes a number over the series. The result lands at payload (number). An empty series yields 0 for Total and Count, and null for Average, Lowest, and Highest. The node reads Value path out of each stored entry before computing the aggregate. Entries where the path does not resolve to a number are skipped. Leave it blank only when the stored value is itself a number: values written by a Set node are always objects, so a blank path aggregates nothing for them.
Value path is a literal path, not a template expression. It addresses the stored value’s own shape, so use the entry’s field names with dots for nested objects and brackets for array elements (amount, data.amount, items[0].price). A {{token}} there is rejected when you save the pipeline, and a pipeline saved before this rule fails the step at run time with the same message rather than aggregating silently to 0 or null.
The editor suggests paths sampled from entries already stored under the configured key. Click a suggestion to fill the field. Upstream pipeline fields are deliberately not offered, because the path is read against the stored entry rather than the current run.

Window

All three operations accept an optional Window to restrict which entries are included.
Range bounds are UTC only. A timestamp carrying a non-zero offset (for example 2026-01-01T10:00:00+05:30) is rejected at run time and the step fails. A timestamp with no zone at all (2026-01-01T10:00:00) is read as UTC.
When no window is set, all entries for the key are included.

Output

The node’s data lives in payload and identity/provenance fields are under metadata.store. Read downstream as {{storeName.payload}} or {{storeName.metadata.store.<field>}} where storeName is the node name in your pipeline. payload - the operation result: metadata.store - identity and provenance:
found and count are present for every Get shape, including a miss and an empty aggregate series, where count is 0. A downstream node can branch on {{getPrice.metadata.store.count}} without first checking that the field exists.

Limits

The pipeline editor enforces the same bounds the API publishes, so a configuration the editor accepts is not refused when you save.

When a store is missing

Deleting a store that a pipeline still references breaks that pipeline:
  • The node editor shows Store not found in place of the store name, with an inline note telling you the selected store no longer exists in this workspace.
  • Saving or validating the pipeline reports a validation error naming that node, and the pipeline stays invalid (and therefore cannot run) until you point the node at a store that exists.
  • If the pipeline does run against a deleted store, the step fails with Store not found or was deleted.

Moving a pipeline between workspaces

Pipeline exports carry store references by name, not by ID. On import, Ingestly rebinds each Store node to the store with the same name in the destination workspace. When no store matches that name (or more than one does), the reference is cleared and reported: the import warning lists unbound connectors, stores, and forward targets together, so open each affected node and pick a replacement. See export and import.

Example: price change detection

A purchase-order pipeline captures each line item’s unit price on every run and surfaces a warning when the price has changed. Set node (runs when the order arrives):
Get node (runs in the next pipeline run for the same SKU):
Downstream Variable node computes the delta:
A downstream Validation node can then gate on {{vars.payload.priceChanged}}, or an edge condition can branch on it. Filter is not the node for this: it only keeps or drops pages of one document and never branches on a variable.

Inputs and outputs

Allowed inputs: All trigger nodes and all action nodes. Output: The node result with data at payload and identity fields at metadata.store, as described in the Output section above.

Credits

Store nodes are free. They consume 0 credits per execution.

Stores settings

Create and manage store resources

Variable

Define named values that live only within a single run

HTTP action

Call external APIs to read or write data mid-pipeline

Expressions and filters

Template syntax for key and value fields