---
title: "Execute a prepared query"
method: POST
path: "/v3/{ledgerName}/prepared-queries/{queryName}/execute"
tags: ["Prepared Queries"]
---

# Execute a prepared query

`POST /v3/{ledgerName}/prepared-queries/{queryName}/execute`

## Request

- Base URL: `http://localhost:9000`
- URL: `http://localhost:9000/v3/{ledgerName}/prepared-queries/{queryName}/execute`
- Auth: one of:
  - HTTP bearer
  - none

Executes a prepared query with optional parameter substitution. Supports LIST and
AGGREGATE_VOLUMES modes. LIST uses cursor pagination with an effective page size
of 100 when omitted or zero, capped at 1000 before collecting and enriching rows.
AGGREGATE_VOLUMES ignores pageSize and aggregates all matching accounts. Also
accepts pageSize, cursor and reverse as query parameters. Supplied pageSize and
reverse values, and nonempty cursor values, override the body. Requires `ledger:ReadQuery` scope.

## Path parameters

- `ledgerName` string, required
- `queryName` string, required

## Query parameters

- `pageSize` integer
- `cursor` string: Page token of a paged list. Clients normally pass back the `next` or `previous` value of a previous response verbatim; building one by hand is supported. A token is base64url (unpadded, RFC 4648 §5) of the JSON object `{"key": <string>, "back": <bool>}`. Both fields are omitted when empty, and unknown fields are rejected. `key` is a position in the endpoint's textual form: - transactions: decimal transaction id - logs: decimal ledger-local log id - audit entries: decimal audit sequence - accounts: address - ledgers and numscripts: name - signing keys: key id - prepared queries: decimal id for TRANSACTIONS and LOGS targets, address for ACCOUNTS - index inspection: base64url of the encoded metadata value Both directions exclude the key and return rows in the requested order (`reverse` included): - `{"key": K}` serves the rows strictly after K; - `{"key": K, "back": true}` serves the page that ends strictly before K; - `{"back": true}` serves the last page; - an absent or empty token, or `e30` (`{}`), serves the first page. On a forward page, `next` is set when a further row follows the page, and `previous` whenever the request carried a key. On a back page, `previous` is set when a further row precedes the page, and `next` whenever the request carried a key. A first page therefore has no `previous`, and the last page requested with `{"back": true}` has no `next`. A malformed token, or a key that is not a valid position for the endpoint, is rejected with 400 `INVALID_REQUEST`.
- `reverse` boolean

## Headers

- `X-Consistency` 'linearizable' | 'stale'
- `Formance-Bigint-As-String` string
- `X-Query-Profile` string

## Request body

- ExecutePreparedQueryRequest
  - `parameters` object: Parameter values for the query (substituted into filter placeholders)
  - `pageSize` integer: LIST page size. Omitted or zero means 100. The effective maximum is 1000; larger uint32 values are accepted and clamped, not rejected. A supplied query parameter overrides this value. Ignored for AGGREGATE_VOLUMES.
  - `cursor` string: Page token from a previous response's `cursor.next` or `cursor.previous` (see the `PageToken` schema). The key is the decimal id for TRANSACTIONS and LOGS targets, the address for ACCOUNTS.
  - `mode` 'LIST' | 'AGGREGATE_VOLUMES': Execution mode (default LIST)
  - `reverse` boolean: List in descending entity order (address, transaction id or log id). A page token is relative to the requested order, so every page of a descending walk must set `reverse`. Rejected with 400 in `AGGREGATE_VOLUMES` mode.

## Response `200`

Query executed successfully

