Cancel a Transfer

How do I cancel a funding transfer or crypto withdrawal?

Overview

Cancel an in-progress funding transfer or crypto withdrawal with DELETE /api/transfers/{transfer_guid}. Cancellation is best-effort: the platform attempts to stop the transfer before it settles, but the outcome depends on how far the transfer has already progressed at the payment provider.

A cancellation request moves an eligible transfer to the cancelling state. The transfer then resolves to one of two terminal states — failed (cancelled successfully) or completed (the transfer settled before the cancellation took effect).

ℹ️

API version required

This operation is available from API version 2026-04-01. Send the Accept-Version: 2026-04-01 header (or a later version) on the request. Earlier versions do not expose this operation and return 404. See API Versioning.

Which transfers can be cancelled

Only funding and crypto transfers can be cancelled, and only in an early state. The platform accepts a cancellation request when the transfer's type, side, and state match a row below:

Transfer typeSideCancellable states
fundingdepositstoring, pending, reviewing
fundingwithdrawalstoring, pending, reviewing, holding
cryptowithdrawalstoring, holding

A withdrawal in holding has not yet been sent to the payment provider or the blockchain, so it can still be cancelled; its hold_details.kind is dispatch. A deposit in holding has already received its funds and cannot be cancelled. Crypto deposits cannot be cancelled, and a crypto withdrawal in pending or reviewing has already been submitted and cannot be cancelled.

Other transfer types — such as instant_funding and book — are not supported by this endpoint; where those types support cancellation, they use a different flow (for example, see Instant funding). A transfer already in completed or failed cannot be cancelled. A request against a transfer that does not match a row in the table returns 422 transfer_not_cancellable.

Request a cancellation

Send a DELETE request with the transfer's GUID. No request body is required, and the token must carry the transfers:execute scope:

DELETE /api/transfers/{transfer_guid}
Accept-Version: 2026-04-01
Authorization: Bearer YOUR_TOKEN
{
  "guid": "transfer_guid",
  "transfer_type": "funding",
  "customer_guid": "customer_guid",
  "quote_guid": "quote_guid",
  "asset": "USD",
  "side": "deposit",
  "state": "cancelling",
  "failure_code": null,
  "amount": 10000,
  "fee": 0
}

The 200 response returns the transfer in the cancelling state. This confirms the request was accepted — not that the transfer was cancelled.

Best-effort cancellation and the race

cancelling is a transient state. When you request a cancellation, the platform records the request and asks the running transfer workflow to stop. Whether the transfer can actually be stopped depends on the payment provider, which is the final authority on the outcome.

Two outcomes are possible:

  • Cancellation succeeds — the transfer transitions from cancelling to failed with failure_code: cancelled.
  • Cancellation loses the race — the transfer settled at the provider before the cancellation took effect, so it transitions from cancelling to completed, as if it had not been cancelled.
⚠️

There is no cancelled transfer state

A successfully cancelled transfer ends in state: failed with failure_code: cancelled, not in a cancelled state. Do not wait for a cancelled state — check for the terminal failed or completed state instead.

Confirm the outcome

Because cancellation is asynchronous, confirm the terminal state after requesting it. Poll GET /api/transfers/{transfer_guid} until the transfer leaves cancelling:

{
  "guid": "transfer_guid",
  "transfer_type": "funding",
  "state": "failed",
  "failure_code": "cancelled"
}

Alternatively, subscribe to webhooks. The platform emits a transfer.cancelling event when the transfer enters cancelling, followed by a terminal transfer.failed event (with failure_code: cancelled) or a transfer.completed event. There is no transfer.cancelled event.

Errors

Statusmessage_codeMeaning
422transfer_not_cancellableThe transfer cannot be cancelled in its current state or is not an eligible transfer type.
404not_foundNo transfer matches the supplied GUID.
403invalid_scopesThe access token is missing the required transfers:execute scope.
{
  "status": 422,
  "error_message": "Transfer cannot be cancelled in its current state",
  "message_code": "transfer_not_cancellable"
}

A 404 can also mean the request targeted an API version earlier than 2026-04-01, which does not expose this operation. Confirm the Accept-Version header before treating a 404 as a missing transfer.

Next steps


Did this page help you?