Codes and code values in Apache Fineract: what the drop-downs control
Codes are the named lists behind the drop-downs in Fineract forms, and each code holds the code values staff choose from. Identifier types, closure and rejection reasons, genders and the options offered by custom fields are all built this way. They need to be designed before the first staff member onboards a client or closes an account, because values entered freely or chosen loosely become history that reports, audits and later migrations must read. Fineract's documented API manages codes and their values through resources to create, list, update and delete them, so the lists can be built and maintained through the platform rather than by editing the database.
The design work is a decision about what the business will need to count and explain later. A closure reason list, for example, decides whether a team can separate customer requests from credit-driven closures in a monthly report, and a rejection reason list decides whether declined applications can be analyzed at all. Before configuration, ask the operations, risk and reporting owners to sign off each list, its values and its wording, and confirm with your compliance and identity owners which identifier types your onboarding policy requires. Confirm the exact fields and any additional constraints for each resource against the Fineract legacy API documentation for your release, since the supplied material does not list default values or limits.
Consistency across tenants is the second decision. Fineract is multi-tenant, so each tenant has its own codes unless your team creates them consistently in every one. Choose one owner for the master list, record the approved values in version-controlled configuration or a change log, and run the same create or update calls against each tenant during rollout. Deleting a code value that already appears on live records is a risk to test before you do it, so plan a retirement approach (stop offering the value, keep existing records readable) instead of removing it outright.
Which code lists to design and when each fits
This table compares the main code list groups in Fineract, what each one drives, who should own its values, and how long or short the list should be. Read it before creating any code, because a list that staff must choose from daily has different design needs than one used mainly for reporting.
| Code list | What it drives | Who owns the values | Short controlled list or longer analytical list |
|---|---|---|---|
| Identifier types | The document types offered when recording client identity, such as national ID or passport, which feed KYC records | Compliance or KYC lead, with sign-off from the business owner of onboarding | Keep short and controlled. Each added type needs a KYC rule and staff training, and auditors will sample against it |
| Closure reasons | The reason captured when a client, loan or savings account is closed, used in closure reporting | Operations or product owner, with input from finance for reporting needs | Medium length. Enough distinct reasons to separate customer-requested closure from default or write-off, but not so many that staff pick at random |
| Rejection reasons | The reason recorded when a pending application or approval is rejected, feeding the approval history | Credit or operations manager who reviews rejected applications | Keep short and standard so approvers choose consistently. Free text in the notes field can carry detail without weakening analysis |
| Genders | The gender value captured on client records, often used in statutory or donor reporting | Confirm with the reporting owner and local regulator requirements before changing defaults | Keep to the values your reporting obligations require. Changing values after data entry can break historic reports |
| Lists backing custom fields | Drop-down options on data table columns for extra client, loan or savings attributes, such as sector or purpose | Product or business owner of the field, with the data table owner | Choose length by use. Short lists suit fields used in eligibility rules, while longer lists suit fields kept for analysis and can be cleaned later |
Setting up code lists in a sequence that avoids rework
The sequence moves from business agreement to a tested tenant and then to every other tenant, so each drop-down is defined once, checked on the real forms, and copied without drift. Each step closes with a check that the reader can repeat before go-live.
Collect value lists from business owners
Before anyone calls the API, the implementation lead asks each business owner for the exact lists their teams will select from: identifier types, closure and rejection reasons, genders, and any values for custom fields. Owners confirm the wording, the spelling users will see, the order they expect, and which values are retired rather than deleted. The output is a signed-off list per code, kept in the project record, so later changes trace back to a decision. Check: every list has a named owner and a written approval date.
Create each code in the test tenant
An administrator creates each code through the codes API resource in a test tenant, using the name and description agreed in the previous step. Names should follow one naming convention across the project so that teams and integrations can find them without guessing. Create codes in a fixed order and record the identifiers Fineract returns, because those are what integrations and later migration scripts will refer to. Check: a list call returns every code created, with no duplicates and no stray test entries.
Add and order the values for each code
For each code, the administrator adds its code values in the order owners approved, with the display label exactly as agreed. Values that appear in reports or are referenced by configuration should be created once and not re-keyed, since a later rename changes what users see but not what the record stores. Confirm with the owner that the first value in each list is the intended default, because it is the value most users will leave selected. Check: a get call on each code returns its values in the approved order with the approved labels.
Verify drop-downs on each affected form
A tester opens every Fineract form that uses these codes in the test tenant, such as client creation, identifier capture, and the closure or rejection screens for the relevant entities. They confirm each drop-down shows the expected values, the default is correct, and inactive values are hidden where they should be. Any form that does not show a code signals a mapping or naming problem to fix before the next step. Check: a written checklist shows each form, each code, and a pass result from a tester who is not the person who built the lists.
Test list and get responses against the approved set
Alongside the screen checks, the team compares the API output with the signed-off lists. List and get calls should return the expected codes and values, including labels, order and any inactive entries, and integrations that read these identifiers should be tested against the same responses. Differences are fixed in the test tenant and the test is repeated until the output matches the approved record. Check: a saved set of list and get responses matches the business-approved document line for line.
Promote the same definitions to other tenants
Once the test tenant passes, the team applies the same code and value definitions to each production or other tenant, using a script or a repeatable set of API calls rather than manual entry. Fineract is multi-tenant and each request carries a tenant identifier, so the promotion must run once per tenant and be logged against it. Where a tenant needs a different list, the difference is recorded in the approved record rather than made by hand. Check: each tenant's list and get output is compared with the test tenant baseline and any differences are explained.
Confirm definitions before go-live and keep them under change control
Before go-live, the implementation lead runs the verification again in each tenant and confirms that the business owners have signed the final lists. After go-live, changes to codes go through the same request, test and promotion path, so a new value is added to the approved record and then to every tenant. The team should confirm with the vendor and in its own environment how the chosen Fineract version handles deactivating or deleting values that already appear on records. Check: a go-live sign-off lists every tenant with a matching comparison and a named owner for future changes.
Keeping codes consistent across tenants
With one tenant, the main risk is a change that nobody recorded. The live values in Fineract are the only current copy, so the list definitions should be kept in version control as the source of truth, and the live tenant should be checked against that file. Code changes go through the same create, update and delete calls described in the Apache Fineract API legacy documentation, whether they are typed by hand in a test environment or scripted.
- Version the definitions: Keep one readable export per code, with its name, values and order. Tag each approved state with the date it went live and the Fineract release running at the time.
- Assign approvers by code: Name one business owner for each code, such as compliance for closure reasons or operations for identifier types, and require that owner's sign-off in the change record before any call runs.
- Replay in the same order: Apply approved changes to production in the order they were tested, and log the response for each call so the production run can be compared with the test run.
- Detect drift on a schedule: Compare a fresh export of the live lists with the version-controlled file, and treat any difference that has no approved change record as an incident.
Confirm whether your team can export the live lists in a form your repository can diff, and check which fields the API returns for each value before you settle the file format.
When several tenants share one standard, a central set of code lists feeds every tenant, and the design questions are who may change the standard and how local deviation gets caught. The shared set should be a published baseline with a named owner, and every tenant should receive it through the same scripted path. Each request still targets one tenant, so the automation must choose the tenant explicitly on every call.
- Publish a versioned baseline: Give each set of shared lists a version number and a date. Each tenant should record which baseline version it currently runs.
- Approve changes centrally: A standards group approves additions and changes to the baseline, and tenant requests go to that group before any tenant is changed.
- Scope every call to a tenant: Fineract selects the tenant with the Fineract-Platform-TenantId header, so confirm that your tooling sets this header on every request. A missing or wrong value sends a change to the wrong tenant.
- Replay per tenant and record results: Run the same scripted calls against each tenant in turn, and keep a result record per tenant so a failure in one tenant is visible and does not get lost.
- Compare each tenant to the baseline: Report the differences by tenant on a schedule, and allow local additions only through a documented extension list so that they show up as expected differences rather than surprises.
Check how your automation behaves when a call fails partway through a run, and confirm whether a partial replay can leave some tenants on an older baseline without anyone noticing.
Some tenants need values the shared standard does not carry, such as a local identifier type or a regional rejection reason. Local rules should stay in the tenant's own version history, be kept in separate files from the shared baseline, and be reviewed whenever the baseline changes so that overlapping names or codes do not conflict. The aim is that a baseline update never silently removes or renames a value a tenant depends on.
- Separate baseline and local files: Mark local values clearly, so a baseline replay can leave them alone. Confirm how your tooling handles deletions of values it did not create before it runs against a tenant with local rules.
- Version locally: Each tenant keeps its own history and records the baseline version its local values were built against.
- Review overlap before approval: The tenant owner approves local values, and the central team checks them against baseline names and codes before they go live.
- Replay selectively: When the baseline changes, apply only those changes to the affected tenants, then re-test any local values that depend on the changed list.
- Detect drift in both directions: Report values that exist in a tenant but not in its declared files, and baseline values that are missing from a tenant.
Check whether tenant reports rely on code value names or IDs, because a renamed local value can break extracts that a tenant builds on its own.
Risks when code lists change after go-live
Codes and code values feed forms, reports and records across every tenant, so a change that looks small can alter history or break comparisons. The risks below share one root cause: a list that changes without a defined owner, a record of the change, and a check against the data that already depends on it.
Renaming or deleting values in use
A code value already attached to client or loan records is part of history. Renaming it changes how old records read, and deleting it can leave records pointing at a value the drop-down no longer offers. Before any change, query which records use the value and decide whether it should be deactivated, relabeled or left alone. Confirm with your Fineract version how the legacy API handles deletes of values that are referenced.
Lists that drift between tenants
Fineract is multi-tenant, so each tenant holds its own codes and values. Over time, one tenant may add a closure reason or rename a gender option that another tenant does not share. Consolidated reporting then groups the same reason under different codes or drops it entirely. Keep a master list of codes and values, and compare every tenant against it on a fixed schedule.
Free-text workarounds that bypass lists
When a needed option is missing, staff often type the answer into a notes or free-text field. Those entries cannot be counted, filtered or validated, and they reappear as inconsistent spellings in reports. Track which free-text fields carry business meaning, review them periodically, and turn recurring entries into proposed code values through a controlled request.
Uncontrolled edits by administrators
Anyone with rights to manage codes can change a drop-down that affects loan closure reasons or identifier types across the institution. Without a change record, an edit can go unnoticed until a report breaks. Restrict code administration to a named role, route changes through a written request with approval, and keep a log of who changed what. Confirm which permissions in your deployment control this.
Mismatches with migration files
Legacy data loaded during migration often uses its own labels for identifier types, genders or closure reasons. If those labels do not match the codes and values configured in Fineract, the import either fails or maps records to the wrong option. Build the code list from the migration mapping file, not the other way round, and reconcile the two before each trial load and again at cutover.
Who can change code lists and how changes are recorded
Creating, updating and deleting codes and code values are state-changing administrative operations in Apache Fineract. Each call alters a drop-down that staff see on live forms, so the people allowed to make those calls should follow the same role model you use for other configuration changes. Start by listing which Fineract users and roles can reach the codes API resources, then remove any shared or generic accounts that could make changes. Confirm that your identity setup, whether the default HTTP basic login is replaced or OAuth2 is in use, ties every call to a named person and not a shared credential. Where your organization requires a second person to approve configuration changes, decide early whether code list edits fall under that control.
Keeping a record of who changed a list matters because a silent edit to a closure reason or an identifier type can change how later records are classified and reported. Do not assume the platform keeps this history. Ask the vendor or check the documentation for your exact Fineract version to establish whether the codes calls write an audit entry, what fields it captures (user, timestamp, before and after values) and how long it is retained. If the platform does not provide that trail, plan one at the gateway or in your own logging, and test it by creating, renaming and deleting a test code in a non-production tenant and confirming the record appears where your auditors will look.
For the broader controls, see the separate pages on Fineract security hardening and maker-checker and permissions. They cover credential handling, network exposure and the approval queue in detail, so this section only sets the code list decisions that feed into them. Keep the approval scope, the admin roles and the logging requirement in one written list, and check it again whenever you upgrade or add a tenant.
Limits to confirm in your Fineract environment
Codes and code values look simple, but their behavior depends on the release you run, the data already in your tenant and how other records point at them. The cards below list what to confirm before you finalize the design. Check each point against the legacy API documentation and in a test tenant on your own release, rather than relying on assumptions carried over from another deployment.
Default codes in your release
Confirm which codes and values ship in the Fineract release you will deploy, since a default list may differ from what your product team expects. Compare the shipped set against your identifier types, closure and rejection reasons, and gender lists. Record each default code's name and ID so migration scripts and reports refer to the same values. Treat any default you plan to keep as a dependency that must survive upgrades.
Deletion when values are in use
Confirm how your tenant behaves when you try to delete a code or a code value that existing clients, loans or savings accounts already reference. Test this in a non-production tenant with a referenced value, and note whether the API blocks the delete or leaves orphaned references. Your retirement process for obsolete reasons should depend on this result, not on an assumption that deletion is safe.
References from custom fields
Confirm how data tables and custom fields point at code values, including whether a dropdown column is bound to a specific code ID. Check what happens to stored values when a code is renamed, deactivated or removed. Because custom fields usually store the code value ID, a change to a shared code can alter historical records and reports that rely on those fields. Document each dependency before you change any shared code.
Ordering and label changes
Confirm whether your release lets you change the display order and the label of a code value without changing its underlying ID. Stable IDs matter for integrations, reports and migrated data, while labels often change with wording or regulatory language. Test a reorder and a label edit in a test tenant, then confirm that API consumers and exports still resolve the same values. Record the answer in your configuration standard.
Localization requirements
Confirm whether code value labels can be held in more than one language and how a front end selects the label to display. If your operations or customers use several languages, decide whether translations live in Fineract or in the front end. Check that reports and exports use a consistent language, since a mixed set of labels can make closure and rejection reasons hard to analyze.
Documentation version you follow
Confirm which Fineract release your team will follow for the API reference, because the legacy documentation may not describe every endpoint or field in your build. Pin the documentation version to the release you deploy, and recheck it at each upgrade. Where the documentation and your test results disagree, trust the tested behavior and raise the gap with the project before you rely on it in production.
Questions teams ask before configuring Fineract code lists
How much effort does a typical Fineract code list setup take?
Effort depends on how many lists you need, how many approval steps sit around changes to them, how many tenants share the design, and how many custom fields depend on those values. A single tenant with a short list of identifier types and closure reasons is a small job. A multi-tenant bank with dozens of lists, custom fields feeding loan and client forms, and a formal change approval process is a much larger one. Ask any partner to break the scope into lists, tenants, custom fields and approval steps, then price each group separately in the written scope.
Can our internal staff configure codes and code values without a partner?
Often yes, provided someone on the team has administrative access to the Fineract API and understands how the codes are used on forms. Codes and code values are managed through API resources that create, list, update and delete them, so the technical steps are simple. The harder parts are agreeing the values with business owners, deciding which values are retired rather than deleted, and checking that every form and report still behaves after a change. Ask your team to confirm who holds the admin role and whether they can run a test tenant first.
What do business owners need to provide for code lists?
Business owners need to supply the authoritative values for each list, the wording staff will see, and the rules for retiring or renaming a value. For identifier types, they must confirm which documents the institution accepts under its own policies. For closure and rejection reasons, they must agree the list with operations and risk, because those reasons appear in reports. Ask for a sign-off record per list, showing the owner, the approved values and the date of approval, so later changes can be traced.
How long does it take to validate the forms that use code values?
Validation time depends on how many forms, entities and custom fields reference the codes, and on whether your test data covers every path a user can take. Each form that shows a drop-down should be opened in a test tenant, submitted with each value that matters and checked against the expected record. Reports that group or filter by code values should be re-run. Ask for a written test list that names each form and report, and confirm who signs off the results before the change goes to production.
How do we keep code lists consistent across tenants?
Start by treating one tenant as the reference for each list, then record every list, value and label in a versioned file or change log that your team can review. Apply changes to other tenants through the same reviewed process rather than editing each tenant by hand. Because codes are managed through the Fineract API, scripts can compare tenants and report differences. Ask any partner how they will detect drift, who approves a change that applies to only one tenant, and how a value is retired when it is still referenced by historical records.
Which parts of a code list change should go through approval?
Any change that affects how records are classified, reported or closed should go through a documented approval step. That includes adding or removing identifier types used in onboarding, changing closure or rejection reasons used in reporting, and altering gender or custom field values used in regulatory returns. Low-risk label corrections can follow a lighter path. Confirm with your compliance and operations leads which changes need a second reviewer, and check how your maker-checker setup in Fineract, if enabled, applies to these resources.
What should a written scope for code lists include?
A written scope should list each code and its values, the tenants in scope, the forms, reports and custom fields that depend on each list, the business owner who approves each list, the test cases and their sign-off, and the process for future changes. It should also state what is out of scope, such as data cleanup of existing records and reporting changes. Ask for the deliverables in writing, including the configuration export or change log, so your team can rebuild or audit the setup without the partner.
How DeployOpen scopes and delivers Fineract code configuration
DeployOpen plans and configures codes and code values inside your own infrastructure, on the Fineract environments you run, and agrees the scope and deliverables in writing before any work starts. The starting point is an inventory of every drop-down your staff and customers will see: identifier types, closure and rejection reasons, genders, and the code lists behind any custom fields. For each list, the written scope names the codes, the values, the tenants that use them, and who approves changes. Because the codes are managed through the legacy API resources to create, list, update and delete codes and their values, the scope should also state whether values will be created by hand in a single tenant or scripted from a reviewed source file.
Delivery covers three documented outputs. The first is the list catalog itself, with each code and value, its purpose and its owner. The second is the approval path for changes, which should be designed alongside the maker-checker setup so that a new reason or identifier type cannot go live without the same review as other state-changing work. The third is the tenant replay process, a written record of how an approved change is applied to each tenant in the same order, checked in each one, and recorded. DeployOpen can document all three so that your team can run future changes without us. Confirm with us which of these outputs your scope needs, and confirm with your own compliance team how the change records will be retained.
Ongoing support for code changes, new tenants, and Fineract upgrades is available as a retainer, which you can add to a fixed-scope configuration project or run separately. DeployOpen implements and documents Fineract work but does not hold partner, reseller or certified status with the Apache Software Foundation or any vendor, and it does not issue audit reports for the controls it helps you document. Ask for a written scope that lists the tenants, the lists in scope, the approval roles and the replay steps, so that the quote can be compared with a quote for doing the same work internally.

