Skip to main content
This page is a complete reference for all template tags, filters, and operators available in Reporter. For an introduction to templates and placeholders, see What is Reporter.

Building templates


Common blocks

  • Loop
{% for <item> in <list> %}
  ...
{% endfor %}
  • Loop with explicit schema
{% for order in external_db:sales.orders %}
  {{ order.id }} - {{ order.total }}
{% endfor %}
  • Simple condition
{% if value_a == value_b %}
  ...
{% endif %}
  • Temporary scope
{% with <object> as <alias> %}
  ...
{% endwith %}
  • Value formatting
{{ field_name | floatformat:2 }}   --> renders 123.45

Conditional blocks

BlockDescriptionExample
IfRuns block if condition is true{% if condition %}...{% endif %}
If-elseRuns one block if true, another if false{% if condition %}...{% else %}...{% endif %}
If-else-ifAllows multiple checks{% if a %}...{% elif b %}...{% else %}...{% endif %}
EqualChecks if two values are equal{% if a == b %}
Not equalChecks if two values are different{% if a != b %}
Greater thanChecks if a is greater than b{% if a > b %}
Less thanChecks if a is less than b{% if a < b %}
Greater than or equalChecks if a is greater than or equal to b{% if a >= b %}
Less than or equalChecks if a is less than or equal to b{% if a <= b %}
AndReturns true if both conditions true{% if a and b %}
OrReturns true if at least one true{% if a or b %}
NotInverts Boolean result{% if not a %}

Tags reference


Aggregation tags

sum_by — Sums numeric values from a field across all items in a collection.
{% sum_by <collection> by <field> %}
{% sum_by <collection> by <field> if <condition> %}
Example:
<Sum>
  {% sum_by transaction.operation by "amount" if accountAlias != "@external/BRL" %}
</Sum>
count_by — Counts the number of items in a collection.
{% count_by <collection> %}
{% count_by <collection> if <condition> %}
Example:
<Count>
  {% count_by transaction.operation if accountAlias != "@external/BRL" %}
</Count>
avg_by — Calculates the average of numeric values in a field.
{% avg_by <collection> by <field> %}
{% avg_by <collection> by <field> if <condition> %}
min_by — Finds the minimum numeric value in a field.
{% min_by <collection> by <field> %}
{% min_by <collection> by <field> if <condition> %}
max_by — Finds the maximum numeric value in a field.
{% max_by <collection> by <field> %}
{% max_by <collection> by <field> if <condition> %}
All aggregation tags use decimal precision to avoid floating-point rounding errors. Missing or non-numeric fields are skipped. Returns 0 if no items match.

Date and time tag

date_time — Outputs the current date and time formatted according to the provided format string. Time is generated in UTC.
{% date_time "<format>" %}
Format codes:
CodeMeaningExample
YYYY4-digit year2025
MM2-digit month01-12
dd2-digit day01-31
HH2-digit hour (24h)00-23
mm2-digit minute00-59
ss2-digit second00-59
Examples:
{% date_time "YYYY-MM-dd" %}           --> 2025-02-06
{% date_time "dd/MM/YYYY HH:mm:ss" %} --> 06/02/2025 14:30:45

Arithmetic tag

calc — Evaluates mathematical expressions with support for variables from the template context.
{% calc <expression> %}
Supported operators:
OperatorDescriptionPrecedence
**ExponentiationHighest (right-to-left)
* /Multiplication, divisionMiddle
+ -Addition, subtractionLowest
( )ParenthesesOverride precedence
Examples:
{% calc 100 + 50 %}                                --> 150
{% calc balance.available * 0.5 %}                 --> calculated value
{% calc (balance.available + 1.2) * balance.on_hold - balance.available / 2 %}
Variables that cannot be resolved default to 0. Division by zero produces an error.

Financial aggregation tag

aggregate_balance — Groups items by a field, selects the most recent entry per account within each group, and sums the balances. Useful for regulatory reports that require the latest balance per account grouped by category.
{% aggregate_balance <collection> by "<balance_field>" group_by "<group_field>" order_by "<date_field>" [if <condition>] as <result_var> %}
The result is stored in a variable you can iterate over:
{% aggregate_balance accounts by "balance" group_by "cosif_code" order_by "created_at" as balances %}
{% for b in balances %}
  {{ b.group_value }}: {{ b.balance }} ({{ b.count }} accounts)
{% endfor %}
Each result item contains:
FieldTypeDescription
group_valuestringThe value from the group_by field
balancedecimalSum of latest balances per account in the group
countintegerNumber of accounts in the group
Maximum collection size: 100,000 items. Results are sorted by group_value.

Counter tags

