useDepositAddress: true, and the user transfers funds to the returned address. The platform tracks the deposit and execution; solvers provide cross-chain fills.
This makes deposit addresses ideal for CEX withdrawals, fiat onramps, and headless systems where the sender can’t sign transactions. The user just sends to an address — same UX as a normal transfer.
How It Works
- Quote — Integrator requests a quote with
useDepositAddress: true. The response includes adepositAddressandrequestId. - User Deposit — User sends funds to the deposit address (wallet transfer or exchange withdrawal).
- Detect + Sweep — Relay detects the deposit onchain and sweeps funds to the depository contract. For open-ended addresses, the amount, currency, and chain are validated and the quote may be regenerated if different from the original. For strict addresses, the deposit is validated against the original order.
- Fill — For cross-chain orders, a solver uses its own liquidity to deliver the requested output to the recipient. Same-chain swaps execute on the deposit chain.
Key Parameters
Address Reuse
Open deposit addresses can be reused for the same route (same origin currency, origin chain, destination currency, and destination chain). Each new deposit triggers a fresh quote and fill. Strict addresses should not be presented as reusable. They are bound to the original order and intended for single-use payment instructions.Open vs Strict Deposit Addresses
Relay supports two deposit address modes that differ in how flexible they are when handling deposits.Open Deposit Addresses
Open-ended deposit addresses are the flexible mode for supported routes. They can handle variable deposit amounts, and on some supported chain families they can also adapt to a different supported input token or a deposit on a different chain within the same VM. Adapting to a different token or a wrong chain is not always automatic — recovery may require manual reindexing before the deposit is recognized.refundTois recommended. OmittingrefundTodisables automatic refund — there is no internal fallback.- Best for: general-purpose integrations where you want tolerance for user variability.
Strict Deposit Addresses
Strict deposit addresses are bound to the original order and should be treated as predictable payment instructions. They are not flexible intake points.refundTois required. The request will fail without it.- Set
strict: truein your/quote/v2request. - Best for: integrations that need predictable behavior and explicit refund handling (e.g., payment processors).
Comparison
Example Request and Response
Open Deposit Address
Bridging 0.01 ETH from Base to Optimism using an open deposit address:Strict Deposit Address
Same route, but using a strict deposit address. Note the addition ofstrict: true and the required refundTo:
strictis set totruerefundTois required — the request fails without it- The deposit address is bound to this specific order and is not reusable
Quote Regeneration
When funds arrive at a deposit address, Relay evaluates what was sent versus what was originally quoted. How mismatches are handled depends on the deposit address mode.Open-Ended Addresses
Same Token, Different Amount- Exact match — The original quote can be reused, in which case the fill proceeds under the original
requestId. Relay can still requote an exact match at sweep time (see Which Request Owns the Fill). - More than quoted — A new quote is generated for the larger amount, and the fill proceeds under a new
requestId. - Less than quoted — If the smaller amount still covers fees and the minimum fill, a new quote is generated and the fill proceeds under a new
requestId. If not, the deposit is refunded to therefundToaddress (if set).
targetChainId to the chain the funds actually landed on. Once detected, Relay sweeps the funds and proceeds with a fresh quote and fill.
Behavior varies by chain family — some families refund a wrong-chain deposit instead of re-routing it. Strict addresses have no wrong-chain recovery (see Strict Addresses).
Different Chain (Different VM)
This is not possible — deposit address formats differ across VM types (e.g., EVM vs Solana vs Bitcoin), so a user cannot accidentally send to the wrong VM.
Strict Addresses
Strict addresses are bound to the original order. The handling is narrower:- Exact amount — The fill proceeds using the original order.
- Underpayment — The deposit fails and is refunded to
refundTo. The fill does not proceed. - Overpayment (
EXACT_INPUT) — The full deposited amount is filled. The excess is not refunded — the fill scales up to cover everything that was deposited. - Overpayment (
EXACT_OUTPUT) — The fill proceeds for the originally quoted amount and the excess is returned torefundToas a separate refund leg. The fill itself is never scaled up. - Wrong token or wrong chain — Not supported. Strict addresses do not have automatic wrong-token or wrong-chain recovery paths.
requestId.
Refund Behavior
What happens when a deposit can’t be processed depends on the token type and therefundTo configuration.
Refund Flows
There are two distinct refund scenarios:- Correct currency, fill failed (e.g., slippage, network issues) — If
refundTois set, the deposit is automatically refunded to that address, minus the cost of gas. No additional fees are taken. - Wrong currency (non-solver token) — Not supported and not currently recoverable.
If a wrong solver currency was sent and the deposit didn’t auto-resolve, users can recover it at relay.link/withdraw.
A same-VM wrong-chain deposit to an open or custodial address is recoverable but may not re-route or refund on its own. Trigger reindexing with
targetChainId set to the chain the funds landed on. Strict addresses have no automatic wrong-chain recovery.refundTo Configuration
If users may send from a centralized exchange, do not set
refundTo as the user’s address — neither an explicit user address you don’t control nor the native-currency-address auto-refund opt-in — the sender address will be the exchange’s hot wallet, not the user’s. Use an app-controlled address instead so your support team can handle the last mile. If you still want depositor auto-detection for self-custodied senders, pair the auto-refund opt-in with a recoveryAddress as the fallback.When auto-refund to the original depositor is triggered, the request’s
outTxs will contain two refund transactions. The first transaction is the solver-to-depositor transfer that actually returns funds to the depositor — this is the one to track from your integration. The second is an internal protocol-settlement transaction that does not move user funds and can be ignored by integrators.recoveryAddress
recoveryAddress is for cases where Relay cannot auto-refund. It should be an integrator-controlled EOA on the origin chain.
Use recoveryAddress when an integrator wants to use Relay’s depositor detection, but also needs a fallback recovery path if the detected depositor cannot safely receive an automatic refund. This is most relevant for deposits from custodial sources like centralized exchanges, unsupported currency deposits, or blocked depositor addresses.
When recoveryAddress is supplied:
- Relay still attempts to auto-refund where possible.
- If Relay cannot auto-refund, the integrator can recover funds using
recoveryAddress. - Existing
refundTobehavior remains unchanged for flows that do not supplyrecoveryAddress.
- Requires
useDepositAddress: true— the request is rejected otherwise. - Must be a valid address on the origin chain and cannot be the origin chain’s native-currency address.
- Strict deposit addresses still require
refundToeven whenrecoveryAddressis set.
Recommended Setup
- Open deposit addresses: Set
refundToto the user’s address for automatic refunds. - Strict deposit addresses: Always set
refundTo. If the sender is unknown (e.g., CEX withdrawal), use an app-controlled address so your support team can manage refunds. - Auto-refund to depositor: When users deposit from wallets they control, you can pass
refundToas the origin chain’s native-currency address (EVM0x0000000000000000000000000000000000000000, Bitcoinbc1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqmql8k8, Solana11111111111111111111111111111111) to refund to the original depositor automatically. The first of the two resultingoutTxsis the transfer to the depositor — track that one for refund delivery. Avoid this when deposits may originate from a centralized exchange, or pair it with arecoveryAddressso funds Relay cannot safely auto-refund remain recoverable.
Tracking Transactions
TherequestId in the quote response is not always the request that fills. Depending on what arrives at the address, the sweep and fill can move to a new requestId (see Which Request Owns the Fill). Treat the deposit address as the stable identifier for the order.
Querying by Deposit Address
Poll the Get Requests API with thedepositAddress query parameter. This is the canonical way to monitor a deposit-address order, because every request that fills from the address — original or regenerated — carries the same depositAddress:
GET /requests/v2 also accepts depositAddress, but it is deprecated and will be retired on November 24, 2026.
Which Request Owns the Fill
Whether the fill runs under the quote-timerequestId depends on the deposit:
- Strict addresses — Always the original
requestId. Strict addresses are never requoted. - Open addresses, original
requestId— The first deposit matches the quote exactly (same currency and amount) and Relay does not requote it at sweep time. - Open addresses, new
requestId— Any of the following can move the sweep and fill to a regenerated request:- The deposit is a different amount or a different supported token.
- The deposit lands on a different EVM chain than the one quoted.
- The address already received an earlier deposit. Every later deposit gets its own
requestId. - Relay requotes at sweep time, even for an exact match. This happens on quotes with sponsored fees, and on EVM when the deposit is the native token or the quote has no explicit
refundTo.
depositAddress rather than by the quote-time requestId. An open address can return several requests, one per deposit. When depositAddress.depositTxHash is populated, use it to match each request to the transfer that funded it.
includeChildRequests=true does not return regenerated requests. It only adds duplicate-deposit requests to an id lookup. The depositAddress query already includes regenerated requests.
Handling Quote Regeneration
After a regeneration, what the quote-timerequestId returns depends on the origin chain:
supersededByRequestId (Bitcoin only) — On Bitcoin-origin requests, the top-level supersededByRequestId in GET /requests/v3 (or data.supersededByRequestId on the legacy GET /requests/v2) points from the original request to the regenerated one. It holds only the most recent regenerated requestId: a later deposit to the same address or a retried sweep replaces it. Until broader chain support ships, the field is null on every other chain.
Request-Level Status
Once thedepositAddress query returns the request that owns the fill, you can poll its requestId with Get Status. To avoid polling, configure a webhook instead. Webhook events are sent under the request that owns the fill, so a regenerated request’s events carry the new requestId — match them to your order with depositAddress.address in the payload.
Reindexing Stuck Deposits
Relay’s background monitor only checks the originally quoted input token. If a user sent a different supported (solver) token, the monitor may not detect it automatically. Use the Deposit Address Reindex endpoint to trigger on-demand re-detection — it checks every solver-depositable currency on the chain and queues a sweep for any non-zero balances.chainId is the chain the deposit address was originally registered on. Pass targetChainId to run the reindex on a different chain — useful when funds were sent to the right address but on the wrong chain (e.g. the address was registered for Arbitrum but funds landed on Ethereum). This is the chain being reindexed, not the destination chain of the original quote.
Pass currency to scope the reindex to a single currency address instead of iterating every depositable currency. Any currency registered with Relay on the target chain is accepted — including currencies outside the standard solver-depositable list (e.g. a HyperCore-registered token when the deposit address was created for HyperEVM).
The deposit transaction hash cannot be used to look up the status of a deposit address bridge. Track status by the deposit address, and use a
requestId only once the depositAddress query has returned it.Caveats
Gas Overhead
Deposit addresses add gas overhead compared to direct calldata execution because Relay must sweep funds from the deposit address:
For very small amounts, the gas overhead may make deposit addresses less cost-effective than direct calldata execution.
Supported Currencies
Only tokens listed as solver currencies for a given chain can be processed by deposit addresses. The input token must be a solver-depositable currency for the requested route. The destination token can differ and be completed through a destination-side swap — in that case,refundTo is required.
Relay treats certain tokens as equivalent within currency groups (e.g., ETH and WETH) — depositing any token in a group triggers the same fill behavior.
The table below is loaded live from the chains API. Each chain’s solverCurrencies array is the authoritative source for which tokens are supported.
Chain-Specific Notes
- Bitcoin — Standard deposits are processed after 1 block confirmation. High-value deposits (above the per-currency threshold) wait for 2 block confirmations to reduce reorg risk. Deposits are detected via mempool monitoring but only acted on after the applicable confirmation count.
- Solana — Supports SPL tokens through the protocol deposit method. Native SOL and SPL tokens like USDC are solver currencies on Solana.
- Hyperliquid — Uses bridged USDC (USDC.e) with different decimal precision than native USDC on other chains. Be aware of decimal mismatches when computing amounts.
Other Limitations
- Calldata execution on destination is not allowed.