Skip to content

REST API Overview

Apache Fineract exposes a REST API over HTTPS. Every feature in the system - loans, clients, savings accounts, accounting, reports, configuration - is accessible via this API. The web UI (Mifos X) is itself an API client and uses the same endpoints.

This page covers the conventions that apply to every API call.

Base URL

All endpoints are under:

https://your-instance.finecko.com/fineract-provider/api/v1/

Replace your-instance.finecko.com with your actual Finecko instance URL.

Required Headers

Every request needs two headers:

bash
Fineract-Platform-TenantId: default
Authorization: Basic <base64(username:password)>

Fineract-Platform-TenantId - identifies which tenant's database to use. Without this header, the request is rejected with a 401. Use the tenant identifier provided at onboarding (typically default for single-tenant deployments).

Authorization - HTTP Basic Auth. Encode username:password in Base64:

bash
# Generate the header value
echo -n 'mifos:password' | base64
# → bWlmb3M6cGFzc3dvcmQ=

# Use in a request
curl https://your-instance.finecko.com/fineract-provider/api/v1/offices \
  -H "Fineract-Platform-TenantId: default" \
  -H "Authorization: Basic bWlmb3M6cGFzc3dvcmQ="

The -H "Authorization: Basic $(echo -n 'user:pass' | base64)" shorthand works in bash and is used throughout these docs.

Authentication

Fineract uses HTTP Basic Authentication. Credentials are validated on every request - there are no sessions or tokens to manage.

Getting a credential key via the authentication endpoint:

bash
curl -X POST \
  https://your-instance.finecko.com/fineract-provider/api/v1/authentication \
  -H "Fineract-Platform-TenantId: default" \
  -H "Content-Type: application/json" \
  -d '{"username": "mifos", "password": "password"}'

Response:

json
{
  "username": "mifos",
  "userId": 1,
  "base64EncodedAuthenticationKey": "bWlmb3M6cGFzc3dvcmQ=",
  "authenticated": true,
  "officeId": 1,
  "officeName": "Head Office",
  "roles": [...],
  "permissions": [...]
}

The base64EncodedAuthenticationKey is the same value you would compute manually - it is provided for convenience and can be passed directly as the Authorization: Basic value.

Service accounts: For integrations, create a dedicated user account with only the permissions the integration requires. Avoid using the admin account for API integrations. See User Management for how to create service accounts and assign minimal permissions.

Request Conventions

Content type: All write requests (POST, PUT) must include Content-Type: application/json.

Date fields: Every date field in a request body requires two companion fields: dateFormat and locale. The format string uses Java's DateTimeFormatter pattern syntax. The locale is a BCP 47 language tag.

json
{
  "activationDate": "15 March 2024",
  "dateFormat": "dd MMMM yyyy",
  "locale": "en"
}

Common date formats:

Format stringExample
dd MMMM yyyy15 March 2024
yyyy-MM-dd2024-03-15
dd/MM/yyyy15/03/2024

Use the same format string and locale consistently within a request. Mismatched formats are a frequent source of 400 errors.

Decimal values: Monetary amounts are sent as plain JSON numbers. Fineract applies the rounding mode configured for the tenant (default: half-even, ROUND_HALF_EVEN).

Response Conventions

Success responses:

  • GET requests return the resource object or an array of objects
  • POST (create) requests return { "resourceId": <id> } - the ID of the created resource
  • PUT (update) requests return { "resourceId": <id>, "changes": { ... } } - the ID and the fields that changed
  • DELETE requests return { "resourceId": <id> }

Listing responses return the array directly (not wrapped in a pagination envelope for most endpoints):

json
[
  { "id": 1, "name": "Head Office", ... },
  { "id": 2, "name": "Nairobi Branch", ... }
]

Some endpoints return richer envelopes with pageItems and totalFilteredRecords - see Pagination below.

Pagination

Endpoints that can return large result sets support offset-based pagination via query parameters:

ParameterDescription
offsetNumber of records to skip (default: 0)
limitMaximum records to return (default varies by endpoint, often 200)
orderByField to sort by
sortOrderASC or DESC

Example - list clients with pagination:

bash
curl "https://your-instance.finecko.com/fineract-provider/api/v1/clients?offset=0&limit=50&orderBy=id&sortOrder=ASC" \
  -H "Fineract-Platform-TenantId: default" \
  -H "Authorization: Basic $(echo -n 'mifos:password' | base64)"

Paginated responses return:

json
{
  "totalFilteredRecords": 1240,
  "pageItems": [ { ... }, { ... } ]
}

Use totalFilteredRecords to calculate the total number of pages.

