LendEasy/Docs
Get API keys
RecipesLendingOriginate a loan

Originate a loan

Create Harbor as a native loan application, approve the exact contract, read the automatically finalized Reg Z disclosure, and create the approval-gated funding.

Time
~8 min
Surface
LMS API
Steps
4
Gate
Configured product · Reg Z · approval
EndpointsPOST /v1/loansPOST /v1/loans/{loanId}?command=approveGET /v1/loans/{loanId}/summaryPOST /v1/loans/{loanId}/fundings

This recipe creates the fictional Harbor Personal Loan: $8,400.00 principal, 18 monthly installments, a 13.25% nominal annual rate, and a $252.00 prepaid finance charge.

1

Create the submitted application

Native wire format
POST/v1/loans

clientId is the numeric value of Maya’s customerId, and productId names a product whose LendEasy configuration is complete. The application uses the native wire format: term fields are enum-coded—2 is months for the term and repayment frequency, 0 is declining balance, 1 is equal installments—and every body that carries a date declares its own dateFormat and locale. externalId is your correlation key.

curl -X POST "$BASE/v1/loans" \
  -H "Authorization: Bearer $TOKEN" \
  -H "LendEasy-Tenant: demo-lender" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: origination-HBR-2026-001" \
  -d '{
    "clientId": 412,
    "productId": 3,
    "loanType": "individual",
    "principal": 8400.00,
    "loanTermFrequency": 18,
    "loanTermFrequencyType": 2,
    "numberOfRepayments": 18,
    "repaymentEvery": 1,
    "repaymentFrequencyType": 2,
    "interestRatePerPeriod": 13.25,
    "interestType": 0,
    "interestCalculationPeriodType": 1,
    "amortizationType": 1,
    "transactionProcessingStrategyCode": "advanced-payment-allocation-strategy",
    "expectedDisbursementDate": "2026-08-12",
    "submittedOnDate": "2026-08-11",
    "externalId": "origination-HBR-2026-001",
    "dateFormat": "yyyy-MM-dd",
    "locale": "en",
    "charges": [{ "chargeId": 12, "amount": 252.00 }]
  }'
{ "officeId": 1, "clientId": 412, "loanId": 7204, "resourceId": 7204 }

No loan balance or payout exists yet. The authoritative amortization schedule is embedded in the loan itself—read it at any time with GET /v1/loans/7204?associations=repaymentSchedule.

2

Approve the exact contract

APR finalized here
POST/v1/loans/7204?command=approve

Approval binds the credit decision to the approved amount and expected disbursement date. It is also the Regulation Z moment: the APR disclosure is computed and finalized automatically at approval—a failed disclosure blocks approval—and is revalidated at disbursement, superseding and refinalizing if the facts changed.

curl -X POST "$BASE/v1/loans/7204?command=approve" \
  -H "Authorization: Bearer $TOKEN" \
  -H "LendEasy-Tenant: demo-lender" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: approve-harbor-decision-8" \
  -d '{
    "approvedOnDate": "2026-08-11",
    "approvedLoanAmount": 8400.00,
    "expectedDisbursementDate": "2026-08-12",
    "dateFormat": "yyyy-MM-dd",
    "locale": "en"
  }'
{ "officeId": 1, "clientId": 412, "loanId": 7204, "resourceId": 7204 }

The loan becomes APPROVED, not ACTIVE. Approval authorizes the contract; posted funding creates the balance.

3

Read the finalized disclosure

Reg Z actuarial
GET/v1/loans/7204/summary

There is no disclosure route to call—read the aprDisclosure block from the loan summary. Harbor’s APR is higher than 13.25% because Maya receives $8,148.00 after the prepaid finance charge but repays $9,308.52.

curl "$BASE/v1/loans/7204/summary" \
  -H "Authorization: Bearer $TOKEN" \
  -H "LendEasy-Tenant: demo-lender"
{
  "loanRef": "7204",
  "customerRef": "412",
  "aprDisclosure": {
    "status": "FINALIZED",
    "method": "REG_Z_ACTUARIAL_APPENDIX_J",
    "apr": "17.29",
    "financeCharge": "1160.52",
    "amountFinanced": "8148.00",
    "totalOfPayments": "9308.52",
    "currency": "USD",
    "toleranceApplied": "REGULAR",
    "finalizedAt": "2026-08-11T18:00:05Z"
  },
  "asOf": "2026-08-11T18:00:06Z"
}

The response is trimmed to the disclosure block. Before approval, the same block computes a non-persisted PREVIEW on each read. See APR & disclosures for the full equation and independent verification.

4

Create the funding

Second approver
POST/v1/loans/7204/fundings

There is no disburse command on the loan—money moves only through the funding API. A DISBURSEMENT requires the loan to be APPROVED, may not exceed the approved principal, and starts in APPROVAL_REQUIRED; it has not touched the rail or ledger. Instrument 705 is Maya’s verified deposit instrument, added exactly as in Add & verify a payment instrument.

curl -X POST "$BASE/v1/loans/7204/fundings" \
  -H "Authorization: Bearer $TOKEN" \
  -H "LendEasy-Tenant: demo-lender" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: fund-harbor-initial" \
  -d '{
    "amount": "8400.00",
    "currency": "USD",
    "fundingType": "DISBURSEMENT",
    "recipientType": "BORROWER",
    "recipientRef": "412",
    "instrumentId": 705,
    "rail": "ACH",
    "reason": "Initial disbursement for approved loan."
  }'
{ "fundingId": 5107, "loanRef": "7204", "status": "APPROVAL_REQUIRED" }

The $252.00 prepaid finance charge is assessed on the loan at disbursement, so the funding carries the full $8,400.00 principal while the disclosure’s amount financed is $8,148.00. An active DISBURSEMENT_HOLD restriction blocks creation.

Approved, not yet funded. Continue to Fund a disbursement to approve the funding as a second user and watch the payout submit, settle, and post.
Unified search across guides, recipes & the API referenceEsc