Skip to main content
POST
Record a repayment
Records a standard repayment against an active loan. The amount is allocated to interest then principal according to the loan’s processing rules. Two equivalent forms — prefer the externalId form for partner integrations.

Path parameters

string
required
The loan’s externalId. On the /v1/loans/{loan_id}/repayments form, this is the numeric LMS id instead.

Request body

number
required
Must be greater than 0.
string
Optional value date of the payment, in ISO yyyy-MM-dd. Books the repayment as of the day the money actually moved on your side rather than the day you call this API — the reconciliation case where a wallet debit succeeds but settling with us is delayed (a failure, timeout, or a next-day retry). Defaults to the current date when omitted. Must be on or after the loan’s disbursement date and not in the future. Backdating across a later transaction already recorded on the loan may be rejected by the ledger.
string
Optional exact instant the money moved on your side, RFC3339 (e.g. 2026-08-08T13:15:00+03:00). Also fixes transactionDate (which must agree if both are sent). Send it on every settlement. Penalties are posted at the loan’s exact dueDateTime, so a date alone cannot tell a payment made at 13:15 from one made at 13:25 on the same day: with transactionAt the service can prove the customer paid before the penalty instant and waive a penalty that was posted while your settle call was in flight. See Reconciling delayed settlements.
string
Optional dedupe token — typically your wallet transaction reference for this payment (max 100 characters). If a repayment carrying this key has already been recorded on the loan, the original transaction is returned unchanged: the retry neither double-posts nor re-runs penalty reconciliation. Strongly recommended on every repayment so timeouts and retries are safe to replay. Use a value unique per payment, and see Timeouts and retries.

Examples

Response

200 OK returns the repayment object showing how the amount was allocated, plus the loan’s post-repayment position so you can decide what to do next without follow-up reads. The idempotencyKey you posted is echoed back (and on every later read of the transaction).
string
The loan’s status after this payment — Active, Closed (obligations met), or Overpaid.
number
What is still owed on this loan after the payment. 0 means the loan is settled.
number
What the customer can borrow now, across all their loans — the same figure as GET /v1/credit-scorecard. Per the integration rule, a customer with any outstanding balance has 0 available (so after a partial repayment this is always 0); only a customer whose last balance this payment settled sees their full finalCreditLimit. On the rare occasion the scoring service cannot be reached, the field is omitted — fall back to the scorecard endpoint.
The position fields appear only on this POST response. Ledger reads (list, get-one, and the repaymentHistory embedded in the loan detail) return pure transaction objects; on an idempotent replay the position reflects the loan at the time of the retry, which is what “remaining balance” means then.

Errors