What happened
A non-custodial payout reached the user-signature step and the end user declined to approve it. No funds were moved. The payout is in a terminal failed state with failureCode: USER_SIGNATURE_DECLINED.
In sandbox you trigger this state by calling POST /v2/sandbox/payouts/:id/simulate/cosign with outcome: "declined".
{
"type": "USER_SIGNATURE_DECLINED",
"title": "User signature declined",
"status": 422,
"detail": "The customer declined the payout from the approval page.",
"resolution": "Submit a new payout if the decline was unintentional.",
"docs": "/errors#user-signature-declined",
"instance": "/v2/payouts/txn_abc123",
"correlationId": "corr_xyz789",
"timestamp": "2026-01-15T09:30:00.000Z"
}
Common causes
- Intentional decline — the user reviewed the payout details and chose not to proceed
- Incorrect payout details — the amount, recipient, or asset shown on the signing screen did not match what the user expected
- Accidental decline — the user tapped the wrong button on the signing UI
Recovery
This is a terminal state. The payout cannot be recovered; a new payout must be
submitted if the user wants to proceed.
1. Confirm the terminal state
Read the payout to confirm it is terminal:
curl -X GET https://api.conduit.financial/v2/payouts/txn_abc123 \
-H "x-api-key: YOUR_API_KEY"
2. Determine whether to resubmit
If the decline was accidental or the user wants to try again, confirm the destination and amount with them first, then submit a new payout:
curl -X POST https://api.conduit.financial/v2/payouts \
-H "x-api-key: YOUR_API_KEY" \
-H "Idempotency-Key: idem_NEW_KEY" \
-H "Content-Type: application/json" \
-d '{
"customerId": "cus_abc123",
"assetAmount": {"code": "USDC", "amount": "50.000000", "chain": "ETHEREUM"},
"destination": {
"recipient": {
"rail": "CRYPTO",
"chain": "ETHEREUM",
"address": "0xabc..."
}
}
}'
Use a fresh Idempotency-Key — the prior key is bound to the declined payout.
Prevention
- Show payout details before sending — display the amount, asset, and destination address on a confirmation screen before initiating the signing step
- Handle
transaction.failed with this code — branch on failureCode === 'USER_SIGNATURE_DECLINED' to surface a clear “you declined this transfer” message rather than a generic error
The transaction.failed event fires when the payout terminates:
{
"type": "transaction.failed",
"data": {
"transactionId": "txn_abc123",
"failureCode": "USER_SIGNATURE_DECLINED"
}
}