When the Apache Fineract batch API fits a multi-step banking operation
The Apache Fineract batch API combines several REST calls into one request, and it fits a multi-step banking operation whose steps must succeed or fail together. Consider a team whose integration must create a client, open a savings account and post an opening deposit as one unit of work. Sent as three separate calls, a failure after the first call can leave a client with no account, and the integration must work out what to undo. A batch request lets the team send those steps together and read the outcome as one result. Before you design compensation logic around it, confirm in the Fineract platform documentation how the batch endpoint treats the enclosed calls.
In the documented deployment model, each Fineract instance is set to a read, write or batch type through environment variables, and the batch endpoint is served by a batch instance. The documentation recommends one write instance, one batch instance and multiple read instances on database read replicas for high load. The practical consequence is that batch traffic runs apart from the write instance, which also runs Liquibase migrations. Your team should decide how traffic is routed to the batch instance, size it for the largest combined request you expect, and confirm the routing with load tests in your own environment, since the project does not provide a comprehensive production guide.
Batching fits operations with dependencies between steps, where a later call needs an identifier returned by an earlier one, and where a partial result would leave customer records inconsistent. It is a weaker fit for independent calls that users trigger one at a time, and bulk historical loads belong with the migration tooling. Before you commit, test three things in a non-production tenant: how a failed inner call is reported, whether all enclosed calls roll back together in your Fineract version, and how idempotency keys behave when a whole batch is retried. Record the answers in your design, because the retry logic in your integration depends on them.
Batch API configuration options and when each fits
This table compares the design choices that shape a Fineract batch request: transaction scope, how later steps refer to earlier results, which instance receives the batch, and whether reads go to replicas. Read each row by asking which failure or load risk you are accepting. Confirm exact behavior against the Fineract documentation for your release before you commit to a design.
| Decision | Option | When it fits | Main trade-off |
|---|---|---|---|
| Transaction scope | Single transaction | Steps must succeed or fail together, such as creating a loan and its related entries in one unit of work | Confirm how a failure affects earlier steps in your version, and keep batches small enough to retry cleanly |
| Transaction scope | Independent requests | Steps are unrelated, such as bulk lookups or separate postings that can each stand alone | Partial success is likely, so each step needs its own retry and reconciliation logic |
| Linking steps | Reference earlier results | A later step needs an identifier created earlier in the same batch, such as a new client before its loan | Creates ordering dependencies, so the reference syntax and failure handling must be tested for your version |
| Linking steps | Pre-assigned identifiers | The caller controls identifiers up front so every step can be built before any call runs | Identifiers must be unique and supported on each endpoint, so confirm this per entity type |
| Instance | Dedicated batch instance | High-volume batches must not compete with interactive writes or end-of-day processing | Another instance to deploy, configure and monitor, and schema changes still run on write instances |
| Instance | Write instance | Low-volume batches, small deployments, or teams without a separate batch node | Batch load shares resources with interactive writes and scheduled jobs |
| Data source | Read replicas | The batch only reads or looks up data that feeds a later write in a separate step | Replica lag can return stale data, so any write must go to a write-capable node |
| Data source | Write nodes | The batch contains writes, or its reads must reflect the latest committed state | Reads compete with writes, so capacity planning must account for the added load |
How to set up and verify batch requests in a test environment
This sequence takes a non-production Fineract tenant from a configured batch instance to a verified batch call with dependent steps and confirmed rollback on failure. The result is evidence your team can reuse before any batch workflow reaches production.
Confirm the batch instance type is set
Check the environment variables for the Fineract deployment and confirm that the instance designated for batch processing is set as the batch instance type, separate from the write and read instances. The Fineract documentation describes read, write and batch instance types set through environment variables, and recommends one write instance, one batch instance and multiple read instances for high load. Ask the platform owner to show the running configuration, not just the deployment template, and record which pod or host serves batch requests. This step is done when the team can name the batch endpoint and confirm it is distinct from the write instance in the test environment.
Enable HTTPS and authenticated access
Turn on TLS for the test environment using the SSL settings the Fineract documentation provides through environment variables, such as FINERACT_SERVER_SSL_ENABLED, and confirm that plain HTTP requests are not served for API traffic. Replace the default development login before any test account is created, because the README's default credentials are for development only. Authenticate with a named test user through OAuth2 or HTTP basic authentication, whichever your deployment uses. The check is a request over HTTPS that returns an authenticated response, and a request without credentials that is refused.
Confirm the tenant header on every request
Fineract is multi-tenant, so each API request must carry the Fineract-Platform-TenantId header with the identifier of the non-production tenant. Send a single read request, such as a request for office or client data, with and without the header, and compare the results. The request with the header should return data from the intended tenant, and the request without it should fail or return nothing useful. Record the tenant identifier in the test plan so that the batch test later uses the same value, which prevents writes landing in a tenant nobody intended to change.
Build a batch of two dependent calls
Write a small batch request with two operations where the second depends on the result of the first, for example creating a client and then creating a record that refers to the new client. Use the reference mechanism described in the Fineract batch documentation so that the second call points to the result of the first call's response rather than a hard-coded identifier. Keep the payload in version control so the same test can be repeated after an upgrade or configuration change. The step is complete when the batch file is reviewed by a second person and both calls are clearly labeled with their expected outcome.
Run the batch against a non-production tenant
Send the two-call batch to the batch endpoint on the test tenant using the authenticated HTTPS session and the tenant header. Check the response for one result entry per call, and confirm that the second call's result reflects the identifier created by the first call. Then query the created records through the read path to confirm they exist with the expected values. The check is that both records are visible in the test tenant and that the response status and per-call results match what the batch file predicted.
Verify that a failing call rolls back the whole set
Add a deliberately invalid third call to a copy of the batch, for example one that references a product or office that does not exist in the test tenant, and submit it. Confirm from the response which call failed and what the error reports. Then query the database-backed read path to confirm that the records created by the first two calls were not kept, which tests the single-transaction behavior. Document the actual behavior in the test log, because the rollback expectation should be confirmed in your Fineract version before it is relied on in a process design.
Record the results as a repeatable test
Store the batch payloads, the tenant identifier, the environment settings used, the successful response and the failure response in the test repository. Re-run the successful batch once more to confirm that repeated submissions are handled the way your design expects, and note whether a duplicate creates new records or is refused. Hand the record to the team that will own the production configuration so they can compare the batch instance settings, TLS settings and tenant header with the production plan before any batch workflow is approved.
Security and operational risks of batching calls
A batch request concentrates several Fineract actions behind one HTTP call, so its risks are the same as those of the individual calls plus a few new ones. The cards below cover the controls to design and verify before a batch endpoint reaches production traffic.
Privileged actions in one request
A batch carries several operations under one authenticated session, so a single compromised token can post many changes at once. Map each batch to the least-privileged user it needs, and confirm that every sub-request is authorized as that user. Test a batch that includes one operation the caller lacks permission for, and check that the response and the database state match your expectations.
Replace default development credentials
The README login for development uses the default user mifos with a published password. Change it, remove it from every environment that holds real data, and confirm that no batch client, script or pipeline still uses it. Check that OAuth2 or basic authentication is configured for each caller that submits batches.
HTTPS-only transport
Batch payloads contain account identifiers, amounts and sometimes personal details, and they travel as one request body. Enforce HTTPS for every path to the batch instance, and enable the SSL settings through environment variables such as FINERACT_SERVER_SSL_ENABLED. Verify with a scan that plain HTTP connections are refused at the edge and inside the cluster where traffic crosses trust boundaries.
Tenant isolation in batch calls
Fineract selects the tenant from the Fineract-Platform-TenantId header, so a batch sent with the wrong header can act on another tenant's data. Have the gateway or client library set this header from the authenticated identity, not from caller input. Test that a sub-request cannot override the tenant context and that cross-tenant access fails.
Personal data in batch logs
Logging the full request body of a batch can write client names, identifiers and loan details to application logs in clear text. Define which fields your logging pipeline may store, mask or drop sensitive values at the gateway or in the application, and set retention for those logs. Review a sample of log entries after a test batch to confirm what was written.
Load on a shared batch instance
The documentation recommends a separate batch instance, so large batches do not slow interactive writes or reads. Set limits on the number of sub-requests and payload size, and test how long a large batch holds database connections. Confirm that a heavy batch cannot delay the close of business day job or other scheduled work on the same environment.
What happens to a batch when one call fails
Design the client on the assumption that a batch does not guarantee what you need until you have confirmed it for your Fineract version. Before you build, decide which groups of calls must succeed or fail together, such as creating a loan and then disbursing it. Then check the Fineract documentation and test on your own deployment to see whether a failed sub-request rolls back earlier sub-requests in the same batch, whether the batch returns partial success, and how the instance type serving the batch affects this. Write the answer down as a explicit rollback rule for each business flow, and do not assume that the behavior you saw in a development environment holds in production.
Dependent references are where partial failure does the most damage. When a later request uses an identifier returned by an earlier one, the client must stop building the dependent calls as soon as the earlier call fails, instead of guessing or substituting values. Parse each sub-response on its own status code and body, not only the envelope status, and treat a missing identifier as a failure. Keep a record that maps each request position to its response so that reconciliation after a failure can show exactly which records were created. Confirm with your version how references are expressed in the batch request body, because the field names and ordering rules are version-specific.
Test rollback and response parsing against the exact Fineract release, database and deployment topology you will run, with PostgreSQL as the recommended database according to the Fineract README. Build a test that forces a failure at every position in a representative batch, then query the database to confirm there are no orphan clients, loans or accounting entries. Retries need separate planning: if a batch times out after Fineract has committed part of it, a blind retry can duplicate work. Plan idempotency for each sub-request before you enable retries, using the approach in the sibling page on idempotency keys in the Fineract API.
Limits to confirm before you rely on batch calls
Batch requests save round trips only if the limits around them fit your volume and your release. The cards below list what to confirm with the project, in your own test environment, and with your operations team before any batch flow reaches production.
Request size and call count
Confirm how many sub-requests one batch call may carry and how large the combined payload can be before the server rejects it. Ask the project whether these caps are configured or fixed in code, and whether they differ between the batch instance and the write instance. Then test your largest real batch, such as an end-of-day disbursement run, and record the response time and any rejection.
Which endpoints accept batch entries
Not every Fineract endpoint may be reachable through the batch mechanism, and some may behave differently inside one. Build a list of every endpoint your flow calls, then check each one against the current API reference for the release you run. Mark any endpoint you cannot confirm and keep it out of batch requests until a test proves it works.
Behavior on your Fineract release
Batch semantics can change between releases, and the project publishes quarterly releases with end-of-life archiving. Record the exact release you deploy, read its release notes for batch and idempotency changes, and rerun your batch test suite on every upgrade candidate. Do not assume behavior carried over from a blog post or an older version.
Business date and approval workflows
A batch call that creates or changes a transaction may run against a business date and an approval step that differ from what the caller expects. Confirm how the referenced results behave when an approval is pending, and whether the business date header is applied to every sub-request. Test a batch that spans a date boundary and a batch that includes an entry requiring approval.
Batch instance sizing
The documentation describes separate read, write and batch instance types, and batch work competes with the same database. Ask your platform team how many batch instances you need for your peak volume, and whether batch load can slow the write path or interfere with end-of-day processing. Load test with production-like account counts and watch database connections and transaction duration.
Partial failure and rollback
Confirm exactly what happens when one sub-request fails midway: whether the whole transaction rolls back, which responses return, and what the caller must reconcile. Test this with a forced failure in staging, including a failure in the last entry, and make sure your retry logic relies on the idempotency behavior you have verified rather than on assumptions.
Questions teams ask before using the Fineract batch API
How much effort does a Fineract batch integration take?
Effort depends mainly on how many business operations each batch bundles, how many of them depend on results from earlier calls, and how many failure paths the integration must handle. No duration is given here because the documentation does not supply one for batch work, so the reliable way to size it is a written scope. The main drivers are the number of endpoints involved, the mapping between your source data and Fineract's request bodies, the rules for retrying or partially failing a batch, and the products, offices and accounting settings that must already exist before the batch runs. Ask any partner to itemize these drivers in a fixed-scope quote, and ask which parts are one-time build work and which recur, such as monitoring and updates when a new Fineract release arrives.
Can our internal team build a Fineract batch integration without a partner?
Yes, a team with REST integration experience and a working Fineract environment can build batch calls on its own, because batch requests are part of the platform's documented API. The harder part is usually knowing the business sequence: which loan, savings or client records must exist before a later call can reference them, and how a failed step should be handled in production. Teams with one integration and a small set of operations often manage this internally. Teams that also need tested rollback, tenant and database configuration review, and audit evidence may find outside help more efficient for the design review. Whichever route you choose, confirm the approach against the Apache Fineract documentation for the release you run.
How long does testing a batch integration usually take?
Testing time depends on how many batch shapes you need to verify, not on a fixed number of days. Each shape needs happy-path tests, partial-failure tests where an early call succeeds and a later one fails, and retry tests that confirm the outcome when the same batch is sent twice. You also need test data covering the loan and savings products the integration touches, and a business date you control, so that end-of-day processing does not change results mid-test. Plan at least one full run against a production-like configuration before cutover. Ask any vendor to list the test cases in the written scope, and ask who owns the test environment, because its setup often takes longer than the tests themselves.
What does our team need to provide for a Fineract batch project?
The work needs more from your side than access to a code repository. Plan to provide:
- Named owners for the business process, such as lending operations or finance, who can confirm which sequence of loan, client and accounting steps is correct.
- Access to a Fineract environment you control, with tenant, database and instance configuration documented, and credentials managed under your own policy.
- Sample payloads from the systems that will call the batch, along with the error responses those systems must handle.
- A named approver for changes to products and accounting mappings, since a batch can create records that are difficult to reverse.
- Time from the people who will run the integration after go-live, so that monitoring and failure handling are designed with them.
When are single API calls a better choice than a batch?
Single calls are the better choice when each step needs a human decision, when the result of one call determines whether anything else should run, or when an operation is simple enough that a failure is easy to see and retry on its own. Batching pays off when several related operations must succeed or fail together and later steps depend on identifiers returned by earlier ones. Single calls are also easier to debug, monitor and retry with an idempotency key for each action. A practical test: if an engineer must read the first response before writing the second request, a sequence of single calls may be clearer. Batches add value for multi-step onboarding or disbursement flows, but they make error handling more involved, so confirm the expected partial-failure behavior before committing.
What goes wrong most often with Fineract batch requests?
The most common problems come from treating a batch as if it behaves like a database transaction across every system. Verify with the documentation for your release how a failed call inside a batch is reported and what state the earlier calls leave behind. Other frequent issues include references to identifiers the batch has not yet returned, duplicate submissions after a timeout without an idempotency key, and business date settings that differ between test and production, which change the outcome of end-of-day processing. Plan monitoring for failed batches and reconcile records after each run. Treat the platform documentation as the authority on behavior, and confirm any detail you are unsure of in a test environment before it reaches production.
How DeployOpen works on this
DeployOpen plans, builds and documents batch request flows for Apache Fineract inside your own infrastructure, starting from a written scope. We test each batch against your environment, hand over the working flows with their runbooks, and can support them afterward under a retainer.
How we scope
- Written scope lists which Fineract workflows will be combined into batch requests and why.
- Scope records which steps must share one transaction and which can run as separate calls.
- Scope names the Fineract version, PostgreSQL setup and instance layout the batches will target.
How we build
- We design batch payloads with request IDs so later items can reference earlier results.
- We build error handling that reads per-item status codes and decides which items to retry.
- We test batches against a running Fineract backend using your own product and accounting setup.
How we hand over
- You receive batch request templates, the reference map and the error handling code.
- You receive test results covering rollback behavior, partial failures and duplicate submissions.
- You receive runbook notes on routing batch calls to the batch instance in your deployment.
How we support
- Engagements are fixed-scope, with deliverables and timelines agreed in writing before work starts.
- Ongoing support, upgrades and continuous testing for batch flows are available as a retainer.
- Retainer reviews can re-run batch tests after each Fineract release you adopt.

