Skip to main content

Lerian APIs


This section answers common questions about Lerian’s APIs. It covers general behavior, configuration, and best practices across all services.
Yes. The default maximum is 100 records per page. This limit keeps performance consistent and controls the data volume in each request. To raise it, set the MAX_PAGINATION_LIMIT environment variable in your deployment configuration. The API accepts larger page sizes after you restart the application.Important: A larger page size can slow response times, especially with large datasets. Test in staging before you change production.

Multi-tenancy and SaaS


These questions cover data isolation, tenant scoping, and how multi-tenancy works in Lerian deployments.
Yes. Every tenant operates on a separate database. The platform resolves your tenant from the JWT on every request and routes it to your isolated database. There is no way to access another tenant’s data through the API. Learn more about multi-tenancy.
No. The JWT access token you receive during authentication carries your tenant context. The platform resolves it automatically. You do not need to include a tenant identifier in headers or request bodies.
Yes. A tenant can contain multiple Organizations. Each Organization has its own Ledgers, accounts, and transactions. The platform scopes all of them to your tenant automatically.
No. The API surface is identical: same endpoints, same payloads, same responses. Only one thing differs. SaaS requires authentication on every request, and your token scopes all operations to your tenant.

Midaz


These questions cover Organizations, Ledgers, Accounts, Transactions, and more in Midaz.

Organizations

No. Each Organization operates independently and does not communicate with others.
No. Each license binds to one Organization. To support multiple Organizations, acquire a separate license for each. The same rule applies to Plugins.
Yes. An Organization can have more than one Plugin.
Yes. An Organization can manage multiple Ledgers.
You can create a Parent Organization and a Child Organization. Each Organization keeps its own Ledger and operates independently. Transactions cannot move value directly between ledgers. You orchestrate the transfer with these steps:
1
In the source ledger, create a transaction from the original account (source) to the asset’s external account (distribute). This removes the value from the source ledger.
2
In the destination ledger, create a second transaction. The source is now the asset’s external account, and the destination is the receiving account (distribute).
This pattern moves value between ledgers in different Organizations in a controlled way.

Ledgers

No. Ledgers do not communicate directly. Transfers between Ledgers require orchestration.
You must orchestrate the process and move the amount through an External Account. This involves two steps:
1
Ledger A -> External Account.
2
External Account -> Ledger B.
No. A single Ledger can support multiple Plugins. For example, one Ledger can handle both Exchange and Pix Plugins.

Assets

No. Each Asset links to a single Account. Each Asset also links to an External Account. Midaz creates that External Account automatically when you create the Asset.
Midaz supports several Asset types:
  • currency: Traditional fiat currencies like BRL, USD, and EUR.
  • fiat: An alternative type for fiat currencies; like currency, the Asset code must follow ISO 4217.
  • crypto: Digital assets such as BTC, ETH, and other cryptocurrencies.
  • commodities: Tangible goods like gold, soybean, and oil.
  • others: Custom Assets, including loyalty points and tokenized securities.

Portfolios

A Portfolio groups accounts that belong to the same entity (CPF/CNPJ). For example, one CPF with two different segment_id values has two matching account_id values. You create a Portfolio for that CPF to link both accounts under one structure. This makes related accounts easier to find and manage.

Accounts

No. Each Account links to a single Asset. You cannot change this link.
An External Account receives funds from outside the Ledger. It brings money into the system.
Midaz creates an External Account automatically when you create an Asset. This External Account backs all transactions that move in and out of the Ledger.
No. Each account (account_id) links to only one Segment (segment_id).
No. You can create as many Accounts as you need. Midaz sets no limit on the number of Accounts.
The balance top-up process works as follows:
  1. When you create an Asset (for example, BRL) in the Midaz Ledger, Midaz also creates an External Account for that Asset.
  2. This External Account mirrors the balances the institution holds outside Midaz. Those balances can sit in a PI account, a settlement account, a reserve account, or a traditional bank or payment account.
  3. To deposit funds from outside the Midaz Ledger into a user account, follow these steps:
    • Create a transaction with the External Account as the source and the target accounts as the destination.
    • Midaz debits the External Account by the amount (so it becomes negative) and credits the destination accounts by the values in the transaction payload.