Filtering

Most listing endpoints accept search query parameters to filter results. Common filters:

bash
# Filter clients by office
/clients?officeId=2

# Filter loans by status
/loans?loanStatus=300   # 300 = active

# Filter by external ID
/clients?externalId=CUST-1001

# Search clients by name
/clients?sqlSearch=firstname%20like%20%27Amara%25%27

The sqlSearch parameter accepts SQL-style WHERE clause fragments. Use with care - always URL-encode the value.

Idempotency

Fineract supports idempotency keys on write requests to prevent duplicate operations on retries. Pass the key in the request header:

bash
curl -X POST \
  https://your-instance.finecko.com/fineract-provider/api/v1/loans/1/transactions?command=repayment \
  -H "Fineract-Platform-TenantId: default" \
  -H "Authorization: Basic $(echo -n 'mifos:password' | base64)" \
  -H "Idempotency-Key: txn-20240315-001" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

If the same request is submitted again with the same Idempotency-Key, Fineract returns the original response without creating a duplicate transaction. Idempotency keys expire after a configured period. The header name defaults to Idempotency-Key and is configurable via FINERACT_IDEMPOTENCY_KEY_HEADER_NAME.

Error Handling

Fineract returns structured error responses with HTTP status codes and a body describing the problem.

400 Bad Request

Validation failure. The response body identifies the specific field(s) that failed:

json
{
  "developerMessage": "The request was invalid.",
  "httpStatusCode": "400",
  "defaultUserMessage": "Validation errors exist.",
  "userMessageGlobalisationCode": "validation.msg.validation.errors.exist",
  "errors": [
    {
      "developerMessage": "The parameter 'dateFormat' cannot be blank.",
      "defaultUserMessage": "The parameter 'dateFormat' cannot be blank.",
      "parameterName": "dateFormat",
      "value": null
    }
  ]
}

Common causes: missing required fields, incorrect date format, invalid enum values, referencing an entity that does not exist.

401 Unauthorized

Authentication failed or the tenant header is missing. Check credentials and the Fineract-Platform-TenantId header.

403 Forbidden

The authenticated user does not have permission for the requested action. Check the user's roles and permissions. See User Management for permission configuration.

404 Not Found

The requested resource does not exist in this tenant. Verify the resource ID and that you are using the correct Fineract-Platform-TenantId.

500 Internal Server Error

A server-side error. The response body typically contains a developerMessage with details. Contact Finecko support with the full request and response if the error persists.

The Swagger UI

An interactive API reference is available at:

https://your-instance.finecko.com/fineract-provider/api/v1/swagger-ui/index.html

The Swagger UI lists every endpoint, shows the expected request body schema, and allows you to make live API calls directly from the browser. It is the most complete reference for specific endpoint parameters and response shapes.

To authenticate in Swagger UI:

  1. Click "Authorize" at the top right
  2. Enter your Fineract-Platform-TenantId value in the tenantid field
  3. Enter your username and password in the HTTP Basic Auth fields

Common Operations Reference

Offices

bash
GET  /offices              # List all offices
POST /offices              # Create an office
GET  /offices/{id}         # Get office details
PUT  /offices/{id}         # Update an office

Clients

bash
GET  /clients              # List clients (supports pagination and filters)
POST /clients              # Create a client
GET  /clients/{id}         # Get client details
PUT  /clients/{id}         # Update a client
POST /clients/{id}?command=activate   # Activate a pending client

Loans

bash
GET  /loans                # List loans
POST /loans                # Submit a loan application
GET  /loans/{id}           # Get loan details
POST /loans/{id}?command=approve    # Approve a loan
POST /loans/{id}?command=disburse  # Disburse a loan
POST /loans/{id}/transactions?command=repayment  # Post a repayment

Savings

bash
GET  /savingsaccounts              # List savings accounts
POST /savingsaccounts              # Open a savings account
POST /savingsaccounts/{id}?command=approve    # Approve
POST /savingsaccounts/{id}?command=activate  # Activate
POST /savingsaccounts/{id}/transactions?command=deposit    # Deposit
POST /savingsaccounts/{id}/transactions?command=withdrawal # Withdrawal

Users and Roles

bash
GET  /users                # List users
POST /users                # Create a user
PUT  /users/{id}           # Update a user (including password change)
GET  /roles                # List roles
POST /roles                # Create a role
PUT  /roles/{id}/permissions  # Update role permissions

Reports

bash
GET  /reports                        # List available reports
GET  /runreports/{report-name}       # Run a report

Use the Swagger UI for the full parameter reference for each endpoint.