Do not replace
/v1 with /v2 everywhere in your integration. Midaz v3.x.x and Midaz v4.x.x are product versions. v1 and v2 are HTTP contract versions. Midaz v4.x.x serves v1 and v2 contracts side by side, and some v1 routes have no v2 route.Ledger routes
Replace
{organization_id}, {ledger_id} and the other identifiers in the paths with the values of your integration.
Organizations, assets, segments, portfolios, account types, ledger settings and metadata indexes also have v2 routes. Keep the method and the scope of each route. Not all of them take an organization and a ledger in the path:
/v2/organizationsand/v2/organizations/{organization_id}/ledgerstake the organization only./v2/settings/metadata-indexestakes no organization and no ledger./v2/transactions/direct,/v2/transactions/hold,/v2/transactions/blockand/v2/transactions/unblocktake no organization and no ledger in the path.
Organization and ledger in the transaction body
The v2 body has no top-level
organizationId or ledgerId. Each item names the organization and the ledger of its own account:
asset, amount and credits. See the example of a direct transaction.
Follow these rules:
- Send
organizationIdandledgerIdin every item. Both are required, and both are UUIDs. - All items must name the same organization and the same ledger.
- From v4.1.0,
directandholdaccept items in different ledgers when every ledger enablescrossLedger.enabled. See cross-Ledger transactions. blockandunblockalways need one organization and one ledger in all items.
Exceptions
These routes need specific handling. Do not apply the tables of this guide to them.
- Annotations.
POST /v1/organizations/{organization_id}/ledgers/{ledger_id}/transactions/annotationhas no v2 route. - Asset rates. These v1 routes have no v2 route:
- Tracer. Tracer keeps its own v1 API. See the Tracer API quick start.
CRM and Fees in API v2
In Midaz v4.x.x, the Ledger serves CRM and Fees as modules. Update the base URL of CRM and Fees in your environment. Midaz v4.x.x serves the CRM and Fees routes in v2 only. It has no v1 copy of them. Each route keeps its method, unless the table says otherwise.
CRM
The v1 routes below come from CRM in Midaz v3.x.x. CRM in Midaz v3.x.x means the CRM component of Midaz v3.5.0 to v3.8.6 and the standalone CRM plugin. Midaz v4.x.x renames aliases to instruments.
The last four rows apply only to the CRM component of Midaz v3.x.x. The standalone CRM plugin does not have these routes.
Fees
The v1 routes below come from the standalone Fees plugin. Midaz v3.x.x has no Fees component.Scope and permission changes
- Send the organization in the path. Do not send the
X-Organization-Idheader. - In Fees, send the ledger in the path. Remove
ledgerIdfrom the body of packages, estimates, billing packages and billing calculation. - The package and billing package lists always cover one ledger. In the plugin,
ledgerIdwas an optional query parameter. To list the packages of a whole organization, call the list once for each ledger. - In CRM instruments, keep
ledgerIdandaccountIdin the body. - Use estimates only to simulate fees. An estimate does not record anything.
midaz group. Grant the new permissions in Access Manager before you move traffic. Do not assume that the old grants still apply.
New routes do not move your data. Plan the migration of the CRM and Fees data, relationships and identifiers as a separate task. For the history of standalone CRM, see CRM migration history. To move the fee packages of Bank Transfer, see Migrate Bank Transfer fees to Midaz.
Transaction contract
The v2 request body has these fields:
asset: the asset code.amount: the total, as a decimal string.debitsandcredits: arrays with one or more items each.
debits and credits has these fields:
alias: the account alias.organizationIdandledgerId: the UUIDs of the organization and the ledger of the account. See Organization and ledger in the transaction body.amountorshare: send exactly one of the two.
pending field:
- Use
/v2/transactions/directto post the transaction at once. - Use
/v2/transactions/holdto create a pending transaction. Then commit or cancel it.
@external/ followed by the asset code in upper case, for example @external/BRL.
Example of a direct transaction
POST /v2/transactions/direct. Replace the aliases and the UUIDs with the real values.
Fields that the v2 body does not accept
Midaz refuses a v2 body that has an unknown field, with a400 response. Review your flow if it sends any of these v1 fields:
rateandremainingin an item.metadatain an item. The transaction itself still acceptsmetadata.transactionDate.balanceKeyin an item, on Midaz v4.0.x only. From v4.1.0, each item accepts an optionalbalanceKey.
Responses and errors
Transaction responses
sourceanddestinationbecomedebitandcredit, in the singular.- The transaction no longer has
routeandchartOfAccountsGroupName. - The operations inside a transaction no longer have
routeandchartOfAccounts. They keeprouteId,routeCodeandrouteDescription. - The responses of an operation that you read alone do not change.
- From v4.1.0, a
directorholdthat spans ledgers returns a group withgroupIdandtransactions[]. Commit, cancel and revert can also return a group.
GET /v2/organizations/{organization_id}/ledgers/{ledger_id}/transactions/{transaction_id} in the API reference.
Errors
The v2 routes return errors in the RFC 9457 format, withContent-Type: application/problem+json. Read these members:
type,title,statusanddetail.code: the Midaz error code. The same error has the same code in v1 and v2.errors[]: the field errors, when the request has them.
POST /v2/transactions/direct request that still sends the v1 field transactionDate gets this response:
type URI ends with the error code. Its /v1 segment is the version of the error catalog, not the version of the API.
Do not rely on message or fields. They belong to the v1 error format. In v2, only 413 and 504 responses also carry a top-level message. See Error handling and the Midaz error list.
Accounts and rules in API v2
Account routes
The v2 account routes let you do these tasks:- Read an account by alias and by external code.
- Update and delete an account.
- Count the accounts with
HEAD.
holderId when you create an account. Read holderId and holderCheckSkipped in the v2 account responses.
Holder rules
- When
accounting.requireHolderis on, each account needs a holder of the organization. Without a holder, Midaz does not create the account. - To skip that check, send
skip.holder. Midaz accepts it only whenoverrides.allowHolderSkipis on. Otherwise, Midaz refuses the request with422and error0490. - When
accounting.requireHolderis off and you send no holder, a non-external account gets the holder of its organization. An external account gets no holder. - When
accounting.requireHolderis off, Midaz does not check that theholderIdyou send exists. - An account that you create through v1 gets no holder. v1 does not apply these rules.
Fees and Tracer
A v2 transaction runs two steps that v1 does not run:- Fees. Midaz charges a fee when a fee package matches the transaction.
- Tracer. Midaz reserves the transaction in Tracer when the Tracer mode of the ledger is not
off.
skip.fees or skip.tracer. The ledger must turn on overrides.allowFeeSkip or overrides.allowTracerSkip first.
Validate your fee packages and your Tracer limits before you move traffic. After the migration, you can see new charges and new refusals. See Midaz and plugin compatibility.
Migration checklist
- List the routes that you use, the product version and the base URL of each service. Separate the routes with a v2 route from the routes that have none. Plan to stop using the routes that have none by April 29, 2027.
- For each transaction, select
directorhold. Updatedebits,credits, the decimal values and the scope of each item. - Change CRM aliases to instruments. Move the organization and the ledger of Fees to the path. After the data migration, check the relationships and the identifiers.
- Grant the
midazpermissions. Test the holder rules of the accounts in a staging environment. - Update how you read success and error responses. Test removed fields, invalid input, missing resources and denied access.
- Test each flow that your integration uses: create, read, hold, commit, cancel, revert, block and unblock. Check balances, operations, fees and refusals by Tracer limits.
- Keep sending
X-IdempotencyandX-TTLon create requests. Do not send the same transaction through v1 and v2 to compare results. Use controlled data and scenarios in a staging environment. - Move traffic in controlled steps. Monitor errors and financial results. Keep a rollback plan that does not send processed transactions again.

