/api/v1/portfolio/loans/{id}/payments
Record a payment against a loan.
- Scope
portfolio:write- Rate limit
- 100 requests / min
- Idempotency
Idempotency-Keysupported
Authentication
Send your key as Authorization: Bearer …. It must carry the scope portfolio:write; a key without it receives 403 forbidden.
Path parameters
idstringrequiredHeaders
Idempotency-KeystringReplays the first response for a repeated request. Reusing a key with a different body is idempotency_key_reused (409), never a silent replay.
Request body
application/jsonrequiredamountintegerrequiredmin 1max 10000000methodstring (enum)requiredachcheckcashcardwiremoney_orderotherreferencestringmax length 100datestringRefused parameters13
Sending any of these returns 400 validation_error naming the field. Each entry explains what to do instead.
loan_id'loan_id' is not accepted: the loan is taken from the URL path.
loanId'loanId' is not accepted: the loan is taken from the URL path.
recorded_by'recorded_by' is not accepted: a payment is always attributed to the API key that recorded it.
recordedBy'recordedBy' is not accepted: a payment is always attributed to the API key that recorded it.
amount_cents'amount_cents' is not accepted, and 'amount' is NOT cents: every amount on this API is in WHOLE DOLLARS. $10,378.00 is 10378, not 1037800. Amounts below one dollar cannot be recorded.
principal_applied'principal_applied' is not accepted: allocation is computed by the servicing waterfall (late fees, then interest, then principal) and is returned on the response.
interest_applied'interest_applied' is not accepted: allocation is computed by the servicing waterfall (late fees, then interest, then principal) and is returned on the response.
late_fee_applied'late_fee_applied' is not accepted: allocation is computed by the servicing waterfall (late fees, then interest, then principal) and is returned on the response.
overpayment'overpayment' is not accepted: any amount left after the waterfall is computed and returned on the response.
new_balance'new_balance' is not accepted: the resulting balance is computed from the payment and returned on the response.
status'status' is not accepted: a recorded payment is always 'applied'. Reversing a payment is a separate operation.
scheduled_payment_id'scheduled_payment_id' is not accepted: the payment is applied to the loan's earliest open installment automatically.
idempotency_key'idempotency_key' is not accepted as a body field: send it as the 'Idempotency-Key' HTTP header.
Response
201application/jsonSerializedPaymentpayment_idstringrequiredloan_idstringrequiredamountnumberrequiredWHOLE DOLLARS. Every money field on this object is.
principal_appliednumberrequiredinterest_appliednumberrequiredlate_fee_appliednumberrequiredoverpaymentnumberrequirednew_balancenumberrequiredWhole dollars: the loan's remaining balance after this payment was applied.
statusstringrequiredOne of applied, pending, reversed, refunded.
methodstringrequiredOne of ach, check, cash, card, wire, money_order, other — always a value the request could have sent.
referencestring | nullrequirednullablescheduled_payment_idstring | nullrequirednullableThe installment this payment was applied to, or null when the loan has no open installment left. Chosen by servicing, not by the caller.
effective_datestring | nullrequirednullableBUSINESS DATE — a calendar day, never an instant.
recorded_bystringrequiredapi_key:<keyId>. Never body-supplied.
recorded_atstring | nullrequirednullableAn INSTANT: when the row was written, not the business date.
Errors
The statuses this operation can return, with the error.code values behind each. Every error body is the shared envelope described under Errors in Getting started.
400validation_error401unauthorized403forbidden404not_found409conflictidempotency_key_reused429rate_limit_exceeded500internal_error