> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Build an account statement

> Use account operations to build a clear statement view from Midaz ledger movements.

This guide explains how integrators can transform Midaz account operations into end-user account statements.

An account statement in Midaz is built from account operations. Each operation is a ledger movement linked to an account, such as a credit, debit, hold, release, or overdraft event.

To build a statement, retrieve the account operations for the period, keep the operations that affect the statement view, and transform each operation into a row that users can understand.

<Frame caption="Account balance flow">
  <img src="https://mintcdn.com/lerian-49cb71fc/S1Q0XYoydT2P-cJO/images/en/docs/account_balance_flow.jpg?fit=max&auto=format&n=S1Q0XYoydT2P-cJO&q=85&s=26c29b65971c4ff424932f3a0acfb912" alt="Account balance flow" width="1536" height="1024" data-path="images/en/docs/account_balance_flow.jpg" />
</Frame>

<Steps>
  <Step title="Retrieve account operations" titleSize="h2">
    Use the [List Operations by Account](/en/reference/midaz/list-operations-by-account) endpoint to list operations for a specific account:

    ```json theme={null}
    GET /v1/organizations/{organization_id}/ledgers/{ledger_id}/accounts/{account_id}/operations
    ```
  </Step>

  <Step title="Apply query filters" titleSize="h2">
    Use query parameters to define the statement period, control pagination, and filter the operations returned by the endpoint.

    ### Required for statement queries

    | Parameter         | Description                              |
    | ----------------- | ---------------------------------------- |
    | `start_date`      | Start date of the statement period       |
    | `end_date`        | End date of the statement period         |
    | `limit`           | Number of items per page                 |
    | `sort_order=desc` | Returns the most recent operations first |

    These fields are required for this statement use case. They define the statement window and make the result predictable for users.

    ### Required when paginating

    | Parameter | Description                                |
    | --------- | ------------------------------------------ |
    | `cursor`  | Cursor returned from the previous response |

    ### Optional filters

    | Parameter          | Description                              |
    | ------------------ | ---------------------------------------- |
    | `direction=credit` | Returns only incoming operations         |
    | `direction=debit`  | Returns only outgoing operations         |
    | `type`             | Filters by operation type                |
    | `route_id`         | Filters by the operation route ID (UUID) |
    | `route_code`       | Filters by the operation route code      |

    Supported operation types:

    | Type        | What it means                       |
    | ----------- | ----------------------------------- |
    | `CREDIT`    | Value entering the account          |
    | `DEBIT`     | Value leaving the account           |
    | `ON_HOLD`   | Amount temporarily locked           |
    | `RELEASE`   | Previously locked amount released   |
    | `OVERDRAFT` | Movement related to overdraft usage |

    Use `type` to classify the accounting movement. Use `direction` to decide whether the amount is shown as positive or negative in the statement.

    Example request:

    ```json theme={null}
    GET /v1/organizations/org_123/ledgers/ledger_001/accounts/account_456/operations?start_date=2026-05-01&end_date=2026-05-31&limit=50&sort_order=desc
    ```
  </Step>

  <Step title="Transform operations into statement entries" titleSize="h2">
    Each object returned in the `items` array can become one statement row.

    ### Required for statement rendering

    | Statement field                  | Operation field          |
    | -------------------------------- | ------------------------ |
    | Date                             | `createdAt`              |
    | Description                      | `description`            |
    | Movement type                    | `type`                   |
    | Direction                        | `direction`              |
    | Amount                           | `amount.value`           |
    | Currency or asset                | `assetCode`              |
    | Balance after operation          | `balanceAfter.available` |
    | Receipt or transaction reference | `transactionId`          |

    These fields are required to render a useful statement row. They are not all required by the API, but a statement without them loses meaning, traceability, or balance context.

    ### Recommended for user-friendly statements

    | Statement context | Operation field         |
    | ----------------- | ----------------------- |
    | Counterparty      | `metadata.counterparty` |
    | Document          | `metadata.document`     |
    | Pix key           | `metadata.pixKey`       |
    | End-to-end ID     | `metadata.endToEndId`   |
    | Channel           | `metadata.channel`      |
    | Category          | `metadata.category`     |

    Midaz returns the ledger movement. The integrating system should add business context in `metadata` when the transaction is created.

    Example transformation:

    ```json theme={null}
    {
      "date": "2026-05-18T14:23:11Z",
      "description": "Pix transfer received",
      "type": "CREDIT",
      "direction": "credit",
      "amount": "150.00",
      "asset": "BRL",
      "balanceAfter": "1240.55",
      "transactionId": "txn_987654",
      "metadata": {
        "counterparty": "John Doe",
        "pixKey": "john@example.com",
        "category": "Transfer"
      }
    }
    ```
  </Step>

  <Step title="Apply statement display rules" titleSize="h2">
    ### Use `direction` to determine the sign

    | Direction | Display behavior             |
    | --------- | ---------------------------- |
    | `credit`  | Display as a positive amount |
    | `debit`   | Display as a negative amount |

    <Warning>
      Do not use `type` to determine whether the value is positive or negative. The `type` field classifies the accounting movement, while `direction` defines whether the value enters or leaves the account.
    </Warning>

    ### Handle hold and release operations separately

    Operations with the following types should not be displayed as regular settled movements:

    * `ON_HOLD`
    * `RELEASE`

    Instead:

    * `ON_HOLD` should appear as a balance hold or temporary lock
    * `RELEASE` should appear as a balance release or unlock

    ### Display only settled operations

    For a settled statement view, include only operations where:

    ```json theme={null}
    "balanceAffected": true
    ```

    This keeps the statement focused on movements that changed the available balance.
  </Step>

  <Step title="Handle pagination" titleSize="h2">
    Responses can be paginated depending on the selected `limit`.

    To retrieve all operations:

    1. Read the `next_cursor` field from the response
    2. Send it in the next request using the `cursor` parameter
    3. Repeat until `next_cursor` is no longer returned

    Example flow:

    ```text theme={null}
    Request 1
      -> returns items + next_cursor

    Request 2
      -> cursor=next_cursor
      -> returns more items + next_cursor

    Repeat until next_cursor is null
    ```
  </Step>
