What happened
An inbound transfer was sent back before Conduit could credit it to the customer. The transaction is in a terminalfailed state.
One code covers two situations, and they do not look the same on the wire. What decides it is where the money was headed, not which rail it arrived on:
Read the case that matches where the funds were going. Branching on
failureCode alone works for the first and never fires for the second — on either rail.
Case 1: the deposit was sent back before it was credited
A deposit headed for your customer’s own virtual account or wallet was sent back to where it came from before Conduit credited it — either because the sending institution reversed it, or because it was returned during review.Common causes
- Insufficient funds at the originating institution — the sender’s account did not have sufficient funds when the transfer was processed
- Account closed or invalid — the originating account was closed or the transfer details were invalid
- Sender-initiated reversal — the sender requested a recall or reversal of the transfer before it cleared
Recovery
1. Confirm the terminal statestatus: "failed" and failureCode: "returned_by_sender".
2. Notify the customer
The inbound transfer was not credited. The customer should be informed that the transfer was returned and that they should contact the sender for the return reason and next steps.
3. Do not resubmit on behalf of the sender
The original transfer is gone: it went back to where it came from, and neither Conduit nor the customer can recall it. A new transfer from the sender is required.
Case 2: a funding transfer was sent back
A transfer arrived at a funding address — the address a deposit-funded order publishes — and was sent back to the address it came from. The deposit ends instatus: "failed" with a neutral failureMessage and no failureCode:
failed deposit, funded, returned and available are all absent too — so the deposit alone does not tell you where the money went.
Common causes
- The sending address was not registered — the transfer came from an address that is not a registered address on the customer, so it was not accepted
- No order claimed the transfer — nothing was waiting for the funds, or the order it was meant to fund had already expired
- The transfer could not be accepted — it was not eligible to be credited
How to reconcile
Do not branch onfailureCode. Reconcile against the order and against the return transaction instead.
1. Read the order the transfer was meant to fund
The order reports its own outcome. A transfer that is not accepted never funds anything, so the order cannot reach its total and expires at its deadline.
2. Find the return transaction
Money sent back is its own transaction, type: "deposit_return", carrying returnOf — the id of the deposit it returns:
returnOf to your deposit’s id. Once the return is completed, destination.txHash is the on-chain hash of the refund, so you can verify it on chain and tie it to your own records.
returnOf is present whenever Conduit can still resolve the deposit a return came from, so a return with no returnOf is not evidence about your deposit either way. If you find no return naming your deposit, match on the sending address and amount instead, and contact support if it stays unclear — do not read the absence as proof that nothing was sent back.
3. Tell the customer what to do next
If the sending address was not registered, register it and have the customer send again. Contact support if the deposit keeps failing.
Prevention
- Handle
transaction.failedby where the deposit was headed — for a deposit into your customer’s own virtual account or wallet, branch onfailureCode === 'returned_by_sender'. For a transfer into a funding address that branch never runs on either rail: key offtypeandstatus, then look for the paireddeposit_return - Register sending addresses before the customer sends — see registered addresses
- Do not retry automatically — neither case is recoverable by retrying the original transfer; a new transfer from the sender is required
Related webhooks
transaction.failed fires when the return is recorded. On a deposit into your customer’s own account it carries the code:
transaction.created and transaction.completed, and the completed event carries the same destination.txHash as the read.
Related endpoints
- GET /v2/transactions/:id — read transaction state
- GET /v2/transactions — filter with
type=deposit_returnto find a return - Deposit-funded orders — how funding addresses, returns and the rolled-up fields work
- Registered addresses — registering the addresses a customer may send from