Promise-to-pay
Capture a specific borrower commitment, approve out-of-policy terms, suppress redundant outreach, and evaluate the promise against posted payment facts.
A promise-to-pay is a structured commitment with covered debt, amounts, dates, guardrail decision, and evaluation state. It is never just a case note, and creating it does not move money.
Lifecycle
Harbor commitment
On May 1, Harbor is 22 days past due for $517.14. Maya commits to pay $260 on May 8 and $257.14 on May 22.
The implemented route uses a numeric case ID and records an in-guardrail promise immediately. If the terms exceed configured bounds, the same call returns the exact materialized approval request instead:
POST /v1/servicing/cases/1001/promises
Idempotency-Key: harbor-promise-2027-05-01-v1
{
"loanRef": "7204",
"planType": "INSTALLMENT",
"installments": [
{ "amount": { "amount": 260.00, "currency": "USD" }, "dueDate": "2027-05-08" },
{ "amount": { "amount": 257.14, "currency": "USD" }, "dueDate": "2027-05-22" }
],
"reason": "Customer confirmed the two-part commitment.",
"evidenceIds": [8801]
}
The following prefixed-ID shape is the roadmap contract:
POST /v1/servicing/cases/case_HBR_COL_51/promises
Idempotency-Key: harbor-promise-2027-05-01-v1
{
"loanId": "7204",
"commitments": [
{ "amount": "260.00", "dueDate": "2027-05-08" },
{ "amount": "257.14", "dueDate": "2027-05-22" }
],
"sourceInteractionId": "int_HBR_CALL_91",
"borrowerConfirmedAt": "2027-05-01T10:18:42-07:00"
}
The response explains each guardrail tested: maximum horizon, minimum covered percentage, installment count, first-payment timing, and any product-specific rule. It returns ACTIVE only if terms are inside policy or already approved.
Money movement is separate
A promise can optionally reference future payment instructions, but it does not authorize a debit. Each later payment must have its own valid authorization and follow the payment lifecycle. This separation allows a borrower to keep a promise through the portal, ACH, card, lockbox, or another posted source.
Evaluation rules
Evaluation uses posted, value-dated payment facts from the authoritative system. The policy defines:
- which loan and transaction types count;
- whether early payments count and how they map to installments;
- grace time and the evaluation timezone;
- how reversals and returns reopen a result; and
- whether one payment can satisfy more than one promise.
For Harbor, if $260 posts effective May 8 and $257.14 posts effective May 22, the promise becomes KEPT. If the second ACH is processing on May 22, evaluation remains pending under the covering-payment policy; it does not prematurely mark kept. If that debit later returns, the prior evaluation is reversed with a linked event and follow-up work opens.
In the current runtime, payment events and scheduled servicing jobs trigger this evaluation; there is no caller-triggered promise-evaluation endpoint. The explicit evaluation route is on the roadmap.
Outreach suppression
An active promise can suppress redundant collection outreach for the covered debt and interval. Required notices, borrower-initiated responses, unrelated obligations, and legally permitted exceptions remain separately evaluated. Suppression exposes its source promise and expiry so a worker knows why a channel is unavailable.
Revision and cancellation
Revision creates a new promise version and re-runs guardrails. The prior version becomes SUPERSEDED; payments already credited to it remain visible. Cancellation requires actor, reason, borrower request or policy basis, and effective time. A broken promise is not cancelled merely to improve performance reporting.
Both are the same implemented command, distinguished by operation:
curl -X POST "$BASE/v1/servicing/cases/1001/promises/6101/revise" \
-H "Authorization: Bearer $TOKEN" \
-H "LendEasy-Tenant: demo-lender" \
-H "Content-Type: application/json" \
-d '{
"operation": "REPLACE",
"planType": "SINGLE",
"promiseDate": "2026-08-08",
"promiseAmount": { "amount": 250.00, "currency": "USD" },
"reason": "Customer requested a one-week extension."
}'
{
"outcome": "COMPLETED",
"promiseId": 6102,
"supersedesPromiseId": 6101,
"resourceId": 6102
}
A replacement returns a new promiseId and names what it superseded. Nothing edits promise 6101 in place, so its terms and approval history stay readable beside the commitment that replaced them. The replacement re-runs current guardrails: an extension that was in policy last week can come back as an approval request today. UPDATE_SERVICING_PROMISE authorizes both operations.
GET /v1/servicing/cases/{caseId}/promises returns the case’s promises alongside the guardrail bounds in force — maxHorizonDays, minAmountPercent, maxInstallments, and the outOfBoundsApprovalRole. Read those bounds before proposing terms to a borrower so the workspace can warn that an extension will need approval rather than discovering it at submit.
Reporting measures
Track created, approved, kept, partially kept, broken, cancelled, and superseded promises by terms and segment. Keep “kept at first evaluation” distinct from “later reversed after payment return,” and measure outreach suppressed without conflating it with successful payment.