</Steps>

## Example statement output

After applying filters, transforming operations, and applying display rules, the final statement can look like this:

| Date       | Description                | Amount      | Balance after |
| ---------- | -------------------------- | ----------- | ------------- |
| 2026-05-18 | Pix received from John Doe | +150.00 BRL | 1,240.55 BRL  |
| 2026-05-18 | Card purchase              | -45.90 BRL  | 1,194.65 BRL  |

The API does not return a ready-made statement page. It returns ledger events that the integrating system turns into a statement experience.

## Add business context

The operations endpoint returns accounting events. A user-facing statement needs more context than the ledger movement alone.

Send business metadata in the transaction payload when creating the transaction. Midaz stores those fields with the operation, and the statement can use them later to show who, what, and why behind the movement.

* `counterparty`
* `document`
* `pixKey`
* `endToEndId`
* `channel`
* `category`

Example metadata:

```json theme={null}
"metadata": {
  "counterparty": "John Doe",
  "document": "12345678900",
  "pixKey": "john@example.com",
  "endToEndId": "E1234567890123456789012345678901",
  "channel": "Pix",
  "category": "Transfer"
}
```

This makes it possible to display entries such as:

* "Pix received from John Doe"
* "Card purchase at Coffee Shop"
* "Transfer to Savings Account"

instead of generic accounting descriptions.

If the integrating system does not send these fields when creating the transaction, the statement still works, but it can only display the accounting data returned by the operation.

<Tip>
  Midaz keeps the ledger consistent and auditable. Business context belongs in transaction metadata, added by the integrating system.
</Tip>