Transactions

A Transaction must have at least two Operations. For example, a transfer of R$ 100 from Account A to Account B has two operations:
  • Operation 1: Debit R$ 100 from Account A.
  • Operation 2: Credit R$ 100 to Account B.
Lerian gives clients several ways to access transaction receipts:
  1. Via APIs — Retrieve transaction data through the APIs, then generate a visual receipt in any format you choose.
  2. With the Reporter — Extract transaction data and create custom visual receipts.
  3. Through the Console — Access transaction data directly in the Lerian Console.

Entities

The Entity (entity_id) accepts external IDs. Midaz enforces no validation on this field. You can use the IDs that already exist in your database and integrate them into your system.

Idempotency

Midaz treats the request as new every time. Retries can then create duplicate operations.
No. Scope each key to a single operation and endpoint.
Midaz uses only the TTL from the first request. A later change has no effect.
Yes. For a completed request, Midaz returns the same result it stored from the first request. It also sets the X-Idempotency-Replayed header to true.
The default TTL is 300 seconds (5 minutes). Send the X-TTL header to set a custom value in seconds.

Accounting in Midaz

Midaz lets you mirror your organization’s official Chart of Accounts in the platform. You configure two core features:
  • Account Types — Create the logical categories from your chart, such as Assets, Liabilities, Revenue, and Expenses. Assign them to accounts in your ledger. When you enable the Account Types feature, the type field in the Accounts API becomes mandatory and must match a registered value.
  • Accounting Routes — Use Operation Routes to validate each leg of a transaction. For example, a debit must come from an account of type user_wallet. Use Accounting Routes (the transactionRoute resource in the API) to define complete transaction patterns that match your accounting logic.
Account Types and Accounting Routes together enforce your accounting rules at the ledger level. Midaz validates and categorizes every transaction against your Chart of Accounts. You do not hardcode rules in your business logic.

Plugins


Plugins extend Midaz with integration and process orchestration. They provide abstractions so you can focus on your business model instead of system logic outside your domain. The questions below cover how plugins work, how you deploy them, and the options available.
Plugins are technologies that integrate into the Midaz ledger. They simplify process integration and orchestration. They provide abstractions so clients can focus on their business model. Clients do not build or manage system logic outside their domain.
No. Plugins operate only with Midaz. They provide specific abstractions and orchestrate transactions based on the ledger structure.
After you contract a plugin, Lerian provides and installs it in your infrastructure (on-premise model), next to your Midaz instance. Applications connect to each plugin according to its function.
Lerian provides two types of plugins, grouped by origin:
  • Native Plugins: Lerian develops and integrates these plugins into the Midaz ledger. Lerian provides full support for them.
  • Marketplace Plugins: Lerian’s partners create these plugins for specific market niches. Lerian helps integrate them into Midaz. The partners provide and support them directly.

Fees Engine


These questions cover Fees Engine. Fees Engine is a licensed Midaz capability that runs inside the unified ledger process.

General Concepts

Fees Engine is part of Midaz. It runs in the Midaz ledger process to calculate fees for financial transactions. Configure and deploy it with Midaz. Learn more in the Fees Engine overview. It works across three main domains:
  • Fee Packages (/v1/packages): defines charging rules per transaction (flat fee, percentage, or whichever is greater).
  • Billing Packages (/v1/billing-packages): defines periodic charges based on transaction volume or account maintenance.
  • Calculation and Estimation (/v1/fees and /v1/estimates): endpoints for calculating fees in real time or simulating before confirming.
Fees Engine runs inside the Midaz ledger process. When a configured fee package applies, Midaz incorporates its fee calculations into the transaction. It uses ledger query use cases rather than an external HTTP connection to Midaz.
Every request requires the X-Organization-Id header with your Organization ID in Midaz. This header scopes the request to an Organization. It is specific to Fees Engine, not a tenant identifier. The platform still resolves your tenant context automatically from the JWT. When the authentication plugin is active, you also send a Bearer token in the Authorization header.
Fees Engine uses MongoDB for storage. Deletions follow the soft-delete pattern. Fees Engine does not remove records physically. It marks them with deletedAt instead. A deleted record does not appear in listings, but you can still audit it.
You need Midaz v3.6.0 or higher. Fees Engine depends on Transaction module APIs that Midaz added in v3.6.0. Earlier Midaz versions do not work with Fees Engine.

