Note: This page is a reference. Use the table of contents or Ctrl+F to find what you need.
Quick syntax cheat sheet
Shape | What it does | Example |
|---|---|---|
| Show a value |
|
| Do something (if, for, set…) |
|
| A note that doesn't appear in the output |
|
| Apply a filter to a value |
|
| Stitch two strings together |
|
| Reach a field on an object |
|
| Reach a field whose name has spaces |
|
| Reach the first item in a list |
|
About Jinja in Pipelines
Pipelines runs Jinja version 2.11.3 in a limited environment. You can't import Python modules, read files from disk, or call out to the network from inside a Jinja expression. Everything you can do is on this page.
Jinja isn't the Quickbase formula language. The two share goals (turn data into something useful) but have different syntax. Many filters below have a close equivalent in formulas, called out in the Quickbase formula column. Treat the mapping as a loose match, not exact.
Variables—dot, bracket, get, set
3 ways to reach a field on a step:
Way to write it | When to use |
|---|---|
| Standard: name is one word, no spaces or special characters |
| The field name has spaces, or matches a reserved word |
| The field might not exist; supply a default |
Create your own variable:
{% set total = 0 %}
{% set greeting = 'Hello, ' ~ a.first_name %}For a variable you want to update inside a loop, use namespace(). Learn more in Pipelines-specific extras.
Statements, expressions, comments
{{ value }} # show a value
{% statement %} # do something — if, for, set
{# comment #} # leave a note that won't appear in the outputComments are useful for temporarily disabling a block of Jinja while you debug.
If / elif / else
{% if a.amount > 1000 %}Big
{% elif a.amount > 100 %}Medium
{% else %}Small
{% endif %}{% if … %}—the first question{% elif … %}—(optional, can have many) another question if the previous was no{% else %}—(optional) what to do if nothing matched{% endif %}—closes the block
To learn more, refer to Start with Jinja in Pipelines.
For loops and loop helpers
{% for r in b %}
{{r.name}}
{% endfor %}Inside any loop, these helpers are available:
Helper | What it gives you |
|---|---|
| Position of the current item, starting at 1 |
| Position of the current item, starting at 0 |
|
|
|
|
| Total number of items |
| Position counted from the end, starting at 1 |
| The previous item (not available on the first) |
| The next item (not available on the last) |
To learn more, refer to Start with Jinja in Pipelines.
Whitespace control
Jinja keeps the whitespace around your statements by default, which can break JSON payloads or leave empty lines. Add a hyphen to either side to strip whitespace:
{%- if a.amount > 100 -%}{%-strips whitespace before the tag-%}strips whitespace after the tag
The same works for expressions: {{- value -}}.
Filters by category
A filter changes a value, applied with the pipe character |. Filters chain: {{a.notes | striptags | trim | upper}} strips HTML, trims whitespace, then uppercases, in that order.
Date/time
Filter | What it does | Example | Quickbase formula |
|---|---|---|---|
| Current date and time, in UTC |
|
|
| Today's date at 00:00 UTC |
|
|
| Add or subtract a span of time. Plural arg ( |
|
|
| Turn a date-shaped string into a real date |
|
|
| Convert UTC to a specific timezone. Codes from the tz database |
| — |
| Format as year-month-day. Default separator is |
|
|
| Format as month-day-year |
|
|
| Format as day-month-year |
|
|
| Custom date format. Method, not filter. Use dot notation, not pipe |
|
|
| Drop the time portion off a date/time |
|
|
| When you subtract two dates, get the number of days as a number |
|
|
| When you subtract two dates, get the number of seconds |
| — |
| Convert a Unix timestamp (seconds since 1970) to UTC |
| — |
Note:
.strftimeand.findare methods, not filters. Usevalue.strftime(...), notvalue | strftime(...). The pipe form silently does the wrong thing.
Common strftime format codes:
Code | Result |
|---|---|
| Year, 4 digits (2025) |
| Month, 2 digits (01–12) |
| Day, 2 digits (01–31) |
| Month name (January) |
| Month abbreviated (Jan) |
| Weekday name (Monday) |
| Weekday abbreviated (Mon) |
| Hour, 24-hour (00–23) |
| Hour, 12-hour (01–12) |
| Minute (00–59) |
| Second (00–59) |
| AM or PM |
Text
Filter | What it does | Example | Quickbase formula |
|---|---|---|---|
| Make all uppercase |
|
|
| Make all lowercase |
|
|
| Capitalize the first letter of each word |
| — |
| Capitalize the first letter, lowercase the rest |
| — |
| Remove whitespace from the ends |
|
|
| Replace a substring |
|
|
| Number of characters |
|
|
| Number of words |
| — |
| Take a portion of a string. Use |
|
|
| Stitch two strings together |
|
|
| Split a string into a list by a delimiter (method) |
|
|
| Position of a substring (-1 if not found). Method, not filter |
| — |
| Remove all HTML/XML tags |
| — |
| Strip HTML and formatting from a rich text field |
| — |
| Convert HTML to Markdown |
| — |
| Convert |
| — |
| Make a string safe to use in a URL |
| — |
| Insert values into a template string |
| — |
| Convert to JSON-safe text. Use when building JSON payloads, as it handles escaping automatically |
| — |
| Mark a value as already safe; skip escaping |
| — |
| Shorten a string and add |
| — |
Numbers
Filter | What it does | Example | Quickbase formula |
|---|---|---|---|
| Convert to a whole number |
|
|
| Convert to a decimal number |
|
|
| Round to a number of decimals |
|
|
| Absolute value (drop the minus sign) |
|
|
| Largest value in a list |
|
|
| Smallest value in a list |
|
|
Lists and aggregation
These work on lists—usually a search step's output, or a multi-select or List-User field.
Filter | What it does | Example |
|---|---|---|
| Number of items |
|
| First item |
|
| Last item |
|
| Sort the list. Add |
|
| Remove duplicates |
|
| Stitch list items into one string |
|
| Sum a list of numbers. Add |
|
| Pull one field out of each record |
|
| Keep only items that pass a test |
|
| Drop items that pass a test |
|
| Keep records whose field passes a test |
|
| Drop records whose field passes a test |
|
| Force the result into a list. Often needed after |
|
| Generate a list of numbers from |
|
| Pick a random item |
|
Encoding and hashing
Filter | What it does |
|---|---|
| Encode or decode a string in Base64. Used for embedding files in JSON payloads |
| MD5 hash |
| SHA hash family |
| Hash-based message authentication code, used for signing API requests |
Other
Filter | What it does | Example | Quickbase formula |
|---|---|---|---|
| Use a fallback if input is undefined or empty |
|
|
| Force a value into a string |
|
|
Tests
A test asks a yes/no question about a value. Tests use the word is, not the pipe character.
{% if a.field is defined %}...{% endif %}
{% if a.field is none %}...{% endif %}
{% if a.amount is number %}...{% endif %}Test | True when… |
|---|---|
| The variable exists |
| The value is empty / null |
| The value is text |
| The value is a number |
| The value is a whole number |
| The value is a decimal number |
| The value is |
| The value can be looped through (a list, for example) |
| The value is a key-value object (like a JSON object) |
| The value is an ordered collection (a list or a string) |
| The number is odd |
| The number is even |
| The number divides evenly by |
| Equals a given value |
| Not equal to |
| Less / less-or-equal / greater / greater-or-equal |
| The value is in a given list or string |
Combine with not to invert: {% if a.field is not none %}.
Pipelines-specific extras
These features are added by Pipelines on top of standard Jinja.
The runtime object
Every pipeline run has a runtime object with metadata about itself.
Property | What it gives you |
|---|---|
| User-defined pipeline name |
| Numeric pipeline ID |
| Link to the pipeline editor |
| Unique ID of this run |
| Direct link to this run in the activity log |
| UTC timestamp of when the run started |
| Pipelines user ID of whoever triggered the run |
Example—build a clickable link into an error alert:
Pipeline "{{runtime.pipeline_name}}" failed.
View activity: {{runtime.activity_url}}The trigger context object (Quickbase triggers)
On a Quickbase trigger step, a.context gives you details about the app and table that fired the run.
Property | What it gives you |
|---|---|
| The app name |
| The app ID |
| The table name |
| The table ID |
| Your Quickbase realm host |
| Numeric realm ID |
| When the change happened, UTC |
| The user who triggered the change |
$prev
Access the previous value of a field when the trigger was a Record Updated event. Goes between the step letter and the field name:
{% if a.status != a.$prev.status %}...{% endif %}Only available on update triggers. Does not work in Quickbase Advanced Query filter strings. See Start with Jinja in Pipelines for the full explanation.
{{CLEAR}}
Explicitly empty a field in a write step. By default, Pipelines silently skips empty values to prevent accidental data loss. Use {{CLEAR}} to override that.
{% if a.priority == 'No priority' %}{{CLEAR}}{% else %}{{a.priority}}{% endif %}raise_error(message)
Stop a pipeline run with a custom error message. Useful for input validation.
{% if a.amount > 10000 %}{{raise_error('Amount over the limit')}}{% endif %}joiner() and namespace()
Two helpers for situations where standard Jinja has limitations.
joiner(separator) builds a comma-separated list inside a loop without a leading or trailing separator. The first call returns nothing; every subsequent call returns the separator.
{% set comma = joiner(', ') %}
{% for c in b %}{{comma()}}{{c.name}}{% endfor %}Produces Alice, Bob, Carol with no leading or trailing comma.
namespace(...) is a container for variables that need to change inside a loop. A normal {% set %} inside a loop only updates for that iteration; namespace persists the value across iterations.
Most common use: a running total that ignores nulls.
{% set total = namespace(value=0) %}
{% for r in b %}
{% set total.value = total.value + (r.amount | default(0, true)) %}
{% endfor %}
Total: {{total.value}}Advanced Query—Quickbase query syntax
Warning: Advanced Query / filter fields on Quickbase search and trigger steps use Quickbase query syntax, not Jinja. When you select code mode on one of these fields, you're typing query syntax. Jinja can still be embedded inside the value portion—see Embed Jinja inside a query below.
Query format
Each query is wrapped in curly braces and has three parts separated by periods:
{fid.OPERATOR.'matching_value'}fid—the field's numeric ID
OPERATOR—uppercase, from the table below
matching_value—what to compare against, in single quotes
Example—find records where field 6 equals "Open":
{6.EX.'Open'}Combine multiple conditions with AND or OR (always uppercase), grouped with parentheses:
({6.EX.'Open'}OR{6.EX.'In Progress'})AND{13.OAF.'01-01-2025'}Common operators
Operator | What it does | Example |
|---|---|---|
| Equals exactly |
|
| Not equal |
|
| Contains substring (text) |
|
| Starts with (text) |
|
| Before / after / on or after (date) |
|
| Less / less-or-equal / greater / greater-or-equal (numbers) |
|
| Contains a value (multi-select, List-User) |
|
| In a relative date range ( |
|
For the full operator list, see Components of a Query.
Compare one field to another
Use _FID_n as the matching value to compare two fields on the same record:
{6.EX._FID_8}Returns records where field 6 equals field 8.
Embed Jinja inside a query
The matching value portion can contain Jinja, evaluated at runtime. The outer query syntax stays the same; the inner {{…}} produces the value.
Find records modified in the last 5 minutes:
{2.OAF.'{{time.now + time.delta(minutes=-5)}}'}Find records owned by the user who triggered the run:
{8.EX.'{{a.context.user}}'}Find records matching a value from step a:
{6.EX.'{{a.customer_id}}'}Two things that don't work inside a query:
$prev—only works in regular Jinja value expressions, not in query stringsMulti-line Jinja with
{% … %}statements—keep it to a single{{ … }}expression
What isn't supported
Things you might expect to work but don't:
{% break %}and{% continue %}inside loops. Useselect/rejectfilters to filter the list before looping, or wrap the loop body in an{% if %}.{% include %},{% import %},{% extends %}—Pipelines doesn't allow template inheritance.Importing Python modules.
Reading or writing files outside the pipeline.
The
doextension ({% do … %}).
Reserved words
A few attribute names conflict with built-in Jinja or Python concepts and can't be reached with dot notation. Use bracket notation instead.
Field name | Use this instead of |
|---|---|
|
|
|
|
|
|
|
|