Peach amortizes a loan in two places, and it helps to keep them separate:
- At activation, Peach builds the loan's real schedule — the periods, expected payments, and first-period obligation that servicing runs against. This is a side effect of activating a loan; it is covered by the onboarding recipes.
- The amortization utility (
POST /api/amortize) generates a schedule from inputs and returns it without touching the database — no loan is created, changed, or activated. Use it to preview payment amounts, total interest, and APR before you originate, or to render a quote in your own UI.
This page covers the standalone utility and its relationship to activation. It does not restate how to originate or activate a loan — see Onboard an installment loan and Onboard a line of credit — nor how the sandbox is provisioned; see Sandbox and test data.
Activating a loan creates its active schedule and periods, the expected payments, and the obligation for the first period — alongside setting the origination address, starting borrower monitoring, writing the activation ledger entries, and firing the activation event.
The activation request controls when amortization happens through the amortizationAtActivation field, which takes one of two values:
| Value | Meaning |
|---|---|
amortizeAtActivation | Amortize the loan as part of the activation call. |
expectedPaymentsAtOrigination | Use the expected payments established at origination. |
To inspect the schedule of a loan that has already been activated, read its expected payments rather than the utility below:
GET /api/people/{personId}/loans/{loanId}/expected-payments
X-API-KEY: <YOUR-API-KEY>The utility works in two modes, set by what you put in the request body.
Predefined loan type. Pass a loanTypeId to amortize against a loan product Peach has already configured for you. For a line-of-credit draw you can pass a loanId instead of a loanTypeId; Peach then references the loan type associated with that loan and, if you omit them, reuses the line-of-credit start date and rates from that loan.
Generic configuration. Omit loanTypeId/loanId and pass the loan-type configuration fields inline (or leave them out to use defaults). Use this to model a product that is not yet configured.
In both modes, atOrigination carries the draw- or loan-specific inputs — start date, amount financed, and duration.
POST /api/amortize
X-API-KEY: <YOUR-API-KEY>
Content-Type: application/json
{
"loanTypeId": "LT-AAAA-BBBB",
"atOrigination": {
"amountFinanced": 10000,
"duration": 12
}
}The utility requires the loan:amortize scope. For the full request contract — every atOrigination field, the inline loan-type configuration, and the promo-rate inputs — see the Loan Amortization tag in the API Reference; this page does not reproduce the field tables.
When you amortize from a predefined loan type, pass a personAddress or personAddressId and Peach checks the amortized output against any rate caps associated with that loan type. The response then reports whether the rate or APR exceeds the configured maximum (see the table below).
Predefined-mode amortization requires a real, configured loan type. When you pass a loanTypeId, Peach resolves it the same way loan creation does — a placeholder or unprovisioned ID is rejected, and the loan type must exist and match the derived installment or line-of-credit type. Generic-configuration mode (omitting loanTypeId and loanId) needs no configured loan type, since you supply the parameters inline. The sandbox uses the same resolution path; there is no sandbox-specific bypass.
The response data is an installment or line-of-credit amortization result. The headline fields answer "what will the borrower pay?"; the schedule array breaks it down per due date.
| Field | Description |
|---|---|
numberPayments | The number of expected payment due dates. |
periodicPaymentAmount | The amortized payment the borrower is expected to pay on each due date. |
totalPaymentsAmount | The total of all expected payments. |
totalInterestAmount | The total interest the loan should accrue. Rounding can make this differ slightly from the sum of per-payment interestAmount. |
totalDiscountAmount | The total discount at origination from promo rates. |
fees.originationFeeAmount | The origination fee amount, if any. |
interestRateExceedsMax / interestRateBelowMinOrZero | Whether the interest rate is above the maximum or below the minimum. |
schedule[] | Per-due-date entries with date, paymentType, amount, and — for periodicPayment rows — principalAmount and interestAmount. |
For an installment loan the result also reports APR: aprEffective, aprNominal, and the aprEffectiveExceedsMax / aprNominalExceedsMax flags that fire when the rate-cap check (above) is triggered.
| Endpoint | Use it for |
|---|---|
POST /api/amortize | Preview a single schedule for a loan or draw (this page). |
POST /api/amortize-combinations | Preview many schedules at once — combinations of duration, interest rate, promo rate, and interest cap for one amount financed. Does not support recurring dynamic fees. |
POST /api/people/{personId}/loans/{loanId}/amortize-preview | Preview amortizing an existing line-of-credit draw. The draw must have non-due principal. Requires the draw:amortize scope. |
If a line-of-credit loan type is configured with accrualMethod=compoundWithFees, draw amortization is calculated with the compound method instead. To keep interest accurate, amortized draws should not include any fees.
- Onboard an installment loan — originate and activate an installment loan end to end.
- Onboard a line of credit — originate a line of credit and its draws.
- Loan Lifecycle Quickstart — activate a loan and confirm its payment schedule.
- Core concepts — loan types, interest, and payment-schedule terms.