Fee Packages

A Fee Package (Package) is a set of charging rules under one feeGroupLabel. Each package links to an Organization + Ledger, and optionally to a Segment. A package can contain several fees (Fee objects), each with its own calculation logic. Learn more about Fee Packages.
Send a POST /v1/packages with the following body. See the Create Package API reference for full details.
Yes. Set the enable field to false when you create or update the package. Fees Engine skips a disabled package during fee calculation, even when the transaction context matches its scope.
Fees Engine applies the package only to transactions whose value falls within the [minimumAmount, maximumAmount] range. If the transaction value falls outside this range, Fees Engine ignores the package.Example: A package with minimumAmount: 100 and maximumAmount: 5000 charges fees only on transactions between 100 and 5,000.
If you do not set maximumAmount, the package can apply without an upper limit. Check the validation rules for your version.
Yes. Set the transactionRoute field in the package. Fees Engine then considers the package only for transactions with that route, such as "PIX", "TED", or "BOLETO".
These are account aliases that the package exempts from fees. If the sender or recipient of a transaction is an account in waivedAccounts, Fees Engine does not apply the package fees to it.
This package does not charge any transaction that comes from or goes to these accounts.
Yes. The listing endpoints (GET /v1/packages, GET /v1/billing-packages) support the limit and page query parameters for pagination.

Calculation Models

The applicationRule field inside calculationModel defines how Fees Engine calculates the fee. See Calculation Models for full details. There are three options:
Use exactly 1 calculation of type flat:
This charges a fixed 5.00 regardless of the transaction amount.
Use exactly 1 calculation of type percentage:
This charges 2.5% of the transaction’s reference amount.
maxBetweenTypes requires 2 or more calculations that combine flat and percentage. Fees Engine calculates both and applies the greater result.Example: Minimum fee of 3.00 or 1% of the value — whichever is greater:
For a 200 transaction: 1% = 2.00 vs. 3.00 flat → charges 3.00. For a 500 transaction: 1% = 5.00 vs. 3.00 flat → charges 5.00.
Yes. You can include any combination of flat and percentage. Fees Engine evaluates all of them and applies the greatest. Note that flatFee and percentual require exactly 1 calculation. Only maxBetweenTypes accepts 2 or more.

Important Fields

The referenceAmount defines which value Fees Engine calculates the fee on:
  • originalAmount: the original transaction value, before any fees.
  • afterFeesAmount: the transaction value after higher-priority fees apply.
The fee with priority: 1 runs first, so it must use originalAmount. No prior fees exist to consider.
When isDeductibleFrom: true, Fees Engine deducts the fee from the amount the sender sends. The recipient receives the discounted amount, and the sender pays extra to cover the charge.When false, Fees Engine charges the fee separately. The sender sends the full amount, and Fees Engine debits the fee apart.Constraints:
  • isDeductibleFrom: true requires referenceAmount: originalAmount
  • If the type is percentage: the value cannot exceed 100
  • If the type is flat: the value cannot exceed the package’s minimumAmount
The priority defines the execution order of fees within a package. Fees Engine runs lower values first.
  • priority: 1 → executed first (must use originalAmount)
  • priority: 2 → executed after, can use afterFeesAmount
Use priorities to chain fees. For example, run an administrative fee on the original amount. Then run an IOF fee on the amount after the administrative fee.
It is the alias of the ledger account that receives the fee revenue. Each fee can have a different creditAccount. This helps when different fees belong to different cost centers.
These fields define the routes of the accounting legs that the fee charge generates. They are optional. They let you track the origin and destination of fee movements in the ledger.

Billing Packages

Billing Packages are periodic charge packages, independent of per-transaction fee calculation. See Billing Package examples for use cases. There are two types:
  • volume: charges based on the number of transactions in a period, with tiered pricing.
  • maintenance: charges a fixed fee per account in a given scope.
