> ## 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.

# Using Reporter

> Generate dynamic, data-driven reports from your Midaz Ledger with Reporter — no SQL needed, just templates with simple placeholders.

Reporter assists Midaz Ledger users in creating dynamic, data-driven reports without SQL knowledge. You define domains, tables, and fields using simple placeholders rather than constructing complex queries.

## Typical usage

***

### Step 1 -- Create the `.tpl` file

Write a template matching your desired output format (HTML, PDF, XML, CSV, or TXT). The template should incorporate Reporter blocks and follow the appropriate syntax for your output format. See [Template examples](/en/reporter/template-examples) for guidance.

<Danger>
  The file **must** be saved with a `.tpl` extension. This is required for proper processing.
</Danger>

### Step 2 -- Upload the template

Once ready, upload the `.tpl` file using the [Upload a Template](/en/reference/reporter/upload-template) endpoint. Set the `outputFormat` field to specify the report format. The system assigns a UUID filename (for example, `0196159b-4f26-7300-b3d9-f4f68a7c85f3.tpl`).

Template management endpoints:

* [**List Templates**](/en/reference/reporter/list-templates) -- View organizational templates.
* [**Retrieve Template details**](/en/reference/reporter/retrieve-template-details) -- Access specific template information.
* [**Update a Template**](/en/reference/reporter/update-templates) -- Modify the `.tpl` file, description, or output format.
* [**Delete a Template**](/en/reference/reporter/delete-template) -- Mark templates as deleted via `deletedAt` timestamp.

### Step 3 -- Generate the report

Use the [Create a Report](/en/reference/reporter/create-report) endpoint to initiate generation. Pass a `templateId` and optional `filters` in the request body:

```json theme={null}
{
  "templateId": "0196159b-4f26-7300-b3d9-f4f68a7c85f3",
  "filters": {
    "midaz_transaction": {
      "transaction": {
        "id": { "eq": ["0196d983-a2c2-7d5a-a5b7-029fe0dcb710"] }
      }
    }
  }
}
```

The API returns a `reportId` for tracking and retrieving the output.

