Build a swap
Deposits and refunds
The order tells the user what to send: depositAddress, depositAmount (in depositTokenDecimals) and the deadline expiresAt. In practice people send a little less, a little more, twice, or late. This page covers each case. The thresholds below are live values from GET /v2/swaps/terms:
| Rule | Current value | Field |
|---|---|---|
| Deposit window | 60 minutes | depositWindowMinutes |
| A short deposit still executes from | 99% of the requested amount | partialDeposit.executesFromPercent |
| Deposits treated as dust (no notice) below | 0.5% of the requested amount | partialDeposit.noticeFromPercent |
| A short deposit continues after the window if worth at least | $10 | partialDeposit.continueFromUsd |
| Automatic recovery re-check | every 15 minutes | recoveryCheckMinutes |
| Maximum integrator fee | 5% | integratorFee.maxPercent |
Live from GET /v2/swaps/terms, read when this page was built (4 Nov 2026, 08:24 UTC).
#Deposit outcomes
| What arrives | customerState |
What happens |
|---|---|---|
At least 99% of depositAmount, or more |
processing |
The order runs on everything that arrived. An overpayment is swapped in full, not refunded. |
| A token deposit (EVM, Solana, Tron, Bitcoin) under 99% | awaiting_deposit with notice below_expected |
The user can top up the same address until expiresAt. Then the order continues on what arrived. A remainder worth less than 10 USD expires instead, and support returns it. |
| A native-coin deposit (XMR, ZEC) at or above the order minimum | processing once seen |
The order runs on what confirms. There is no top-up wait. |
| A native-coin deposit under the order minimum | awaiting_deposit with notice below_minimum |
Send the rest to the same address now. A top-up before the first deposit confirms joins it, and the order continues once the total reaches notice.minimumDepositAmount. A small deposit that confirms under the minimum on its own is set aside; support returns it. |
| A deposit parked under its minimum | paused with reason below_minimum |
With minimumDepositAmount present, a top-up to the same address that reaches it continues the order automatically. Without it, contact support. |
Nothing by expiresAt |
expired |
The address stays watched. Support recovers a late deposit. |
- Every transfer to the deposit address counts: a second transfer adds to the first, it is never a separate deposit.
observedDepositAmountis the running total. - Deposits under 0.5% of
depositAmountare treated as stray dust and show no notice. minimumDepositAmountis in the deposit asset's atomic units. What is left to send isminimumDepositAmount − observedDepositAmount.expiresAtis exact. For a short token deposit it is also the moment the top-up wait ends, so a countdown to it is precise.
#Continue early on a short deposit
While the below_expected notice is shown, the user can stop waiting and continue on what arrived:
curl -X POST 'https://api-beta.wagyu.xyz/v2/orders/<orderId>/deposit-wait/close' \
-H 'x-session-id: <sessionId>'- It works with the owner session, or with the confidential (server) integrator key of the integration that created the order. A key embedded in a browser cannot.
- Outside
below_expected, and always for native-coin deposits, it returns409. Repeating a close that already succeeded returns200. - It decides nothing by itself: the engine rechecks the deposit and continues on what arrived. You never have to call it; when the window ends the order continues on its own.
#Refund addresses
A refund needs a destination. A token deposit is refunded to the wallet it came from. For a native-coin source, such as XMR, provide the address yourself, in one of two ways:
- Up front: send
refundAddresswhen you create the order. Recommended for native-coin sources. - When asked: when
customerStateisaction_requiredwith actionrefund_address, show a form and submit it:
curl -X PUT 'https://api-beta.wagyu.xyz/v2/orders/<orderId>/refund-address' \
-H 'x-session-id: <sessionId>' \
-H 'content-type: application/json' \
-d '{ "refundAddress": "<address on the deposit chain>" }'refundRecovery on the order describes the refund:
| Field | Meaning |
|---|---|
kind |
What is returned: wrong_chain (a deposit on the wrong chain), source (a deposit whose route can never run) or table_deposit (a coinflip-table deposit the table never used). |
phase |
address_required (show the form), requested, then in_progress. |
asset, chainId, amountAtomic |
What will be returned and where. |
suggestedAddress |
An address the order already has for that chain. Pre-fill the form with it and let the user confirm or replace it. Nothing is sent until it is submitted. |
destination |
Once decided: the address, and source = customer (someone submitted it) or sender (back to the wallet the deposit came from). |
- The saved address is immutable. Submitting starts automatic recovery once safety checks pass; no other call is needed.
- One exception: a
table_depositowed by a coinflip table that already finished keeps the table's outcome as itscustomerState. Show the refund form beside the result. - A successful response confirms the address was saved, not that the refund was sent. Keep tracking until the recovery is done.
#Replacement payout addresses
When customerState is action_required with action payout_address, the order needs a new destination:
curl -X PUT 'https://api-beta.wagyu.xyz/v2/orders/<orderId>/payout-address' \
-H 'x-session-id: <sessionId>' \
-H 'content-type: application/json' \
-d '{ "payoutAddress": "<new destination address>" }'The owner session is required; an integrator key alone cannot change addresses. The replacement is write-once, and resubmitting the same address is idempotent.
#After an address is saved
Both address routes queue an immediate recovery check. If that check is blocked or cannot be queued, a scheduled re-check runs every 15 minutes (recoveryCheckMinutes). Cases that need an operator's decision stay manual. When both are pending, an explicit refund request takes priority over automatic payout recovery.
#Zcash deposit addresses
Zcash deposit addresses are shielded unified addresses. Each order also lists the same address in other forms in depositAddressForms (kind: shielded or transparent) for wallets that only support older formats.