- ExecutePreparedQueryResponse: Result of executing a prepared query. Exactly one field is set, discriminated by the request execution `mode` (see `ExecutePreparedQueryRequest.mode`): `mode=LIST` returns `cursor`, `mode=AGGREGATE_VOLUMES` returns `aggregateResult`. (The query `target` — ACCOUNTS, TRANSACTIONS or LOGS — selects the row type inside the cursor, not which envelope field is set: `accountData`, `transactionData` or `logData` respectively. LOGS is a usable prepared-query target: `query.Execute` hydrates `logData` for it.) Both payloads use the same camelCase encoding as the equivalent non-prepared endpoints (header-negotiated monetary amounts, `color` always present on every volume row including the uncolored bucket).
  - `cursor` object: Paged cursor, returned when the request `mode` is `LIST`. The row type follows the query `target`: `accountData` for ACCOUNTS, `transactionData` for TRANSACTIONS, `logData` for LOGS. Rows use the same camelCase shapes as the non-prepared list endpoints.
    - `pageSize` integer: Effective LIST page size after applying the default and cap.
    - `hasMore` boolean: True when a following page exists; set iff `next` is.
    - `next` string: Page token of a paged list. Clients normally pass back the `next` or `previous` value of a previous response verbatim; building one by hand is supported. A token is base64url (unpadded, RFC 4648 §5) of the JSON object `{"key": <string>, "back": <bool>}`. Both fields are omitted when empty, and unknown fields are rejected. `key` is a position in the endpoint's textual form: - transactions: decimal transaction id - logs: decimal ledger-local log id - audit entries: decimal audit sequence - accounts: address - ledgers and numscripts: name - signing keys: key id - prepared queries: decimal id for TRANSACTIONS and LOGS targets, address for ACCOUNTS - index inspection: base64url of the encoded metadata value Both directions exclude the key and return rows in the requested order (`reverse` included): - `{"key": K}` serves the rows strictly after K; - `{"key": K, "back": true}` serves the page that ends strictly before K; - `{"back": true}` serves the last page; - an absent or empty token, or `e30` (`{}`), serves the first page. On a forward page, `next` is set when a further row follows the page, and `previous` whenever the request carried a key. On a back page, `previous` is set when a further row precedes the page, and `next` whenever the request carried a key. A first page therefore has no `previous`, and the last page requested with `{"back": true}` has no `next`. A malformed token, or a key that is not a valid position for the endpoint, is rejected with 400 `INVALID_REQUEST`.
    - `previous` string: Page token of a paged list. Clients normally pass back the `next` or `previous` value of a previous response verbatim; building one by hand is supported. A token is base64url (unpadded, RFC 4648 §5) of the JSON object `{"key": <string>, "back": <bool>}`. Both fields are omitted when empty, and unknown fields are rejected. `key` is a position in the endpoint's textual form: - transactions: decimal transaction id - logs: decimal ledger-local log id - audit entries: decimal audit sequence - accounts: address - ledgers and numscripts: name - signing keys: key id - prepared queries: decimal id for TRANSACTIONS and LOGS targets, address for ACCOUNTS - index inspection: base64url of the encoded metadata value Both directions exclude the key and return rows in the requested order (`reverse` included): - `{"key": K}` serves the rows strictly after K; - `{"key": K, "back": true}` serves the page that ends strictly before K; - `{"back": true}` serves the last page; - an absent or empty token, or `e30` (`{}`), serves the first page. On a forward page, `next` is set when a further row follows the page, and `previous` whenever the request carried a key. On a back page, `previous` is set when a further row precedes the page, and `next` whenever the request carried a key. A first page therefore has no `previous`, and the last page requested with `{"back": true}` has no `next`. A malformed token, or a key that is not a valid position for the endpoint, is rejected with 400 `INVALID_REQUEST`.
    - `accountData` Account[]
      - `address` string, required: Account address
      - `metadata` object: Account metadata (typed values)
      - `volumes` AccountVolume[]: Account volumes listed per (asset, color). Sorted by (asset, color) ascending for stable serialization. The empty color is the uncolored bucket; colored buckets are strictly isolated. Use the `collapseColors=true` query parameter on GET /accounts to sum every colored bucket of the same asset into a single uncolored entry.
        - `asset` string, required: Asset identifier (e.g. "USD/2")
        - `color` string, required: Color of the bucket. Empty string is the uncolored bucket.
        - `volumes` VolumesWithBalance, required
          - `input` union, required: Arbitrary-precision unsigned BigUint value encoded as a JSON number by default, or a canonical decimal string when Formance-Bigint-As-String is enabled. The same rule applies to every response BigUint value, including nested fields, regardless of business meaning. JavaScript consumers should enable the header to avoid number rounding.
            - integer
            - string
          - `output` union, required: Arbitrary-precision unsigned BigUint value encoded as a JSON number by default, or a canonical decimal string when Formance-Bigint-As-String is enabled. The same rule applies to every response BigUint value, including nested fields, regardless of business meaning. JavaScript consumers should enable the header to avoid number rounding.
            - integer
            - string
          - `balance` union, required: Arbitrary-precision SignedBigInt value encoded as a JSON number by default, or a canonical decimal string when Formance-Bigint-As-String is enabled. The same rule applies to every response SignedBigInt value, including nested fields, regardless of business meaning.
            - integer
            - string
    - `transactionData` TransactionResponse[]
      - `postings` PostingResponse[], required
        - `source` string, required
        - `destination` string, required
        - `amount` union, required: Unsigned amount from 0 through 2^256-1. Requests accept JSON integer tokens or canonical decimal strings independently of the response header; the server enforces the bound for both forms. Responses use numbers by default and strings with Formance-Bigint-As-String enabled, as do all response Uint256 values regardless of business meaning.
          - integer
          - string
        - `asset` string, required
        - `color` string, required: Segregation key for "color of money". The empty string means the uncolored bucket. Always present on responses (never omitted); two postings on the same (account, asset) but different colors operate on strictly isolated balances.
      - `metadata` object, required
      - `timestamp` string, date-time: Transaction timestamp (ISO 8601 format)
      - `reference` string
      - `id` integer, required: Transaction ID (assigned by the system)
      - `reverted` boolean, required: Whether this transaction has been reverted
      - `insertedAt` string, date-time: When the transaction was inserted into the ledger
      - `updatedAt` string, date-time: Last update timestamp
      - `revertedAt` string, date-time, nullable: When the transaction was reverted (null if not reverted)
      - `revertedByTransactionId` integer: ID of the transaction that reverted this one (absent when not reverted)
      - `revertsTransactionId` integer: ID of the original transaction this transaction reverts (absent when this is not a revert)
      - `postCommitVolumes` PostCommitVolumes: Post-commit volumes, keyed by account address. Each account maps to a flat array of per-(asset, color) volume tuples. The wire is a plain `{"addr": [{asset, color, input, output}]}` map — the proto `volumesByAccount` / `volumes` wrappers are flattened away by `PostCommitVolumes.MarshalJSON`. This replaces the pre-color `{"addr": {"asset": Volumes}}` map shape, which can no longer key a bucket uniquely once a color dimension exists.
    - `logData` SystemLog[]
      - `sequence` integer
      - `payload` object: Named system payload variants are preserved as supplied, including nested fields and future sibling variants. Only apply is typed here; other variants remain open-ended (EN-2781).
        - `apply` object
          - `ledgerName` string
          - `log` LedgerLog: Ledger-local log. The type selects the direct object in data, following the v2 type/data structure; data has no variant-name wrapper. New v3 operations have distinct type values. Metadata remains typed, volumes retain colors, and reversals contain the original transaction ID and the reversing transaction rather than the full original transaction. This JSON projection is not an audit replay or backup format.
            - `type` 'NEW_TRANSACTION' | 'REVERTED_TRANSACTION' | 'SET_METADATA' | 'DELETE_METADATA' | 'SET_METADATA_FIELD_TYPE' | 'REMOVED_METADATA_FIELD_TYPE' | 'ORDER_SKIPPED' | 'FILL_GAP' | 'CREATE_INDEX' | 'DROP_INDEX' | 'ADDED_ACCOUNT_TYPE' | 'REMOVED_ACCOUNT_TYPE' | 'UPDATED_DEFAULT_ENFORCEMENT_MODE', required
            - `data` object, required: Direct operation payload selected by type. NEW_TRANSACTION contains transaction and optional accountMetadata. REVERTED_TRANSACTION contains revertedTransactionId and revertTransaction. SET_METADATA and DELETE_METADATA contain targetType (ACCOUNT or TRANSACTION) and targetId: an account-address string or an unsigned 64-bit transaction integer, including zero. SET_METADATA also contains metadata; DELETE_METADATA contains key. ORDER_SKIPPED contains reason and optional context. Other types carry the fields of their corresponding operation directly. FILL_GAP contains originalId, a uint64 encoded as a decimal JSON string by protobuf JSON. Transaction IDs, revertedTransactionId and transaction targetId are JSON numbers; consumers must preserve full integer precision. Metadata integers are JSON numbers and null-valued keys are preserved.
            - `date` string, date-time
            - `id` integer: Ledger-local log ID; omitted when zero.
      - `responseSignature` object
  - `aggregateResult` AggregateVolumesData
    - `volumes` AggregatedVolume[], required: Flat aggregated volumes per asset
      - `asset` string, required: Asset identifier (e.g. "USD/2")
      - `color` string, required: Color of the aggregated bucket. By default the response contains one AggregatedVolume per (asset, color) tuple. With `collapseColors=true`, every colored bucket of the same (asset, precision) is summed and the resulting entry carries color = "".
      - `input` union, required: Arbitrary-precision unsigned BigUint value encoded as a JSON number by default, or a canonical decimal string when Formance-Bigint-As-String is enabled. The same rule applies to every response BigUint value, including nested fields, regardless of business meaning. JavaScript consumers should enable the header to avoid number rounding.
        - integer
        - string
      - `output` union, required: Arbitrary-precision unsigned BigUint value encoded as a JSON number by default, or a canonical decimal string when Formance-Bigint-As-String is enabled. The same rule applies to every response BigUint value, including nested fields, regardless of business meaning. JavaScript consumers should enable the header to avoid number rounding.
        - integer
        - string
      - `balance` union, required: Arbitrary-precision SignedBigInt value encoded as a JSON number by default, or a canonical decimal string when Formance-Bigint-As-String is enabled. The same rule applies to every response SignedBigInt value, including nested fields, regardless of business meaning.
        - integer
        - string
    - `groups` GroupedAggregateResult[]: Per-prefix aggregated volumes (present when groupByPrefixes is set)
      - `prefix` string, required: Account prefix this group matches
      - `volumes` AggregatedVolume[], required: Aggregated volumes for accounts matching this prefix
        - `asset` string, required: Asset identifier (e.g. "USD/2")
        - `color` string, required: Color of the aggregated bucket. By default the response contains one AggregatedVolume per (asset, color) tuple. With `collapseColors=true`, every colored bucket of the same (asset, precision) is summed and the resulting entry carries color = "".
        - `input` union, required: Arbitrary-precision unsigned BigUint value encoded as a JSON number by default, or a canonical decimal string when Formance-Bigint-As-String is enabled. The same rule applies to every response BigUint value, including nested fields, regardless of business meaning. JavaScript consumers should enable the header to avoid number rounding.
          - integer
          - string
        - `output` union, required: Arbitrary-precision unsigned BigUint value encoded as a JSON number by default, or a canonical decimal string when Formance-Bigint-As-String is enabled. The same rule applies to every response BigUint value, including nested fields, regardless of business meaning. JavaScript consumers should enable the header to avoid number rounding.
          - integer
          - string
        - `balance` union, required: Arbitrary-precision SignedBigInt value encoded as a JSON number by default, or a canonical decimal string when Formance-Bigint-As-String is enabled. The same rule applies to every response SignedBigInt value, including nested fields, regardless of business meaning.
          - integer
          - string

