After migration succeeds, you may need to correct data or handle borrower disputes. Peach supports a specific set of post-migration modifications, with constraints that reflect the migration draw's read-only nature and the system's data integrity rules.
| Action | How | Notes |
|---|---|---|
| Dispute a historical purchase | POST .../draws/{drawId}/purchases/{purchaseId}/disputes | Creates a type: "refund" purchase with an effective date after the cutoff. Lowers draw balance using standard refund functionality. |
| Waive or cancel a historical fee | PUT .../fees/{feeId}/cancel | Changes fee status to canceled and depletes the fee balance. If fee balance is already zero, depletes draw principal instead. |
| Change a past transaction's status | PUT .../migration/past-transaction/{txnId} | Allowed transitions: pending → succeeded, and pending/succeeded → failed. For transitions to failed, the system uses drawSplitDetails from the original transaction to increase draw balances. |
| Reverse a historical transaction | POST .../transactions/{txnId}/reverse | Creates a reversal transaction. For each entry in drawSplitDetails, increases the corresponding draw's non-due principal balance. |
| Correct and re-create with same external ID | Clear the external ID on the original object, then create a new one | For purchases: update with externalId: null. For transactions: cancel with clearExternalId: true. |
| Apply balance adjustments | Service credits (POST .../transactions) or adjustment fees (POST .../fees) | Use for post-validation balance discrepancies. See Adjust balances. |
The following are the API code examples for each supported modification type.
If a borrower disputes a purchase that occurred before the migration cutoff date:
POST /api/people/{personId}/loans/{loanId}/draws/{drawId}/purchases/{purchaseId}/disputes
Content-Type: application/json
{
"reason": "unauthorized",
"amount": 249.99
}Cancel a fee that was charged before the migration cutoff date:
PUT /api/people/{personId}/loans/{loanId}/fees/{feeId}/cancelUpdate the status of a past transaction (e.g., marking a pending payment as succeeded or failed):
PUT /api/people/{personId}/loans/{loanId}/migration/past-transaction/{transactionId}
Content-Type: application/json
{
"status": "failed"
}For transitions to failed, the system requires drawSplitDetails from the original transaction to know which draw balances to increase. These details are only available via the migration-specific endpoint (GET .../migration/past-transaction), not the standard transactions endpoint. If drawSplitDetails is null, the status change to failed will be rejected.
Reverse a past transaction to undo its effect:
POST /api/people/{personId}/loans/{loanId}/transactions/{transactionId}/reverseIf you need to delete and re-create a purchase or transaction with the same external ID:
- Purchases: Update the purchase with
externalId: nullto release the external ID, then create a new purchase with the original external ID. - Transactions: Cancel the transaction with
clearExternalId: trueto release the external ID, then create a new transaction with the original external ID.
These constraints exist because of how the migration draw and historical data are stored:
Migration draw is disabled after migration. You cannot post new purchases, transactions, or fees to the static draw. All new activity must target actual draws.
drawSplitDetailsrequired for past-transaction status changes tofailed. When marking a past transaction asfailed, the system needs to know which draws to increase balances for. IfdrawSplitDetailsis null (which can happen for transactions that pre-date the migration cutoff), the status change tofailedwill be rejected.drawSplitDetailsonly available via migration endpoint. Past-transactiondrawSplitDetailsare returned byGET .../migration/past-transaction, not by the standardGET .../transactionsendpoint. If you need draw allocation details for a historical transaction, always use the migration-specific endpoint.Past periods are read-only. Statement-cycle snapshots created via
POST .../migration/past-periodscannot be modified after migration succeeds. If you need to correct a past period, you would need to cancel and re-migrate the loan.Cannot reverse acceleration or charge-off for loans migrated with a non-null
postMigrationLoanStatus. If a loan was created withpostMigrationLoanStatus: "accelerated"orpostMigrationLoanStatus: "chargedOff"(meaning it was in that state before the cutoff date), the system blocks reverse-acceleration and reverse-charge-off operations. Loans that are accelerated or charged off after migration (through normal DLM processing) can be reversed normally.Cannot add new past periods after migration. The past-periods endpoints are only available while the loan is in
prepMigrationstatus.
| Action | Why |
|---|---|
| Post new activity to the migration draw | Static draws are disabled after migration |
| Modify past period data | Past periods are read-only snapshots |
Change migrationStatus back to prepMigration | Migration status can only move forward in the lifecycle |
Reverse accel/charge-off for loans created with postMigrationLoanStatus | These status changes preceded the migration cutoff; the system considers them historical |
Mark a past transaction as failed without drawSplitDetails | The system needs draw allocation data to reverse the transaction's balance impact |
- After LOC migration — Validate balances and post-migration system behavior.
- LOC migration procedure — Create the historical data these modifications act on.