Create Loan
Create or update (upsert) a loan pushed from an external partner. The loan is keyed on (customer, externalReference). Returns 201 on create, 200 on update.
Overview
Create or update (upsert) a loan pushed from an external partner. The loan is keyed on the combination ofcustomerId and id (your external loan reference). If an active loan with the same external reference already exists for the customer, it is updated in place; otherwise a new loan is created.
This endpoint is designed for collections intake — all loans must be created with servicingStatus: ACTIVE.
Upsert Behavior
POST /loans is an upsert. If you push a loan that already exists (matched on id + customerId among active loans), we update the existing record. Soft-deleted or deactivated (NOT_SERVICING) loans are not matched — a new active loan is created instead.
- New loan: Returns
201 Created - Existing loan updated: Returns
200 OK - Concurrent duplicate: Returns
409 Conflict
Required Fields
Validation Rules
Balance fields (non-negative)
All monetary fields must be>= 0 when provided: totalBalance, originalFundedAmount, originalTotalOwed, totalPayoffAmount, payoffAmount, balanceAtTransfer, preTransferPayments, chargeoffAmount.
amountDue must be strictly positive (> 0).
Rate fields
interestRate and apr must be non-negative. Values are stored as decimals where 1.0 = 100%. High-interest loans can have values above 1.0 (e.g. 6.49 = 649% APR).
Chargeoff pairing
chargeoffDate and chargeoffAmount must both be set or both omitted. Setting only one returns a validation error.
Settlement percentages pairing
paymentPlanMinPercentage and paymentPlanMaxPercentage must both be set or both omitted. When set, both must be between 0 and 1, and min <= max. When both are omitted (null), the loan is pay-in-full only (no settlement discount).
For XRiver loans, when both percentages are omitted at creation and originalFundedAmount, preTransferPayments, and totalBalance are all provided, the settlement band is computed server-side: if originalFundedAmount - preTransferPayments exceeds 65% of totalBalance, the loan is pay-in-full only; otherwise it gets a 65%–90% settlement band. Sending the percentage pair explicitly overrides this. The band is set once at creation — later updates never recompute it.
Portfolio ID
portfolioId must be a valid UUID when provided. If omitted, defaults to the configured portfolio for your company.
Servicing status
servicingStatus must be ACTIVE on loan creation. To stop servicing on an existing loan, you can either upsert with servicingStatus: NOT_SERVICING (which also updates any other loan fields in the same call) or use the dedicated POST /loans/{id}/cancel-servicing endpoint. Both cancel all scheduled payments and communications.
Schedule creation
A collections schedule is automatically created on new loans based on the specifiedtaskType. The customer must have a valid IANA timezone set. taskType defaults to Collections if not specified.
Request Body
Error Responses
Authorizations
Body
Loan data
Your stable loan reference ID
"LOAN-12345"
External reference of a previously-pushed customer
"CUST-001"
Required. Date the loan was originated.
"2026-04-01"
Required. Current outstanding balance.
x >= 0425
Origination amount due. Must be positive. Immutable after creation.
125
Next payment date (YYYY-MM-DD)
"2026-05-01"
Must be ACTIVE on create. Use cancel-servicing endpoint to stop.
ACTIVE CASH_ADVANCE, PERSONAL_LOAN, INSTALLMENT_LOAN PENDING, APPROVED, FUNDED, WITHDRAWN, REJECTED x >= 0500
x >= 0650
Non-negative decimal where 1.0 = 100% (e.g. 6.49 = 649%)
x >= 00.2999
Non-negative decimal where 1.0 = 100%
x >= 00.355
x >= 0x >= 0x >= 0x >= 0Must be paired with chargeoffAmount
Must be paired with chargeoffDate
x >= 0true
CUSTOMER_OPT_OUT, LEGAL_HOLD, BANKRUPT, INCARCERATED, DECEASED, MILITARY, FRAUD, AGENCY_REQUEST, COMPLAINT, WRONG_NUMBER, OTHER CUSTOMER_OPT_OUT, LEGAL_HOLD, BANKRUPT, INCARCERATED, DECEASED, MILITARY, FRAUD, AGENCY_REQUEST, COMPLAINT, WRONG_NUMBER, OTHER CUSTOMER_OPT_OUT, LEGAL_HOLD, BANKRUPT, INCARCERATED, DECEASED, MILITARY, FRAUD, AGENCY_REQUEST, COMPLAINT, WRONG_NUMBER, OTHER true
x >= 0x >= 0Portfolio UUID for payment processor routing
Min settlement percentage (0-1). Both min+max required together. NULL = pay-in-full.
0 <= x <= 1Max settlement percentage (0-1). Both min+max required together. NULL = pay-in-full.
0 <= x <= 1Schedule task type (e.g. Collections). Defaults to Collections for JustLoans.
"Collections"
Response
Existing loan updated
External loan reference ID
External customer reference ID