QSavings

Reference

Documentation

Learn how every feature in QSavings works — from authentication and group creation to contributions, loans, campaigns, and platform administration.

Authentication

QSavings uses phone-based authentication. Users register with their phone number, verify via OTP, and receive JWT tokens for all subsequent requests.

Registration & Login

FieldDefaultPurpose
Phone Number+250...The primary identity. Must be a valid Rwandan phone number. Used for login and OTP verification. No email required.
Full NameDisplay name shown throughout the platform — in group member lists, contribution records, and loan applications.
PasswordMust meet strength rules (min 8 chars, mixed case, digit). Used alongside phone number for login.

Token Management

FieldDefaultPurpose
Access Token1 hourShort-lived JWT sent with every request. Contains user ID, phone, platform role, and KYC status. Expires after 1 hour for security.
Refresh Token30 daysLong-lived token stored hashed in the database. Used to obtain new access tokens without re-entering credentials.
OTP Code6 digitsOne-time code sent to the phone number during registration. Verifies that the user owns the phone number.

Savings Groups

A savings group is the core unit in QSavings. It defines the rules for contributions, loans, and cycles. The person who creates a group automatically becomes its chairperson.

Core Identity

FieldDefaultPurpose
NameThe display name of the savings group (e.g. "Family Ntwari Savings"). Used throughout the UI to identify the group.
DescriptionOptional text explaining the group’s purpose, rules, or goals. Helps members understand what the group is about.
CurrencyRWFThe currency all financial transactions in the group are denominated in. Currently fixed to Rwandan Franc.

Contribution Rules

FieldDefaultPurpose
Share ValueThe monetary value of one “share” (e.g. 10,000 RWF). When a member contributes, they buy a number of shares. grossAmount = sharesCount × shareValue. This standardizes contributions so every member contributes in equal units.
Contribution FrequencymonthlyHow often members are expected to contribute — weekly or monthly. Drives the group’s savings cycle rhythm.

Loan Rules

FieldDefaultPurpose
Max Loan Multiplier3How much a member can borrow relative to their total contributions. If a member has contributed 100,000 RWF and the multiplier is 3, they can borrow up to 300,000 RWF. This limits risk exposure for the group.
Loan Interest Rate %2The interest rate charged on loans. When disbursed, the system calculates: totalRepayment = principal + (principal × interestRate / 100). This is how the group earns returns on its pooled savings.
Penalty Rate %5The percentage charged on late loan repayments. If a repayment is overdue past the grace period, a penalty of outstandingAmount × penaltyRate / 100 is applied. Discourages delinquency.
Grace Period (days)7Number of days after a repayment due date before the penalty kicks in. Gives borrowers a buffer for minor delays without financial consequence.

Cycle Management

FieldDefaultPurpose
Cycle Duration (months)12The length of one full savings cycle. At the end of a cycle, groups typically do a "share-out" — distributing accumulated savings and profits back to members proportional to their shares. Then a new cycle begins.
Cycle Start DateTodayWhen the current cycle begins. Auto-set to the creation date. Used to calculate cycle end date (cycleStartDate + cycleDurationMonths) and determine which contributions/loans belong to the current cycle.

Roles & Governance

Each group has a committee that governs operations. Roles are assigned per-group and checked on every request — they are never stored in the JWT token for security.

Committee Roles

FieldDefaultPurpose
ChairpersonAuto-assignedThe group creator. Has full administrative rights: invite members, manage settings, and oversee all operations. Every group has exactly one.
TreasurerAssignedResponsible for verifying and rejecting contributions. Can also approve or reject loan applications. Ensures financial accountability.
SecretaryAssignedCan verify contributions and review loan applications. Supports the treasurer in maintaining accurate records.

Access Control

FieldDefaultPurpose
MemberOn joinCan record contributions, apply for loans, pledge to campaigns, and view group data. Cannot verify contributions or approve loans.
Platform AdminSystem-wide role (not per-group). Can view all users, groups, revenue, and audit logs. Cannot interfere with group-level operations.

Contributions

