Skip to main content
A repayment is a transaction posted against an active loan. The API lets you post a repayment, list a loan’s repayments, and read a single transaction back by id. All repayment endpoints are nested under a loan. The loan can be addressed two equivalent ways. Prefer the externalId form — it lets you drive repayment flows off the reference you already store, with no client-side mapping to a numeric LMS id.

Addressing the loan

FormPath prefixWhen to use
By loan externalId (recommended)/v1/loans/external/{loan_external_id}/repayments/...Use the externalId you supplied on loan create.
By LMS id/v1/loans/{loan_id}/repayments/...Use the numeric id from the create response.
Both forms hit the same handlers and return identical responses. The externalId form returns 404 not_found if no loan matches.
# By loan externalId (recommended)
curl -X POST "$BASE/v1/loans/external/loan-ext-12345/repayments" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"transactionAmount": 450}'

# Same effect, by LMS id
curl -X POST "$BASE/v1/loans/501/repayments" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"transactionAmount": 450}'

The repayment object

The same object is returned by repay, get a transaction, the transaction list, and as each entry of repaymentHistory on the loan object.
id
string
Unique transaction identifier. Use it on get.
type
string
Transaction type label — always Repayment. The history is restricted to customer repayments; disbursements, waivers, and accruals are excluded.
date
string
ISO-8601 YYYY-MM-DD. Value date the transaction was effective.
amount
number
Total transaction amount.
principal
number
Portion applied to principal. Omitted if zero.
interest
number
Portion applied to interest. Omitted if zero.
fees
number
Portion applied to fees. Omitted if zero.
penalty
number
Portion applied to penalty charges. Omitted if zero.
overpayment
number
Overpayment amount, present only when the transaction exceeded the outstanding balance. A strong signal that something needs reconciling.
status
string
posted for a normal transaction, or reversed if it has been reversed (an operational LMS-side action).

Endpoints

MethodPathPurpose
POST/v1/loans/external/{loan_external_id}/repaymentsRepay by loan externalId (recommended)
POST/v1/loans/{loan_id}/repaymentsRepay by LMS id
GET/v1/loans/external/{loan_external_id}/repaymentsList repayments
GET/v1/loans/external/{loan_external_id}/repayments/{transaction_id}Get a transaction
The repayment reads (list and get-one) are available in the externalId form only. Posting a repayment still supports both the externalId and numeric-id forms.

Repayment history: two ways to read it

The repayment history is available in two places, both returning the object above and both containing only customer repayments (newest first) — disbursements, waivers, and accruals are excluded:
  • Embedded snapshot — every single-loan read (GET /v1/loans/external/{loan_external_id}) includes a repaymentHistory array. Use this for a quick view without a second call. It is not included on the loan list endpoint, only on single-loan reads.
  • Paginated listGET /v1/loans/external/{loan_external_id}/repayments (reference) returns the same entries with page/rows pagination, for loans with many partial payments.

Request body

POST /v1/loans/.../repayments takes:
transactionAmount
number
required
Must be greater than 0.
transactionDate
string
Optional value date (ISO yyyy-MM-dd). Defaults to today. See Reconciling delayed settlements.
idempotencyKey
string
Optional dedupe token — typically your wallet transaction reference (max 100 characters). A repayment carrying a key already seen on the loan returns the original transaction unchanged, so retries never double-post. Strongly recommended on every repayment.
The payment method is filled in by the service.

Reconciling delayed settlements

A common integration pattern is to debit the customer’s wallet first, then call this API to settle the loan. If that settle call fails, times out, or is only retried the next day, the payment still happened on your side — and your records are the source of truth for when. Pass transactionDate set to the date the wallet was actually debited. The repayment is then booked as of that value date rather than the day the API call lands. What that does:
  • It records when the payment happened. Allocation and balances reflect the backdated date.
  • On-time payments are not penalised for your delay. If the value date is on/before the due date and the LMS had already raised a late penalty while your call was in flight, the service automatically cancels that penalty (waives and deactivates it) before posting the repayment, then lets the overdue-penalty job recompute it against whatever is genuinely still overdue:
    • Paid in full on time → nothing remains overdue → no penalty at all (net zero).
    • Partial on-time payment → the penalty is recomputed on the remaining overdue balance only. A 50,000 payment against a 100,000 principal leaves 61,000 overdue, so the penalty becomes 10% of 61,000 — not the original 100,000.
  • Late payments still bear the penalty. If the value date is after the due date, the payment is genuinely late and the penalty stands (paid penalty → interest → principal).
The recomputed penalty appears at the next run of the overdue-penalty job — the same nightly cycle that raises every penalty. So immediately after an on-time partial payment the loan shows no penalty and a reduced balance; the corrected penalty lands on the next cycle, exactly as it would have with no delay.
# Wallet debited 2026-06-01; settle call only succeeds on 2026-06-02.
# Book it as of 2026-06-01 so the delay isn't counted against the customer.
# Include the wallet reference so the call is safe to retry.
curl -X POST "$BASE/v1/loans/external/loan-ext-12345/repayments" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"transactionAmount": 11100, "transactionDate": "2026-06-01", "idempotencyKey": "wallet-txn-abc123"}'
The loan products use flat interest fixed at disbursement, so the value date never changes the interest owed. The value date must be on/after disbursement and not in the future.