Salary advances
Read, request, approve, and reject salary advances via the API.
The Advances endpoints let you manage salary advances — early access to earned wages, repaid from the employee’s upcoming pay.
Call https://api.kuahr.com with the company’s authorised Live key in KUA_API_KEY. The SDKs use this address by default: Node or Python. Replace the illustrative IDs with real records from this company; the public API does not list employees. Persist an operation-specific idempotency key before writes and reuse the exact request on interrupted responses.
List advances
Optionally filter by employeeId:
curl "https://api.kuahr.com/v1/advances?employeeId=b2c3…" \
-H "X-Api-Key: kua_live_your_key_here"const advances = await kua.advances.list({ employeeId: "b2c3…" });advances = kua.advances.list(employee_id="b2c3…")Amounts are in minor units (e.g. kobo) — 5000000 is ₦50,000.
Request an advance
Starts a Pending advance for an employee (advances:write):
curl "https://api.kuahr.com/v1/advances" \
-X POST -H "X-Api-Key: kua_live_your_key_here" -H "Content-Type: application/json" \
-d '{ "employeeId": "b2c3…", "amountMinor": 5000000, "termMonths": 3 }'const advance = await kua.advances.request({
employeeId: "b2c3…",
amountMinor: 5_000_000,
termMonths: 3,
});advance = kua.advances.request(employee_id="b2c3…", amount_minor=5_000_000, term_months=3)An employee can have only one open advance at a time.
Approve or reject
Approving disburses funds and builds the repayment schedule; rejecting cancels the request:
# Set ADVANCE_ID and exactly one authorised ADVANCE_DECISION.
case "$ADVANCE_DECISION" in
approve) curl -X POST "https://api.kuahr.com/v1/advances/$ADVANCE_ID/approve" -H "X-Api-Key: $KUA_API_KEY" ;;
reject) curl -X POST "https://api.kuahr.com/v1/advances/$ADVANCE_ID/reject" -H "X-Api-Key: $KUA_API_KEY" ;;
*) echo "Choose approve or reject deliberately" >&2; exit 1 ;;
esac// Execute exactly ONE authorised decision for a Pending advance.
if (decision === "approve") await kua.advances.approve(advance.id); // moves money
else if (decision === "reject") await kua.advances.reject(advance.id);# Execute only the selected authorised branch.
if decision == "approve":
kua.advances.approve(advance.id) # moves money
elif decision == "reject":
kua.advances.reject(advance.id)Events
React to the advance lifecycle via webhooks:
salary_advance.requested, salary_advance.approved, salary_advance.rejected.
Read back and reconcile
A request starts Pending. Approval requires an eligible employee, company policy and available funding; successful disbursement makes the loan Active and creates its repayment schedule. Rejection of a Pending advance makes it Cancelled; it is not a refund of an already approved advance. List advances for the intended employee again and match the ID/status, then verify the corresponding wallet/ledger outcome through the authorised product flow. A list or HTTP acknowledgement alone is not proof of a bank withdrawal.
On ADVANCE_NOT_PENDING, re-read before deciding; never follow approval with rejection. On eligibility, existing open advance, funding or disbursement errors, resolve the exact code and reconcile before another approval. Persist the same idempotency identity for uncertain responses; generating a new key or changing credentials can repeat an effect. Repayment servicing, disputes and provider settlement are separate authorised product journeys beyond these four public operations.
Done when: the selected decision is authorised, the loan state and money outcome agree, and the responsible finance/operator has evidence. For read-only integration, stop after the list. Continue with events and production readiness.