---
title: Calculate
description: Do exact maths in an Edgaze workflow: totals, counts, reconciliation checks and per-category subtotals over data from earlier steps.
source: https://www.edgaze.ai/docs/builder/nodes/calculate
section: builder
---
# Calculate

> Do exact maths in an Edgaze workflow: totals, counts, reconciliation checks and per-category subtotals over data from earlier steps.

**Audience: Workflow creators.**

## Overview

Exact totals, counts, checks and group-by over data from earlier steps.

Use this block when its responsibility is clear in the graph. Give it a name that describes the work it performs, then test it with representative input before publishing.

## Working examples

These are complete starting points, not decorative diagrams. Every graph is also available in the main template library and is checked by the workflow compiler.

### 1. Reconcile a bank statement

**You will build:** Extract opening_balance, closing_balance and a transactions list with date, description and signed amount..

Proves every transaction was captured: opening balance plus all transactions must equal the closing balance. The sum is exact arithmetic, not a model's estimate, so a missed row always shows up.

```docsgraph
block-calculate-reconcile-a-bank-statement
```

[Open this template](/templates/block-calculate-reconcile-a-bank-statement) and adapt the labels, prompts, or credentials to your own workflow.

### 2. Total spending by category

**You will build:** Extract an expenses list with description, category and amount..

Gives exact per-category subtotals a person can trust. Grouping and totals are computed, so they match the rows exactly.

```docsgraph
block-calculate-total-spending-by-category
```

[Open this template](/templates/block-calculate-total-spending-by-category) and adapt the labels, prompts, or credentials to your own workflow.

### 3. Check an invoice total

**You will build:** Extract line_items with description, quantity, unit_price and line_total, plus tax and the stated total..

Catches invoices whose stated total does not match their lines. Line totals and tax are recomputed exactly instead of trusted.

```docsgraph
block-calculate-check-an-invoice-total
```

[Open this template](/templates/block-calculate-check-an-invoice-total) and adapt the labels, prompts, or credentials to your own workflow.

## Building calculations

Calculate works on the data the previous step returns. Connect a step that returns fields, such as Generate Text with **Return data as fields** turned on, and the editor lists every value and list it holds, each with its type and an example.

Click **Add a calculation** and choose what to work out from the menu: a total, count, average, lowest or highest value of a list; adding, subtracting, multiplying or dividing two values; checking that two values match; or rounding. Then pick the list and field, for example **Transactions › Amount**. To count or total only some items, add a condition such as "Category is Meals".

Each calculation has a result name, filled in for you (`total_amount`), that later calculations and later steps can use. Every row shows its result while you build, and **What this step returns** lists them all.

Previews use made-up example values until you run a test. After a test run, they use the real data the previous step returned, as long as you have not changed that step since; the editor says which it is using. If a test run stops before reaching the previous step, the last run that did reach it is used. Test-run data stays in your browser tab and is cleared when you reload or switch workflows.

While the workflow runs, customers see "Working out the numbers" with rolling digits, never the formulas or values. You can change the line under **What customers see**.

## Custom formulas

For anything the menus do not cover, choose **Custom formula** and write the expression. A formula can use any field and any earlier result.

```
net = sum(transactions.amount)
expected_closing = opening_balance + net
reconciled = approx(expected_closing, closing_balance, 0.01)
meals = sum(filter(transactions, "category", "==", "Meals").amount)
```

- **Fields** are read by path from the data connected to the step: `summary.total`, `transactions[0].amount`, or `["Field with spaces"]`. A path through a list collects the field from every item, so `transactions.amount` is every amount.
- **Money text is read as a number:** `$1,234.56`, `€1.234,56`, `12,50`, `(45.00)`, `45.00-`, `−45.00`, `12.00 CR` (money in) and `12.00 DR` (money out) all work. `N/A` and a lone dash count as empty, so totals skip them.
- **Operators:** `+ - * / %`, comparisons `== != < <= > >=`, and `and`, `or`, `not`. `not` applies to a whole comparison, so `not category == "Rent"` means "category is not Rent".
- **Only the side that matters is worked out:** `if(count(items) > 0, total / count(items), 0)` never divides by zero, and neither does `and` or `or` when the left side already decides the answer.
- **Rounding** ("Round numbers to") applies to what the step returns, half away from zero (8.575 becomes 8.58). Later formulas always use the exact values.
- **Functions:** `sum`, `count`, `avg`, `min`, `max`, `round(x, decimals)`, `abs`, `floor`, `ceil`, `approx(a, b, tolerance)`, `if(condition, a, b)`, `coalesce`, `filter(list, "field", operator, value)`, `unique`. The filter operators are `==`, `!=`, `<`, `<=`, `>`, `>=` and `contains`.

If the incoming value is text from a model, Calculate reads the JSON inside it, even inside a code fence.

## Totals per group

Choose a list and the field to group by to get one row per value, with how many items it has and, if you choose a field to total, their total. For example, group Transactions by Category and total Amount to see the spend in each category. The result is a list of `{ key, count, total }` under its result name.

## Ports

- **Input: Data** (`input`): `any`, required, single.
- **Output: Results** (`out`): `object`, optional, single.

## Inspector

- **Formulas (one per line):** key `formulas`; textarea; default: `""`; Write name = formula. Later lines can use earlier names..
- **Group: list to group (optional):** key `groupList`; text; default: `""`; Example: transactions.
- **Group: by field:** key `groupKey`; text; default: `""`; Example: category.
- **Group: field to total:** key `groupValue`; text; default: `""`; Example: amount.
- **Group: result name:** key `groupName`; text; default: `""`; Example: groups.
- **Round numbers to:** key `decimals`; select; options: ``, `0`, `1`, `2`, `3`, `4`; default: `""`.
- **calculate editor:** manages `formulas`, `groupList`, `groupKey`, `groupValue`, `groupName`, `decimals` with edit, validate, preview support.

## Behavior

- **Input requirement:** Required input ports: `input`.
- **Execution:** Handled by the handler using `calculate`.
- **Timeout:** No node-level timeout is defined.

## Cost

Uses workflow compute and may contribute to the run's compute cost.

## Security

- No credentials are used.
- The node has no external side effects.

## Retry

The runtime may retry this node according to the compiled execution policy.

## Production checklist

- Test the happy path and one malformed or empty input.
- Keep credentials out of prompts and published graph configuration.
- Set a timeout that matches the operation's side effects.
- Name the final result so a runner can tell what success looks like.