## Other responses

- `400`: Bad request
- `401`: Authentication required (missing or invalid JWT token)
- `403`: Insufficient permissions (missing required scope)
- `404`: Not found
- `405`: Method not allowed
- `500`: Internal server error
- `503`: Service unavailable — the server cannot serve the request right now but an immediate retry can succeed. The `errorCode` field discriminates the cause: `NO_LEADER` (no elected Raft leader), `CACHE_HORIZON_EXCEEDED` (admission snapshot too old, retry against a fresh one), `UNAVAILABLE` (an internal forwarded stream was torn down mid-transfer), or the reason of any domain error of the unavailable kind (e.g. `INDEX_BUILDING`).

## Changes

- **2026-11-03** `f5e817eca038`: 1 info
  - api operation id `executePreparedQuery` removed and replaced with `v3ExecutePreparedQuery`
- **2026-10-19** `2a7ea687c691`: 2 breaking, 4 warning, 1 info
  - for the `query` request parameter `pageSize`, default value `100` was added
  - the `pageSize` request property format changed from `int32` to `uint32`
  - for the `query` request parameter `pageSize`, the max was set to `4294967295.00`
  - for the `query` request parameter `pageSize`, the min was set to `0.00`
  - …3 more
- **2026-10-09** `0ed18e459f51`: 12 breaking, 12 info
  - response property `aggregateResult/groups/items/volumes/items/balance` list-of-types was widened by adding types `integer` to media type `application/json` of response `200`
  - response property `aggregateResult/groups/items/volumes/items/input` list-of-types was widened by adding types `integer` to media type `application/json` of response `200`
  - response property `aggregateResult/groups/items/volumes/items/output` list-of-types was widened by adding types `integer` to media type `application/json` of response `200`
  - response property `aggregateResult/volumes/items/balance` list-of-types was widened by adding types `integer` to media type `application/json` of response `200`
  - …20 more
- **2026-10-08** `3da23d327316`: 2 info
  - added the media type `text/plain` for the response with the status `401`
  - added the media type `text/plain` for the response with the status `403`
- …earlier changes not shown

[Operation history](https://skmtc.dev/formancehq/apis/ledger-api/changes/v3/:ledgerName/prepared-queries/:queryName/execute/post.md)

---

[API](https://skmtc.dev/formancehq/apis/ledger-api.md) - [All operations](https://skmtc.dev/formancehq/apis/ledger-api/llms.txt) - [OpenAPI document](https://skmtc.dev/formancehq/apis/ledger-api/revisions/f5e817eca038?raw)
