Cancel loans
You can cancel loans in two ways: cancel a single loan, or cancel all active loans on an account. The platform processes both operations asynchronously and returns an HTTP 202 response. You must send the Idempotency-Key header with each request.
You can either enable your end-users to cancel their loan or have configurations automatically cancel loans. The bulk loan cancellation option works similarly where you can either have manual actions cancel all loans or trigger a workflow that cancels all loans and then also cancel related credit cards.
To understand the impact of canceling a loan, refer to Cancel loans in Loan management overview.
Cancel a single loan
If you cancel a loan before disbursement, the platform might not charge the borrower. If you cancel a loan after disbursement, the borrower must repay the disbursed amount. When you cancel a loan, the platform cancels all expected transfers and moves the loan to the CANCELED status, which will then create loan reversals with an authorization ID and tracking ID. For more information about loan statuses, refer to Loan statuses overview.
To cancel a loan, use the Cancel loan endpoint. Send the Idempotency-Key header with the request payload. Include the tracking_id; you can optionally add a list of the related processing_code and metadata.
Request payload
{
"tracking_id": "5c075cc6-8dc2-4fe6-9ed7-cf5687d4e834",
"processing_code": {
"booking": "7DJ8L",
"repayment": "I1I7J",
"penalty_waiver": "80Y39"
},
"metadata": {
"cancellation_reason": "Write-off"
}
}The platform processes the cancellation asynchronously. The endpoint returns the cancelled_loan_id along with a reversal_authorization_id and reversal_tracking_id that you can use to correlate the reversal.
Response payload
{
"cancelled_loan_id": "73e45fd5-759f-4e04-a88a-7172fa948afa",
"reversal_authorization_id": 123456789,
"reversal_tracking_id": "4df987e3-8179-11ed-8209-06c7b022d1ee"
}The Pismo platform generates a Loan updated event that reflects the transition to the CANCELED status within the current_status parameter:
Loan updated event
{
"cid": "7da3db3b-400d-4851-a362-2022dab27284",
"loan_id": "73e45fd5-759f-4e04-a88a-7172fa948afa",
"org_id": "TN-89e56522-726a-453e-ba6d-796b03245128",
"account_id": 12176,
"product_id": "89e56522-726a-453e-ba6d-796b03245128",
"program_id": 9000,
"currency": "USD",
"amount": 1000.00,
"previous_status": "ACTIVE",
"current_status": "CANCELED",
"created_at": "2026-10-24T21:34:47.000Z",
"updated_at": "2026-10-24T21:34:47.000Z",
"authorization_cancellation_id": 123456789,
"authorization_cancellation_tracking_id": "4df987e3-8179-11ed-8209-06c7b022d1ee"
}Troubleshooting single loan cancellation
If the Cancel loan endpoint returns an error, check the response code against the following table:
| Code | HTTP status | Cause | How to resolve |
|---|---|---|---|
ELND0010 | 400 | The request omits the Idempotency-Key header. | Add the Idempotency-Key header and retry. |
ELND0004 | 400 | The platform declined the cancellation's reversal authorization (the response includes response_code and denial_code). | Read the denial_code and response_code to find the reason. Then, call Get loan to confirm the loan's state, account's status, and limits. After you fix the cause, retry with a new Idempotency-Key. The original request already completed as a denial, so reusing a key replays the request. |
ELND0001 | 500 | The platform hit an unexpected error. | Capture the x-cid you sent. Because the platform processes cancellation asynchronously, first confirm whether it took effect by calling Get loan or checking for the Loan updated event. If you retry, reuse the same Idempotency-Key. If the error persists, escalate to Pismo support with the x-cid and the error code. |
Cancel all loans for an account
To cancel every active loan on an account in a single request, use the Cancel all loans by account endpoint. Because this operation works at the account level, you must provide an account-specific access token in addition to the Idempotency-Key header.
The request body contains a single boolean field, bring_to_present_value (default false):
false— the platform cancels the loans against their booked balances.true— the platform calculates interest and charges up to the cancellation date, then cancels the loans against those present-value amounts.
Request payload
{
"bring_to_present_value": true
}Because the platform processes the cancellation asynchronously, the response doesn't report a terminal status for each loan. It returns total_to_be_canceled and a canceled_loans array, where each entry pairs a loan_id with the tracking_id of its cancellation authorization.
Response payload
{
"total_to_be_canceled": 2,
"canceled_loans": [
{
"loan_id": "550e8400-e29b-41d4-a716-446655440000",
"tracking_id": "4df987e3-8179-11ed-8209-06c7b022d1ee"
},
{
"loan_id": "550e8400-e29b-41d4-a716-446655440001",
"tracking_id": "5ef098f4-9280-12fe-9310-07d8c133e2ff"
}
]
}The platform generates one Loan updated event per canceled loan, each reflecting the transition to the CANCELED status. To confirm completion, consume these events or poll Get loan until each loan reports CANCELED.
This endpoint cancels the account's loans only. It doesn't close the account or change its status. However, the delinquency closure flow drives account closure and status changes, and when driven to completion, the platform then closes any associated credit accounts.
If you do not want this downstream effect, we recommend setting up different credit card accounts and loan accounts so the platform does not have that account-level association.
Troubleshooting multiple loan cancellation
If the Cancel all loans by account endpoint returns an error, check the response code against the following table:
| Code | HTTP status | Cause | How to resolve |
|---|---|---|---|
ELND0010 | 400 | The request omits the Idempotency-Key header. | Add the Idempotency-Key header and retry. |
ELND2107 | 400 | The accountId path parameter is invalid (for example, zero or negative). | Send a valid account ID, and confirm you're using the internal Pismo account ID rather than an external one. |
ELND2106 | 400 | The account has no active loans to cancel. | Treat this as a no-op rather than a failure — the account has nothing to cancel. Don't loop-retry; list the account's loans (GET /v2/accounts/{accountId}/loans?status=ACTIVE) to confirm before you retry. |
ELND0002 | 403 | The x-account-id header doesn't match the accountId in the path. | Create an account-specific token (set account_id or uid to the account), and make sure both x-account-id and the token's account match the accountId in the path. |
ELND0001 | 500 | The platform hit an unexpected error. | Capture the x-cid you sent. Because the platform processes cancellation asynchronously, first confirm whether it took effect by listing the account's loans or checking for the Loan updated events. If you retry, reuse the same Idempotency-Key. If the error persists, escalate to Pismo support with the x-cid and error code. |
Because both cancellation endpoints return
202before the cancellation completes, a successful response doesn't guarantee success. The platform reports failures that happen after the202through alending_errorevent (which carrieserror_code,error_message,loan_id,account_id, andcid). Subscribe to that event along with Loan updated to catch cancellations that fail after the platform accepts the request.
Updated about 17 hours ago