Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.digiflecttech.dev/llms.txt

Use this file to discover all available pages before exploring further.

The Payouts API handles the distribution of group funds to members. Only admins can initiate and approve payouts. Every payout is created with a PENDING status and is executed only after all active admins have approved it. When a payout executes, the group balance is debited, the configured retention percentage is kept in the group fund, and the member receives a push notification.

Get the payout queue

For an ordered queue that respects each member’s credit score, use GET /api/cycles/{cycle_id}/queue instead. That endpoint returns the PayoutQueue for a specific cycle, where members are ranked by their credit_score_at_generation and assigned a sequential position. This ensures fairer, score-based ordering rather than sorting only by total contributions paid.
Return a list of members who are currently eligible to receive a payout. This endpoint is restricted to admins. GET /api/payouts/queue A member appears in this list when all three conditions are true:
  • role is member
  • has_received_payout is false
  • is_active is true
Results are ordered by contribution_paid descending — members who have contributed the most appear first.

Response

Returns an array of MemberEntity objects.
id
string
required
Unique member identifier.
name
string
required
Member’s full name.
phone
string
required
Member’s phone number in Uganda format (+256XXXXXXXXX).
role
string
required
Always member for records in this list.
contribution_paid
number
required
Total amount this member has contributed so far.
shortfall_amount
number
required
Outstanding shortfall amount for this member.
has_received_payout
boolean
required
Always false for records in this list.
is_active
boolean
required
Always true for records in this list.
credit_score
integer
required
Member’s current credit score (range 300–850, starting value 500).
reliability_label
string
required
Human-readable eligibility label, e.g. "ELIGIBLE".
is_eligible
boolean
required
Whether the member is eligible for a payout.
created_at
string
required
ISO 8601 datetime when the member account was created.

Example

curl --request GET \
  --url "https://api.saveapp.example/api/payouts/queue" \
  --header "Authorization: Bearer <token>"

Get cycle payout queue

Retrieve the ordered payout queue for a specific cycle. Members are ranked by their credit score at the time the queue was generated. GET /api/cycles/{cycle_id}/queue

Path parameters

cycle_id
string
required
The UUID of the cycle whose queue you want to retrieve.

Response

Returns an array of PayoutQueueResponse objects ordered by position.
id
string
required
Queue entry identifier.
member_name
string
required
Display name of the member.
position
integer
required
1-indexed position in the payout queue for this cycle.
credit_score_at_generation
number
The member’s credit score at the time the queue was generated.
has_received_payout
boolean
required
Whether this member has already been paid out in this cycle.
payout_date
string
Scheduled payout date for this position, if set.
actual_payout_date
string
The date the payout was actually executed, once completed.

Example

curl --request GET \
  --url "https://api.saveapp.example/api/cycles/cyc_xyz789/queue" \
  --header "Authorization: Bearer <token>"

Initiate a payout

Create a payout for a member. Admin only. The payout is saved in PENDING status and requires unanimous admin approval before funds are moved. A retention amount is automatically withheld based on the retention_percentage in the system configuration. POST /api/payouts
If the group balance is insufficient to cover the requested amount, the API returns a 400 error that includes the exact shortfall: "Insufficient group balance. Need {shortfall} more". Resolve the shortfall by collecting additional contributions before retrying.

Request body

memberPhone
string
required
Member’s phone number in Uganda format (+256XXXXXXXXX or 256XXXXXXXXX). Used to look up the recipient.
amount
number
required
Gross payout amount. Must be greater than 0 and must not exceed the payout_amount value in the system configuration. The net amount disbursed to the member will be lower after the retention percentage is applied.
deferRemaining
boolean
default:"false"
When true, any amount that cannot be paid immediately is deferred rather than cancelled.
idempotency_key
string
A unique string (max 100 characters) you generate per request. If a payout with this key already exists, the server returns {"success": true, "message": "Payout initiated. Awaiting approval."} without creating a duplicate.

Response

success
boolean
required
true when the payout record was created successfully.
message
string
required
"Payout initiated. Awaiting approval." on success.

Example

curl --request POST \
  --url "https://api.saveapp.example/api/payouts" \
  --header "Authorization: Bearer <token>" \
  --header "Content-Type: application/json" \
  --data '{
    "memberPhone": "+256701234567",
    "amount": 500000,
    "deferRemaining": false,
    "idempotency_key": "payout-jane-cycle-3"
  }'

Approve a payout

Submit an admin’s approval for a pending payout. Admin only. The system requires unanimous approval — the payout executes only once every active admin has approved it. POST /api/payouts/{id}/approve When unanimous approval is reached:
  1. The group balance is debited by the gross payout amount.
  2. The configured retention_percentage is kept in the group fund (retention_amount is stored on the payout record).
  3. The member’s has_received_payout flag is set to true.
  4. A push notification is sent to the member.
The response message includes the current approval count so you can track progress: "Approval recorded. {count}/{total} admins have approved."

Path parameters

id
string
required
The UUID of the payout to approve.

Request body

adminEmail
string
required
Email address of the admin submitting this approval (2–100 characters).
txId
string
Optional external transaction reference ID for audit purposes.

Response

success
boolean
required
true when the approval was recorded.
message
string
required
"Payout approved unanimously by all {n} admins and has been executed." when unanimous, or "Approval recorded. {count}/{total} admins have approved." when more approvals are still needed.

Example

curl --request POST \
  --url "https://api.saveapp.example/api/payouts/pay_d4e5f6g7/approve" \
  --header "Authorization: Bearer <token>" \
  --header "Content-Type: application/json" \
  --data '{
    "adminEmail": "admin@savegroup.ug"
  }'