Contributions are the core savings mechanism. Members buy shares at a fixed value. A platform fee is automatically deducted, and the net amount is credited to the group pool.

Formula

grossAmount = shares × shareValue | fee = gross × 5% | net = gross − fee

How Contributions Work

FieldDefaultPurpose
Shares CountThe number of shares the member is buying. The gross amount is calculated as sharesCount × group shareValue. This ensures standardized, equal-unit contributions.
Gross AmountCalculatedThe total contribution before fees. Example: 2 shares × 10,000 RWF = 20,000 RWF gross.
Platform Fee (5%)CalculatedAutomatically deducted from the gross amount. Fee = grossAmount × 0.05. Recorded in the platform_fees table and the immutable ledger.
Fee Rate SnapshotLocked at recordThe contribution fee rate is snapshotted onto the contribution row at the moment it is recorded. If a platform admin changes the rate later, your existing pending or verified contribution is unaffected — it keeps the rate that was in effect when you created it.
Net AmountCalculatedThe amount actually credited to the group pool. netAmount = grossAmount − fee. Example: 20,000 − 1,000 = 19,000 RWF.

Verification Workflow

FieldDefaultPurpose
PendingOn recordInitial status when a member records a contribution. Awaits committee verification.
VerifiedA committee member (treasurer or secretary) confirms the contribution is valid. Only verified contributions count toward loan eligibility.
RejectedA committee member rejects the contribution with a reason (e.g. incorrect amount). The member can correct and resubmit. The original platform fee is reversed: a contribution_fee_reversal entry is appended so the platform_fees aggregate for the rejected contribution nets to zero.

Loans

Members borrow against their verified contributions. Loans require unanimous committee approval, and repayments are tracked with interest and penalty enforcement.

Formula

maxLoan = verifiedContributions × multiplier − activeBalance | repayment = principal + (principal × interest%)

Eligibility

FieldDefaultPurpose
Max Loan AmountCalculatedmaxLoan = totalVerifiedContributions × group maxLoanMultiplier − activeLoansBalance. If a member contributed 100,000 RWF verified and the multiplier is 3, they can borrow up to 300,000 RWF minus any outstanding loan balance.
Active Loan BlockA member can only have one active loan per group at a time. They must fully repay before applying again.
Defaulted Loan BlockIf a member has any defaulted loans, they are blocked from new applications until resolved.

Approval Process

FieldDefaultPurpose
Committee ReviewALL must actEvery committee member must review the application. ALL must approve for the loan to proceed. ANY single rejection causes the entire loan to be rejected.
Serializable IsolationApproval decisions use database serializable isolation to prevent race conditions when multiple committee members review simultaneously.
Review CommentEach committee member can leave a comment explaining their approval or rejection reason. Recorded in the audit log.

Loan Lifecycle

FieldDefaultPurpose
PendingOn applyLoan application submitted. Awaiting committee review.
Under ReviewAt least one committee member has reviewed, but not all have acted yet.
ApprovedAll committee members approved. Ready for disbursement from the group pool.
DisbursedFunds released to the borrower. Repayment schedule begins. Interest calculated: totalRepayment = principal + (principal × interestRate / 100).
Interest Fee SnapshotLocked at applyThe platform's loan-interest fee rate (default 2%) is captured onto the loan at the moment the borrower applies. Every future repayment uses that snapshotted rate — even if a platform admin changes the group's fee config later, the borrower's quoted cost is locked from day one.
CompletedAll repayments made. The loan is fully settled. Member can now apply for a new loan.
RejectedAt least one committee member rejected the application. The member can apply again with adjustments.

Social Fund Campaigns

Campaigns are group-level fundraisers for members in need. Any member can be the beneficiary. Other members pledge amounts, and progress is tracked against a target.

Campaign Setup

FieldDefaultPurpose
TitleA short name for the campaign (e.g. “Medical Fund for Alice”). Displayed on campaign cards and lists.
DescriptionDetails about why the campaign was created and how the funds will be used. Helps members decide whether to pledge.
Target AmountThe fundraising goal in RWF. Progress is tracked as a percentage of this target. Example: 500,000 RWF.
BeneficiaryThe group member who will receive the collected funds. Selected from the current member list.

