Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.docpipe.ai/llms.txt

Use this file to discover all available pages before exploring further.

DocPipe templates pull data from earlier nodes into the configuration of later ones. Wherever you see a field that accepts {{ ... }} (callback URL, HTTP body, email subject, transform output, validation rule), you can reference an upstream value, index into arrays, transform it with filters, or insert a built-in helper.

Basic syntax

A template expression has three parts: a path, optional filters, and the surrounding {{ }} markers.
{{ path | filter | filter }}
The path locates the value. Filters transform it left to right. The result replaces the whole {{ ... }} token.

Path

A path is a dotted identifier, optionally with array indices.
FormWhat it resolves to
{{nodeName}}The full output of the named upstream node, as JSON
{{nodeName.payload.field}}A field inside that node’s output
{{nodeName.payload.items[0].sku}}The first element of an array, then a field inside it
{{nodeName.payload.items[-1]}}The last element of an array (negative index counts from the end)
The first segment of every path must be the name of an upstream node (or a built-in placeholder or helper, see below). Subsequent segments index into that node’s output, which has the shape { success, payload, metadata, error }. Paths are case sensitive and may use letters, digits, and underscores.
Each node in the editor has a Name field. Default names are auto-assigned (extract, extract2, vars, etc.) but you can rename a node to anything that’s unique within the pipeline. Whatever name you pick is the identifier used at the head of every template expression.

Built-in placeholders

These resolve from the run context:
PlaceholderValue
{{documentId}}The current document’s ID
{{organizationId}}The owning organization’s ID
{{pipeId}}The current pipe’s ID
{{nodeId}}The current node’s ID

Built-in helpers

These produce a value at the time the template is evaluated.
HelperReturns
{{now}}Current UTC datetime as ISO 8601 (yyyy-MM-ddTHH:mm:ssZ)
{{today}}Current UTC date (yyyy-MM-dd)
{{nowUnix}}Current Unix epoch seconds
{{uuid}}A new UUID v7 (time-ordered)
You can chain filters onto helpers: {{now | formatDate: 'yyyy-MM-dd'}}.

Filters

Add a filter with the pipe character: {{ value | filter }}. Filters with arguments use a colon: {{ value | filter: 'arg1', 'arg2' }}. You can chain as many filters as you need, applied left to right.

Filter arguments

Each argument is one of:
FormExampleNotes
Number literal{{count | add: 5}}-3.14, 1e6, etc.
Quoted string{{name | concat: '!'}}Single or double quotes
true, false, null{{value | default: null}}Bare keywords
Path reference{{payload.terms | div: payload.divisor}}Resolved against the same upstream context as the head expression
Path references must satisfy the same shape as the head path (identifier(.identifier|[N])*). The runtime resolves them at filter-application time, so they can reference upstream node fields (extract.payload.divisor), built-in helpers ({{end | dateDiff: 'days', start}}), or array elements ({{items[0] | concat: items[1]}}). If the path resolves to a type that doesn’t match what the filter expects (e.g., div argument resolves to a string), the editor flags it before the run starts.

String filters

FilterExampleResult
upper{{name | upper}}ALICE
lower{{name | lower}}alice
trim{{ ' alice ' | trim}}alice
replace: 'from', 'to'{{name | replace: 'a', '@'}}@lice
substring: start, length?{{name | substring: 0, 3}}Ali
split: separator{{tags | split: ','}}["a","b","c"]
concat: 'suffix'{{name | concat: '!'}}Alice!
contains: 'needle'{{name | contains: 'lic'}}true

Number filters

FilterExampleResult
round: digits?{{3.14159 | round: 2}}3.14
ceil{{3.2 | ceil}}4
floor{{3.8 | floor}}3
abs{{-5 | abs}}5
add: n{{5 | add: 3}}8
sub: n{{5 | sub: 3}}2
mul: n{{5 | mul: 3}}15
div: n{{6 | div: 3}}2

Array filters

FilterExample
length{{items | length}}
first{{items | first}}
last{{items | last}}
join: separator{{tags | join: ', '}}
sum{{prices | sum}}
avg{{prices | avg}}
min{{prices | min}}
max{{prices | max}}
unique{{tags | unique}}
sort{{prices | sort}}

Date filters

Operate on ISO 8601 strings (or anything that can be parsed as one).
FilterExampleResult
formatDate: '...'{{now | formatDate: 'yyyy-MM-dd'}}2026-04-28
addDays: n{{today | addDays: 7}}2026-05-05T00:00:00Z
subDays: n{{today | subDays: 1}}2026-04-27T00:00:00Z
dateDiff: unit, otherDate{{end | dateDiff: 'days', '{{start}}'}}5
formatDate uses .NET-style format strings. Common patterns: yyyy-MM-dd, yyyy-MM-ddTHH:mm:ssZ, MM/dd/yyyy, HH:mm.

General filters

FilterExampleNotes
default: 'fallback'{{maybeMissing | default: 'n/a'}}Substitutes when the value is null or empty
json{{payload | json}}Stringify the value as JSON
escape{{name | escape}}HTML-escape a string

Type-aware autocomplete

When you type inside a {{ ... }} field in a node editor, DocPipe suggests:
  • Upstream node fields at the start of the expression (after {{)
  • Built-in helpers (now, today, uuid, nowUnix) alongside fields
  • Filters after a |, scoped to the type of the preceding value (an array path shows length, first, join; a string path shows upper, lower, trim)
  • Filter arguments as snippet placeholders you can tab through
Unknown filter names render with a red squiggle and surface as a validation error on the node.

Inside JSON bodies

When you write a template inside a JSON value position, like "qty": "{{payload.qty}}", DocPipe emits the resolved value as raw JSON so types are preserved. A number stays unquoted, an object stays structured, an array stays an array.
{
  "amount": "{{payload.amount | round: 2}}",
  "lines": "{{payload.lineItems}}"
}
After substitution the request body becomes:
{
  "amount": 3.14,
  "lines": [{ "sku": "A1", "qty": 2 }]
}
This applies to the HTTP action and callback output body fields when they parse as JSON. Outside JSON value positions (URLs, email subjects, plain-text fields), templates substitute as plain strings.
Filter arguments inside a JSON-position template should use single quotes ('a') rather than double quotes, to avoid clashing with the surrounding JSON string.

Common recipes

Last item from an extracted line items array, with a fallback:
{{extract.payload.lineItems[-1].sku | default: 'no-sku'}}
Total of a numeric array, rounded:
{{extract.payload.amounts | sum | round: 2}}
Today’s date plus 30 days as a yyyy-MM-dd string:
{{today | addDays: 30 | formatDate: 'yyyy-MM-dd'}}
Stringified JSON of a structured value, for a plain-text field:
{{extract.metadata | json}}
Comma-joined tags, uppercased:
{{extract.payload.tags | join: ', ' | upper}}

When a template doesn’t resolve

If the path can’t be resolved (the field is missing, the upstream node didn’t run, the index is out of bounds), DocPipe substitutes an empty string. Use default: '...' to provide a fallback. If the filter name is unknown or a filter call is malformed (wrong arg count, bad argument type), the substitution yields an empty string and the node surfaces a validation error.