counter — Increments a named counter by 1. Produces no output. Counters are scoped per render.
{% counter "<counter_name>" %}
counter_show — Displays the sum of one or more named counters.
{% counter_show "<name1>" %}
{% counter_show "<name1>" "<name2>" "<name3>" %}
Example:
{% for tx in ledger.transactions %}
  {% counter tx.type %}
{% endfor %}
Total credits: {% counter_show "credit" %}
Total debits: {% counter_show "debit" %}
Combined: {% counter_show "credit" "debit" %}

Filters reference


percent_of

Calculates the percentage of a value relative to a total. Returns a formatted string with 2 decimal places.
{{ value | percent_of: total }}
Example: if category.amount = "6.00" and total.expenses = "20.00":
{{ category.amount | percent_of: total.expenses }}  --> 30.00%

strip_zeros

Removes trailing zeros from a numeric value without rounding.
{{ number | strip_zeros }}
Examples:
{{ "100.50000" | strip_zeros }}  --> 100.5
{{ "100.00" | strip_zeros }}     --> 100
{{ "99.990" | strip_zeros }}     --> 99.99

slice

Extracts a substring using start and end indices (0-based).
{{ string | slice:"start:end" }}
Examples:
{{ "hello" | slice:"0:3" }}  --> hel
{{ "12345" | slice:"1:4" }}  --> 234

replace

Replaces all occurrences of a search string with a replacement string. Format: "search:replacement".
{{ string | replace:"search:replacement" }}
Examples:
{{ "01310-100" | replace:"-:" }}      --> 01310100   (removes hyphens)
{{ "1234.56" | replace:".:," }}       --> 1234,56    (dot to comma)
{{ "12.345.678/0001-99" | replace:".:" }}  --> 12345678/0001-99

where

Filters an array of objects by field equality. Supports nested fields via dot notation.
{{ array | where:"field:value" }}
Examples:
{{ holders | where:"state:SP" }}
{{ holders | where:"address.state:SP" }}
Use inside loops:
{% for holder in holders|where:"state:SP" %}
  {{ holder.name }}
{% endfor %}

sum (filter)

Sums numeric values from a field across all items in an array. Uses decimal precision.
{{ array | sum:"field" }}
Examples:
{{ operations | sum:"amount" }}
{{ items | sum:"price.value" }}

count (filter)

Counts elements in an array where a field matches a value. Supports nested fields.
{{ array | count:"field:value" }}
Examples:
{{ operations | count:"nat_oper:6" }}
{{ holders | count:"address.state:SP" }}

contains

Checks if one value is partially included in another. Useful when data includes dynamic prefixes or suffixes.
{% if contains(source_field, target_field) %}
Example:
  • Source: 0#@external/BRL
  • Target: @external/BRL
Returns true because @external/BRL exists within the source value.

Operators and filters summary


NameTypeDescription
sum_byTagSum values by field with optional filter
count_byTagCount items with optional filter
avg_byTagCalculate average by field
min_byTagFind minimum value
max_byTagFind maximum value
date_timeTagFormat current date/time
calcTagEvaluate arithmetic expressions
aggregate_balanceTagGrouped financial balance aggregation
counterTagIncrement a named counter
counter_showTagDisplay counter value(s)
percent_ofFilterCalculate percentage
strip_zerosFilterRemove trailing zeros
sliceFilterExtract substring
replaceFilterString replacement
whereFilterFilter array by field value
sumFilterSum array field values
countFilterCount matching items
containsFunctionPartial string match
floatformatFilterFormat decimal places

Advanced filtering


When generating a report, you can pass filters in the request body to narrow the data. Filters follow a structure of datasource > table > field: Single schema (default):
{
  "templateId": "00000000-0000-0000-0000-000000000000",
  "filters": {
    "midaz_onboarding": {
      "account": {
        "id": { "eq": ["123", "456"] },
        "createdAt": { "between": ["2023-01-01", "2023-01-31"] },
        "status": { "in": ["active", "pending"] }
      }
    }
  }
}
Multi-schema (explicit schema.table key):
{
  "templateId": "00000000-0000-0000-0000-000000000000",
  "filters": {
    "external_db": {
      "sales.orders": {
        "total": { "gt": [100] },
        "created_at": { "gte": ["2025-01-01"] }
      },
      "finance.invoices": {
        "status": { "eq": ["paid"] }
      }
    }
  }
}
Supported operators:
OperatorDescriptionExample
eqEqual to{ "eq": ["active", "pending"] }
gtGreater than{ "gt": [100] }
gteGreater than or equal to{ "gte": ["2025-06-01"] }
ltLess than{ "lt": [1000] }
lteLess than or equal to{ "lte": ["2025-06-30"] }
betweenValue falls within a range{ "between": [100, 1000] }
inValue is within a list{ "in": ["active", "pending"] }
ninValue is not within a list{ "nin": ["deleted", "archived"] }