Use volume billing to charge clients by the number of processed transactions. This is a common model for payment platforms with volume-based pricing. You define price tiers that apply as volume grows.
The last tier must be unbounded (no maxQuantity). There must be no gaps or overlaps between tiers.
Use maintenance billing to charge a fixed periodic fee per account. For example, charge a monthly fee per active account. You specify the scope (segmentId, portfolioId, or aliases) and the fee amount.
accountTarget must have exactly one of the three fields: segmentId, portfolioId, or aliases (maximum 100 aliases).
Tiers define the unit price per tier as volume increases. The rules are:
  1. Must be contiguous — no gaps between tiers (minQuantity of the next = maxQuantity of the previous + 1).
  2. Must not overlap.
  3. The last tier must be unbounded (no maxQuantity).
Example of correct tiers:
It is a free allowance. Fees Engine does not charge a set number of transactions before tiers apply. This helps pricing models with a minimum included volume.Example: freeQuota: 100 means Fees Engine does not charge the first 100 transactions in the period.
These are discount tiers for volume billing. They reduce the charged amount based on extra criteria. They complement the logic of the main tiers.
It defines how Fees Engine counts transactions:
  • perRoute: counts transactions by route (e.g., total approved Pix).
  • perAccount: counts transactions per individual account.

Fee Calculation and Estimation

The endpoint receives the transaction data. The system automatically finds the applicable packages. It considers:
  • ledgerId — required
  • segmentId — optional
  • transactionRoute — optional
  • Transaction value — compared with the package’s minimumAmount/maximumAmount
Fees Engine calculates and returns fees from all matching packages.
The /v1/estimates endpoint simulates the fee of a specific package (packageId). You do not need an actual transaction. It works well for:
  • Show the estimated cost to the user before confirmation.
  • Test configurations of newly created packages.
  • Build fee simulators in your product.
Yes. /v1/estimates is a read-only endpoint. It does not alter state or register transactions. It is safe to use in UX flows to show the cost before confirmation.
After you configure Billing Packages, call this endpoint:
This endpoint processes the configured rules and generates the charges for the period. See the Calculate Billing API reference.

Common Errors

The fee with priority: 1 must have referenceAmount: "originalAmount". It is the first fee to run, so no prior fees exist to base the calculation on.Fix:
Fees with isDeductibleFrom: true can only use referenceAmount: "originalAmount". Update the field:
When isDeductibleFrom: true and the type is flat, the fee value cannot exceed the package’s minimumAmount. This prevents a fee that is larger than the minimum transaction value.Example: If minimumAmount: 100, the flat fee cannot exceed 100.
This error occurs when isDeductibleFrom: true, the type is percentage, and the value is above 100. A deductible percentage fee of 100% would zero out the transaction. Values above 100 are invalid.
Volume billing tiers must cover all ranges without gaps. Check that the minQuantity of each tier is exactly maxQuantity + 1 of the previous tier.
The last tier in volume billing must have no upper limit (no maxQuantity). This keeps a price on transactions above the highest defined range.
In maintenance billing, the accountTarget field accepts only one of the three options. Do not combine fields:
Yes. The aliases field accepts a maximum of 100 aliases per maintenance Billing Package.
The applicationRule: "flatFee" accepts exactly 1 calculation, and it must be of type flat. Do not use percentage with flatFee.
Like flatFee, the applicationRule: "percentual" accepts exactly 1 calculation of type percentage.
maxBetweenTypes requires at least 2 calculations to work — it needs values to compare. Provide at least one flat and one percentage.
Diagnostic checklist — see also Best Practices:
  • enable: is the package active (enable: true)?
  • ledgerId: is the package linked to the correct ledger?
  • minimumAmount / maximumAmount: is the transaction value within the range?
  • transactionRoute: if the package has transactionRoute, does the transaction use the same route?
  • segmentId: if the package is scoped to a segment, does the account belong to it?
  • waivedAccounts: is the account listed as exempt?
Fees Engine soft-deletes records. It marks them with deletedAt and does not remove them from the database. The API does not expose restoration endpoints by default. Contact the Lerian team if you need to recover a deleted record. For a full list of error codes, see the Error Codes reference.