# Cancel an ACH transfer

> Cancel an ACH transfer through the Moov API or Dashboard before the debit or credit originates, including cancellation windows and transfer groups.

> AI agents: search and read all Moov docs with the docs MCP server at https://docs.moov.io/mcp (no API key). Setup: https://docs.moov.io/guides/developer-tools/mcp-ai/docs-mcp/index.md

You can cancel an ACH transfer until its debit or credit is sent to the bank (originates). After that, ACH can't be canceled or refunded.

| Transfer      | Cancel until          |
|---------------|-----------------------|
| Bank → wallet | The debit originates  |
| Wallet → bank | The credit originates |
| Bank → bank   | The credit originates |

Origination happens at the next [ACH cutoff](/guides/money-movement/ach/ach-processing-speeds/index.md#cutoff-times). Canceling a transfer in a [transfer group](/guides/money-movement/transfer-groups/index.md) also cancels every transfer after it in the group, but doesn't affect future [scheduled transfers](/guides/money-movement/scheduling/index.md).

![Cancellations must occur within a specific time frame.](./images/ach-cancel-window-light.png)

Cancellations must occur within a specific time frame.

To return money after an ACH transfer originates, create a new transfer in the opposite direction. See [return funds after an ACH payment originates](/guides/get-started/recipes/refunds-cancellations/index.md#return-funds-after-an-ach-payment-originates).

## Request a cancellation

**Dashboard**

Navigate to **Transfers** in the Dashboard. If a transfer can be canceled, you'll be able to use the **Cancel** button located near the transfer amount. If the transfer is outside the cancellation window, the cancel button will be grayed out.

**API**

Request a cancellation by sending the `accountID` and `transferID` to the cancel a transfer `POST` [endpoint](/api/money-movement/transfers/cancel/index.md).

```zsh
curl -X POST "https://api.moov.io/accounts/{accountID}/transfers/{transferID}/cancellations" \
  -H "Authorization: Bearer {token}" \
  -H "x-idempotency-key: UUID" \
  -H "x-moov-version: v2026.07.00"
```

If you request a cancellation, but the transaction has already been originated, previously failed, or already completed, you'll receive a `400` error. A request made very close to origination can fail. Retrying the cancellation is possible, but likely won't be successful.

Additionally, you can get the details of a cancellation using the following:

```zsh
curl -X GET "https://api.moov.io/accounts/{accountID}/transfers/{transferID}/cancellations/{cancellationID}" \
  -H "Authorization: Bearer {token}" \
  -H "x-moov-version: v2026.07.00"
```

## Track the cancellation

A cancellation status can be one of `pending`, `completed`, or `failed`. The `achDetails` object will also show a status of `canceled` if the transfer has been successfully canceled, along with a `canceledOn` timestamp.

For bank-to-bank transfers, a cancellation will be `pending` when the debit transaction has already been originated. Moov waits for the debit to complete and subsequently credits the source wallet before the credit leg is initiated to the destination. If the source does not have a wallet, the destination wallet will be credited and you can initiate a transfer of funds back to the source bank account.

A successful request returns:

```json
{
  "cancellationID": "8df8e13c-3c20-4b4b-b265-796534cf4275",
  "status": "pending",
  "createdOn": "2023-09-09T14:15:22Z"
}
```

For updates on a pending cancellation, you can subscribe to the cancellation [webhooks](#webhooks), or get the cancellation status using the cancellation details `GET` [endpoint](/api/money-movement/transfers/cancel-details/index.md).

## Webhooks

Subscribe to the following [webhook events](/guides/webhooks/webhook-events/index.md#cancellations), which will provide you with relevant cancellation updates:

- `cancellation.created` notifies you when the cancellation was successfully created
- `cancellation.updated` notifies you when the cancellation was updated
  
  - `pending`
  - `completed`
  - `failed`