<Info>
  You can apply advanced filters to control which data is included in the report. Filters support operators like `eq`, `gt`, `gte`, `lt`, `lte`, `between`, `in`, and `nin`. Filters work transparently across both PostgreSQL and MongoDB data sources. See [Advanced filtering](/en/reporter/template-reference#advanced-filtering) for the full reference and examples.
</Info>

### Step 4 -- Check the report status

The [Check Report Status](/en/reference/reporter/check-report-status) endpoint monitors progress. Possible status values are:

* `Processing` -- The report is being generated.
* `Finished` -- The report is ready for download.
* `Error` -- An error occurred during generation.
* `PendingExtraction` -- The report is waiting for data extraction to complete.

### Step 5 -- Download the report

Once the status is `Finished`, download the report using the [Download a Report](/en/reference/reporter/download-report) endpoint. The file appears in the response body with proper `Content-Disposition` headers.

## Mapping data sources for dynamic filters

***

Two supporting endpoints enable dynamic filtering:

* [**List Data Sources**](/en/reference/reporter/list-data-sources) -- Lists available data sources with their schemas and tables.
* [**Retrieve a Data Source by id**](/en/reference/reporter/retrieve-data-source) -- Returns the schema for a specific data source, including tables and fields.

<Note>
  These endpoints are optional and designed for advanced use cases, like building custom UIs or automating report workflows based on schema data.
</Note>

## Configuring storage

***

Reporter stores templates and generated reports in S3-compatible object storage (cloud file storage). It supports AWS S3, MinIO, and SeaweedFS out of the box.

All files are stored in a single bucket with internal prefixes:

* `templates/` -- for uploaded template files
* `reports/` -- for generated report files

### Storage environment variables

| Variable                        | Description                                               | Default            |
| ------------------------------- | --------------------------------------------------------- | ------------------ |
| `OBJECT_STORAGE_ENDPOINT`       | S3-compatible endpoint URL. Leave empty for AWS S3.       | --                 |
| `OBJECT_STORAGE_REGION`         | AWS region                                                | `us-east-1`        |
| `OBJECT_STORAGE_ACCESS_KEY_ID`  | Access key for authentication                             | --                 |
| `OBJECT_STORAGE_SECRET_KEY`     | Secret key for authentication                             | --                 |
| `OBJECT_STORAGE_USE_PATH_STYLE` | Use path-style URLs. Required for MinIO and SeaweedFS.    | `false`            |
| `OBJECT_STORAGE_DISABLE_SSL`    | Disable SSL verification. Use for local development only. | `false`            |
| `OBJECT_STORAGE_BUCKET`         | Bucket name                                               | `reporter-storage` |

### Configuration examples by provider

<Accordion title="AWS S3">
  ```env theme={null}
  OBJECT_STORAGE_ENDPOINT=
  OBJECT_STORAGE_REGION=us-west-2
  OBJECT_STORAGE_ACCESS_KEY_ID=AKIA...
  OBJECT_STORAGE_SECRET_KEY=your-secret-key
  OBJECT_STORAGE_USE_PATH_STYLE=false
  OBJECT_STORAGE_DISABLE_SSL=false
  OBJECT_STORAGE_BUCKET=reporter-prod-bucket
  ```
</Accordion>

<Accordion title="MinIO">
  ```env theme={null}
  OBJECT_STORAGE_ENDPOINT=http://minio:9000
  OBJECT_STORAGE_REGION=us-east-1
  OBJECT_STORAGE_ACCESS_KEY_ID=minioadmin
  OBJECT_STORAGE_SECRET_KEY=minioadmin
  OBJECT_STORAGE_USE_PATH_STYLE=true
  OBJECT_STORAGE_DISABLE_SSL=true
  OBJECT_STORAGE_BUCKET=reporter-storage
  ```
</Accordion>

<Accordion title="SeaweedFS (local development)">
  ```env theme={null}
  OBJECT_STORAGE_ENDPOINT=http://reporter-seaweedfs:8333
  OBJECT_STORAGE_REGION=us-east-1
  OBJECT_STORAGE_ACCESS_KEY_ID=any
  OBJECT_STORAGE_SECRET_KEY=any
  OBJECT_STORAGE_USE_PATH_STYLE=true
  OBJECT_STORAGE_DISABLE_SSL=true
  OBJECT_STORAGE_BUCKET=reporter-storage
  ```
</Accordion>

<Note>
  S3 does not support per-object TTL. To automatically expire generated reports, configure [S3 bucket lifecycle policies](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html) on your bucket.
</Note>

## Configuring external data sources

***

Reporter connects to external databases (PostgreSQL and MongoDB) as data sources for your templates. You can configure data sources in two ways:

* **Via environment variables** -- Using the `DATASOURCE_<NAME>_*` pattern described below. Ideal for infrastructure-as-code setups and static configurations.
* **Via the connections API** -- Using the [database connections API](/en/reference/reporter/connections/create-connection) to dynamically register, test, and manage connections. Ideal for scenarios where connections change frequently or are managed through a UI.

### Environment variable configuration

Each data source is configured through environment variables following the pattern `DATASOURCE_<NAME>_*`.

### Data source environment variables

| Variable                        | Description                                                                                                                                                                              | Required        |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- |
| `DATASOURCE_<NAME>_CONFIG_NAME` | Unique identifier used in templates (for example, `midaz_onboarding`)                                                                                                                    | Yes             |
| `DATASOURCE_<NAME>_HOST`        | Database host                                                                                                                                                                            | Yes             |
| `DATASOURCE_<NAME>_PORT`        | Database port                                                                                                                                                                            | Yes             |
| `DATASOURCE_<NAME>_USER`        | Database user                                                                                                                                                                            | Yes             |
| `DATASOURCE_<NAME>_PASSWORD`    | Database password                                                                                                                                                                        | Yes             |
| `DATASOURCE_<NAME>_DATABASE`    | Database name                                                                                                                                                                            | Yes             |
| `DATASOURCE_<NAME>_TYPE`        | Database type: `postgresql` or `mongodb` (lowercase). Note: the [connections API](/en/reference/reporter/connections/create-connection) uses uppercase values (`POSTGRESQL`, `MONGODB`). | Yes             |
| `DATASOURCE_<NAME>_SSLMODE`     | SSL mode for PostgreSQL (`disable`, `require`)                                                                                                                                           | PostgreSQL only |
| `DATASOURCE_<NAME>_SSLROOTCERT` | SSL root certificate path for PostgreSQL                                                                                                                                                 | PostgreSQL only |
| `DATASOURCE_<NAME>_SSL`         | Enable SSL for MongoDB (`true` or `false`)                                                                                                                                               | MongoDB only    |
| `DATASOURCE_<NAME>_SSLCA`       | CA certificate file path for MongoDB                                                                                                                                                     | MongoDB only    |
| `DATASOURCE_<NAME>_OPTIONS`     | Additional URI options for MongoDB                                                                                                                                                       | MongoDB only    |
| `DATASOURCE_<NAME>_SCHEMAS`     | Comma-separated list of schemas to expose                                                                                                                                                | PostgreSQL only |

### Single data source example

```env theme={null}
DATASOURCE_ONBOARDING_CONFIG_NAME=midaz_onboarding
DATASOURCE_ONBOARDING_HOST=midaz-postgres-replica
DATASOURCE_ONBOARDING_PORT=5702
DATASOURCE_ONBOARDING_USER=midaz
DATASOURCE_ONBOARDING_PASSWORD=lerian
DATASOURCE_ONBOARDING_DATABASE=onboarding
DATASOURCE_ONBOARDING_TYPE=postgresql
DATASOURCE_ONBOARDING_SSLMODE=disable
```

In templates, you reference this data source as `midaz_onboarding`:

```
{% for account in midaz_onboarding.account %}
  {{ account.id }} - {{ account.name }}
{% endfor %}
```

### Multi-schema data source

To query tables across multiple PostgreSQL schemas, set the `DATASOURCE_<NAME>_SCHEMAS` variable with a comma-separated list:

```env theme={null}
DATASOURCE_EXTERNAL_CONFIG_NAME=external_db
DATASOURCE_EXTERNAL_HOST=external-postgres
DATASOURCE_EXTERNAL_PORT=5432
DATASOURCE_EXTERNAL_USER=db_user
DATASOURCE_EXTERNAL_PASSWORD=db_password
DATASOURCE_EXTERNAL_DATABASE=external_database
DATASOURCE_EXTERNAL_TYPE=postgresql
DATASOURCE_EXTERNAL_SSLMODE=disable
DATASOURCE_EXTERNAL_SCHEMAS=sales,inventory,reporting
```

In templates, use the explicit schema syntax `database:schema.table`:

```
{% for order in external_db:sales.orders %}
  {{ order.id }} - {{ order.total }}

  {% for item in external_db:inventory.items|where:"order_id:{{ order.id }}" %}
    Item: {{ item.name }} ({{ item.quantity }} in stock)
  {% endfor %}
{% endfor %}
```

When generating a report with filters, use `schema.table` as the table key:

```json theme={null}
{
  "templateId": "00000000-0000-0000-0000-000000000000",
  "filters": {
    "external_db": {
      "sales.orders": {
        "created_at": { "gte": ["2025-01-01"] }
      }
    }
  }
}
```

<Info>
  When `DATASOURCE_<NAME>_SCHEMAS` is not set, Reporter defaults to the `public` schema only.
</Info>

### Connection behavior

Reporter uses two initialization strategies:

* **Manager component (lazy):** Loads configuration without connecting. Connects on-demand when a template references the data source. This provides faster startup.
* **Worker component (eager):** Attempts connection on startup with retries at increasing intervals (up to 5 attempts). Continues with degraded functionality if a data source is unavailable.

## Complete environment variables reference

***

### Application

| Variable         | Description                                  | Default       |
| ---------------- | -------------------------------------------- | ------------- |
| `ENV_NAME`       | Environment name                             | `development` |
| `LOG_LEVEL`      | Log level (`debug`, `info`, `warn`, `error`) | `debug`       |
| `SERVER_PORT`    | Manager HTTP port                            | `4005`        |
| `SERVER_ADDRESS` | Manager bind address                         | `:4005`       |

### Object storage (S3-compatible)

| Variable                        | Description     | Default            |
| ------------------------------- | --------------- | ------------------ |
| `OBJECT_STORAGE_ENDPOINT`       | S3 endpoint URL | --                 |
| `OBJECT_STORAGE_REGION`         | AWS region      | `us-east-1`        |
| `OBJECT_STORAGE_ACCESS_KEY_ID`  | Access key      | --                 |
| `OBJECT_STORAGE_SECRET_KEY`     | Secret key      | --                 |
| `OBJECT_STORAGE_USE_PATH_STYLE` | Path-style URLs | `false`            |
| `OBJECT_STORAGE_DISABLE_SSL`    | Disable SSL     | `false`            |
| `OBJECT_STORAGE_BUCKET`         | Bucket name     | `reporter-storage` |

### MongoDB

| Variable              | Description                             | Default |
| --------------------- | --------------------------------------- | ------- |
| `MONGO_URI`           | URI scheme (`mongodb` or `mongodb+srv`) | --      |
| `MONGO_HOST`          | MongoDB host                            | --      |
| `MONGO_NAME`          | Database name                           | --      |
| `MONGO_USER`          | Database user                           | --      |
| `MONGO_PASSWORD`      | Database password                       | --      |
| `MONGO_PORT`          | Database port                           | --      |
| `MONGO_MAX_POOL_SIZE` | Connection pool size                    | `1000`  |
| `MONGO_PARAMETERS`    | Additional URI parameters               | --      |

### RabbitMQ

| Variable                         | Description                              | Default |
| -------------------------------- | ---------------------------------------- | ------- |
| `RABBITMQ_URI`                   | URI scheme (`amqp`)                      | --      |
| `RABBITMQ_HOST`                  | RabbitMQ host                            | --      |
| `RABBITMQ_PORT_AMQP`             | AMQP port                                | --      |
| `RABBITMQ_PORT_HOST`             | Management port                          | --      |
| `RABBITMQ_DEFAULT_USER`          | User                                     | --      |
| `RABBITMQ_DEFAULT_PASS`          | Password                                 | --      |
| `RABBITMQ_GENERATE_REPORT_QUEUE` | Queue name for report generation         | --      |
| `RABBITMQ_NUMBERS_OF_WORKERS`    | Number of consumer workers (worker only) | `5`     |

### Redis / Valkey

| Variable            | Description                                     | Default |
| ------------------- | ----------------------------------------------- | ------- |
| `REDIS_HOST`        | Redis host with port (for example, `host:6379`) | --      |
| `REDIS_PASSWORD`    | Redis password                                  | --      |
| `REDIS_DB`          | Database number                                 | `0`     |
| `REDIS_PROTOCOL`    | Redis protocol version                          | `3`     |
| `REDIS_MASTER_NAME` | Sentinel master name (if using Sentinel)        | --      |
| `REDIS_TLS`         | Enable TLS                                      | `false` |

### PDF generation (worker only)

| Variable              | Description                               | Default |
| --------------------- | ----------------------------------------- | ------- |
| `PDF_POOL_WORKERS`    | Number of parallel PDF generation workers | `2`     |
| `PDF_TIMEOUT_SECONDS` | Timeout per PDF generation in seconds     | `90`    |

### Telemetry (OpenTelemetry)

| Variable                               | Description                  | Default |
| -------------------------------------- | ---------------------------- | ------- |
| `OTEL_RESOURCE_SERVICE_NAME`           | Service name for traces      | --      |
| `OTEL_LIBRARY_NAME`                    | Instrumentation library name | --      |
| `OTEL_RESOURCE_SERVICE_VERSION`        | Service version              | --      |
| `OTEL_RESOURCE_DEPLOYMENT_ENVIRONMENT` | Deployment environment       | --      |
| `OTEL_EXPORTER_OTLP_ENDPOINT`          | OTLP exporter endpoint       | --      |
| `ENABLE_TELEMETRY`                     | Enable telemetry collection  | `false` |

### Authentication

| Variable              | Description           | Default |
| --------------------- | --------------------- | ------- |
| `PLUGIN_AUTH_ADDRESS` | Auth service URL      | --      |
| `PLUGIN_AUTH_ENABLED` | Enable authentication | `false` |

### License

| Variable           | Description                             | Default |
| ------------------ | --------------------------------------- | ------- |
| `LICENSE_KEY`      | License key for Reporter                | --      |
| `ORGANIZATION_IDS` | Organization IDs for license validation | --      |
