Skip to main content
The Save App loan system lets members request funds against their accumulated savings and gives admins the tools to review and act on those requests. Members can list their own loans and submit new requests, while admins see all loans across the group and can approve or reject pending ones.

Loan statuses

A loan moves through the following statuses during its lifecycle:

List loans

Retrieve a paginated list of loans. Members only see their own loans; admins see all loans in the group. Filter by status using the status query parameter.

Query parameters

string
Filter loans by status. Accepted values: pending, approved, active, completed, rejected, overdue.
number
default:"20"
Number of loans to return per page. Minimum 1, maximum 100.
number
default:"0"
Number of loans to skip before returning results. Use with limit for pagination.

Response fields

object[]
Array of loan objects matching the query.
number
required
Total number of loans matching the query, before pagination.
number
required
The limit value applied to this response.
number
required
The offset value applied to this response.

Example


Submit a loan request

Submit a new loan request on behalf of a member. The requesting member must not have an existing active or pending loan, and the amount must not exceed their eligibility (3× total contributions).

Request body

string
required
Full name of the member requesting the loan. Must match an existing member record. Minimum 2 characters, maximum 100 characters.
number
required
Loan principal in the group’s currency. Must be greater than 0 and must not exceed the member’s maximum eligibility (3× their total contributions).
number
required
Repayment duration in months. Minimum 1, maximum 24.
string
required
Purpose of the loan. Minimum 2 characters, maximum 200 characters.
string
Full name of the guarantor. Minimum 2 characters, maximum 100 characters.
string
Ugandan phone number for the guarantor. Must match the pattern ^\+?256[0-9]{9}$.
string
A unique key (maximum 100 characters) to make the request idempotent. If you submit a request with an idempotency_key that was already used, the API returns the original loan response instead of creating a duplicate.

Response

Returns a loan object with status: "PENDING".

Example


Approve a loan

Record an admin’s approval for a pending loan. Approval requires unanimous consent from all active admins in the group. Each admin must call this endpoint separately; the loan status changes to ACTIVE only after every admin has approved.
This endpoint is restricted to admin users. A loan remains in PENDING status until all active admins have approved it. The API response indicates how many approvals have been recorded so far (e.g., 2/3 admins have approved).

Path parameters

string
required
The unique identifier of the loan to approve.

Response

boolean
required
true when the approval was recorded successfully.
string
required
A human-readable message indicating either that approval is unanimous and the loan is now ACTIVE, or showing the running tally (e.g., "2/3 admins have approved").

Example


Reject a loan

Reject a pending loan request. Only admins can reject loans. The rejection reason is appended to the loan’s existing reason field for audit purposes.

Path parameters

string
required
The unique identifier of the loan to reject.

Request body

string
required
Explanation for the rejection. Minimum 2 characters, maximum 200 characters. This is appended to the loan record as [REJECTED: <reason>].

Response

boolean
required
true when the loan was rejected successfully.
string
required
Confirmation message, e.g. "Loan rejected".

Example