Pledges & Fees

FieldDefaultPurpose
Pledge AmountThe amount a member commits to the campaign. Members can pledge any amount. Multiple pledges are allowed.
Platform Fee (5%)CalculatedDeducted from total collected funds when the campaign completes. fee = totalCollected × 0.05. Recorded in ledger.
Progress0%Visual percentage showing collectedAmount / targetAmount. Displayed as a progress bar on campaign cards.

Campaign Lifecycle

FieldDefaultPurpose
ActiveOn createCampaign is open for pledges. Members can contribute funds toward the target.
CompletedTarget reached or committee closes the campaign. Funds (minus platform fee) are released to the beneficiary.
CancelledCampaign terminated before completion. Pledges may be refunded depending on group rules.

Platform Administration

Platform admins have a bird’s-eye view of the entire system. They can monitor users, groups, revenue, and audit trails but cannot interfere with group-level operations.

Dashboard Metrics

FieldDefaultPurpose
Total UsersCount of all registered users on the platform, including verified and unverified accounts.
Total GroupsCount of all savings groups created across the platform. Includes active and inactive groups.
Total ContributionsSum of all verified contributions across all groups, in RWF. Gives a sense of platform savings volume.
Platform RevenueTotal fees collected: contribution fees (5%) + loan interest fees (2%) + campaign fees (5%). Broken down by fee type.

Fee Configuration

FieldDefaultPurpose
Per-Group OverrideOptionalPlatform admins can override any default fee rate (contribution, loan interest, campaign, payout) on a per-group basis through the group's Settings page. Stored in group_config_overrides and resolved at runtime with Redis caching.
Effective FromNowEvery fee change carries an effective date. Defaults to the moment the change is applied, but admins can schedule changes for a future date. The admin UI exposes a date-time picker for fee rows.
Snapshot RuleFee changes apply only to NEW contributions and loans recorded on or after the effective date. Existing in-flight loans and pending contributions are NEVER retroactively affected — their fee rate was snapshotted onto the row when they were originated. The admin UI shows a confirmation dialog re-stating this guarantee before any fee change is committed. See backend ADR-002.

Audit & Compliance

FieldDefaultPurpose
Audit LogImmutable record of every state change: contribution verifications, loan approvals, campaign completions, role assignments. Includes actor, action, entity, and timestamp.
Ledger EntriesAppend-only financial ledger. Every franc in, out, or transferred is recorded. Cannot be edited or deleted. Ensures full financial traceability.
Platform FeesDetailed breakdown of every fee charged: which transaction, fee type (contribution/loan/campaign), gross amount, fee amount, and net amount.

Security & Data Integrity

QSavings is designed for financial trust. Every transaction is recorded immutably, every mutation is idempotent, and every role check happens at request time.

Authentication Security

FieldDefaultPurpose
JWT Tokens1h / 30dAccess tokens expire after 1 hour. Refresh tokens last 30 days and are stored hashed in the database. Short-lived tokens minimize damage from token theft.
Phone VerificationRequiredUsers must verify their phone number via OTP before accessing the platform. Prevents fake account creation.
Per-Request Role CheckGroup roles are never stored in the JWT. Every request checks the database for the user’s current role in the target group. Prevents stale permissions.

Data Integrity

FieldDefaultPurpose
Idempotency KeysUUID v4Every mutation (POST/PUT) requires a unique idempotency key. If the same key is sent twice, the second request returns the original result without re-processing. Prevents duplicate transactions.
Immutable LedgerAll financial transactions write to an append-only ledger. Entries cannot be updated or deleted. Provides an unalterable audit trail for every franc.
Serializable TransactionsCritical operations like loan approvals use serializable database isolation. Prevents race conditions and ensures consistency.
RFC 7807 ErrorsAll errors return a standard Problem Details JSON object with type, title, status, detail, and instance. Makes error handling predictable for all clients.

Ready to explore the API?

Try endpoints interactively with Scalar API Reference.

Open API Reference