Explanations

About Reports

Learn how Reporting works in Minka Ledger

Introduction

Most of the time when building any kind of payment system, the need for reporting quickly comes up, from simple data exports to complex pivot reports. Ledger has a very lightweight abstraction to facilitate report generation of all kinds.

In Ledger individual report executions are represented by a Report record and report types, e.g., reconciliaton, billing and similar are represented by Schemas for Report records.

Report definition

A report Schema defines the names and types of Report parameters as well as any labels necessary to properly display the report in Studio. For more information on Ledger Schemas, see About Ledger Schemas.

Here is an example report Schema:

{
  "hash": "...",
  "data": {
    "parent": "...",
    "handle": "reconciliation",
    "format": "json-schema",
    "record": "report",
    "schema": {
      "description": "Create Ledger reconciliaton report",
      "title": "Reconciliation",
      "type": "object",
      "required": [
        "custom"
      ],
      "properties": {
        "custom": {
          "additionalProperties": false,
          "title": "",
          "type": "object",
          "required": [
            "start_timestamp",
            "end_timestamp"
          ],
          "properties": {
            "start_timestamp": {
              "title": "Reporting start date and time",
              "type": "string",
              "format": "date-time"
            },
            "end_timestamp": {
              "title": "Reporting end date and time",
              "type": "string",
              "format": "date-time"
            }
          }
        }
      }
    },
  },
  "luid": "$sch.-0kjMv1yLfRKiGqo8",
  "meta": {
    "proofs": [ ... ],
    "status": "created",
    "moment": "2025-08-01T08:36:54.008Z",
    "owners": [
      "..."
    ]
  }
}

In this example, reconciliation reports are defined to have two parameters, start_timestamp and end_timestamp, both of which are of date-time type.

Here is an example of a corresponding Report record:

{
  "hash": "...",
  "data": {
    "handle": "029O8tbnLJm3TSTNY",
    "schema": "reconciliation",
    "custom": {
      "end_timestamp": "2025-08-31T00:00:00.000Z",
      "start_timestamp": "2025-08-01T00:00:00.000Z"
    },
  },
  "luid": "$rep.-0tGKbPbcL1aN6Brj",
  "meta": {
    "proofs": [ ... ],
    "status": "completed",
    "moment": "2025-08-26T10:19:17.188Z",
    "owners": [
      "..."
    ],
    "assets": [
      {
        "handle": "reconciliation.csv",
        "output": "gs:/-reports-stg/ledgers/example-ledger/schemas/reconciliation/reports/$rep.-0tGKbPbcL1aN6Brj/assets/reconciliation.csv"
      }
    ]
  }
}

Report parameters are contained in data.custom properties and validated using the definition from the Schema. Creating this Report record will generate a reconciliation report from 2025-08-01T00:00:00.000Z to 2025-08-31T00:00:00.000Z.

Storage

The actual reports are stored in files located in a Google Cloud Storage bucket linked to individual ledger instances. These files are referenced from reports in the meta.assets field.

The assets field contains a list of assets each of which represents a file and contains a handle and an output. The handle is used to reference the file and corresponds to the filename and the output contains the location of the file. In the example above reconciliation.csv is the file name and gs:/-reports-stg/ledgers/example-ledger/schemas/reconciliation/reports/$rep.-0tGKbPbcL1aN6Brj/assets/reconciliation.csv is the file location in GCS.

The location path is generated by using Report data and is created by filling out the following template: gs://{bucket}/ledgers/{ledger-handle}/domains/{report-domain}/schemas/{report-schema}/reports/{report-luid}/assets/{asset-handle} where the domain is optional and depends on the report being inside a domain.

Report generation

Report generation is done in a series of steps. During this, the report status will be updated a few times, depending on the current step.

  1. A Report record is created.

Usually this is done by the user through Studio or CLI. It can also be done on a schedule automatically. At this point the report will be in the created status.

  1. A reporting bridge is notified of report creation (see below for configuration).

An Event is sent to a bridge registered to handle creation of the specific report. The bridge should be registered to receive report-created Signals by creating an Effect record. For more details on Effects, Signals and Events see Extending Ledger.

  1. Report creation starts and Ledger is notified.

The bridge will send a pending proof to ledger to notify it that Report creation has begun which will change the report status to pending.

  1. The Report is generated.

The bridge will generate the report using the data at it's disposal.

  1. Report is saved to GCS.

After report completion, it is saved to Google Cloud Storage by the reporting bridge.

  1. Asset references are saved to Ledger.

Finally, the reporting bridge will save asset references to Ledger by sending a completed proof containing the assets. This will change the report status to completed and update the meta.assets field as well.

At this point a user can download or preview the report.

In case of issues generating a report, the bridge will send a rejected proof to Ledger instead which may also contain details about the error.

Ledger Report Generation

Overview of report types

Ledger provides a few built-in reports that are available to all ledgers through the BigQuery Reporting Bridge (BQRB). These reports include:

  • Ledger Movements
  • Transaction details
  • Ledger Participants

To set up the BQRB, check out How to set up BigQuery Reporting Bridge , and if you want to enable the reports above, follow How to enable BQRB reports.

Besides these reports, custom reports are possible in BQRB that can be built by the Ledger team.

If you want to build reports yourself, you can do that either by using a dedicated BQRB instance or by building your own reporting bridge that follows the protocol described above.