Vault deposit
GET/v1/actions/vaults/deposit
The single deposit entry point for every share-token vault. The protocol, interface, and underlying are resolved from the vault (share token), so a deposit needs only vault + amount + operator.
What it routes, all from the share token
- ERC-4626 family — savings, Morpho, Fluid, Euler-Earn, Silo, Gearbox, Lagoon, Yearn. Routes directly to
vault.depositwhen no wrap/swap is needed; otherwise the 1delta Composer (wraps native ETH, handles composition). - LST / liquid-staking mints — stETH, wstETH, weETH, rETH, stCELO, pumpBTC, Solv, Core, native-staked, … Resolved from the calldata-sdk registry by
vaultand built via the protocol's mint path, including protocol-specific prep (e.g. StakedCelo validator-group selection — seevalidatorGroup). - ERC-7540 async and ERC-7575 multi-asset vaults — detected via an ERC-165 probe.
- Pendle Principal Tokens — a PT has no deposit leg at all: it is a zero-coupon bond BOUGHT on Pendle's AMM (and sold to exit). Detected from the token list, then built as a trade through the spot meta-aggregator, so the same
vault+amount+operatorcall works.slippage(bps) is REQUIRED here and has no default — this leg settles against a pool, not a protocol-set price, so an unbounded fill accepts any price.payAssetis free (defaults to the PT's underlying); the chosen trade is intransactions, every quote inalternatives. This is what/v1/data/earnmarksvia: 'swap'.
underlying and interface are read on-chain (asset() + ERC-165) when omitted; pass them explicitly to skip the reads. For Fluid margin vaults (NFT-position lending markets), use /v1/actions/lending/deposit instead.
Not handled here: GMX (GM/GLV) and Hypercore vaults are USD-denominated / multi-leg, not
asset()-based share tokens, so they keep dedicated flows — GMX via /v1/actions/vaults/gmx, Hypercore viainterface=hypercorebelow. Passing one to the auto path returnsUNRESOLVED_UNDERLYING.
/v1/actions/vaults/lstand/v1/actions/vaults/savingsremain as back-compatible aliases for their specific flows.
Execution mode (mode query param, ERC-4626 path)
auto(default) — direct whenpayAsset === underlyingand not native, otherwise composer.direct— force direct; returns 400 when not eligible (e.g. nativepayAsset).proxy— force the composer (legacy behavior).
The direct path is smaller (one call to the vault) and sidesteps the EVC indirection that the composer triggers. Approval target also changes: direct → the vault; proxy → the composer.
Native deposits
Native ETH is supported via the composer's wrap-then-deposit path (mode=proxy, or auto falls back automatically), and natively by most LST mints (payAsset=0x0). Fluid fToken vaults expose a payable depositNative that skips wrapping — opt in with provider=fluid.
Async / multi-asset / Hypercore (interface query param)
Auto-detected for ERC-7540/7575; only Hypercore needs an explicit interface:
erc7540— async vaults. Two-phase:action=requestDeposit(default, escrow assets) thenaction=claimDeposit(mint once fulfilled). Passcontrollerwhen it isn'toperator. Track the pending request via /v1/data/vaults/withdrawals.erc7575— multi-asset vaults (share ≠ entry token).isSharesswitches deposit-by-assets vs mint-by-shares.hypercore— HyperLiquid multi-leg deposit route (explicit only).amountis uint64 micro-USD (USDC);sourcepicks the funding origin and the response is a structuredlegs[]array (each with its ownchainId/async) rather thantransactions[].
Plain-text reference — GET /v1/actions/vaults/deposit
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
chainId | query | string | yes | Chain ID See the ChainId schema for the full set of supported chains. |
vault | query | string | yes | Share-token address — ERC-4626 vault or LST share token. The protocol/interface is resolved from it. (Alias: shareToken.) |
underlying | query | string | no | Vault's asset() (real ERC-20 — never the zero address). Resolved on-chain from vault when omitted; required only for vaults without an asset() getter. Not needed for LST share tokens. |
amount | query | string | yes | Amount in wei. Interpreted as assets unless isShares=true. |
operator | query | string | yes | User wallet executing the deposit (payer) |
payAsset | query | string | no | What the user actually pays. Defaults to underlying. Zero address or the 0xEEEE… sentinel = native ETH (composer wraps before depositing). |
slippage | query | string | no | Basis points. Pendle PTs only, and REQUIRED there — that leg is a trade against an AMM, so there is no protocol-set price to fall back on and no safe default. Ignored by every other vault family. |
receiver | query | string | no | Share recipient. Defaults to operator. The composer mints shares directly to this address. |
isShares | query | boolean | no | When true, amount is treated as shares (mint) rather than assets (deposit). |
isAll | query | boolean | no | Full-balance deposit. Relaxes the exit-sweep tolerance so dust does not revert the tx. |
provider | query | fluid | no | Optional provider hint. Currently only fluid is recognized — it opts into Fluid's payable depositNative path when paying native ETH. |
mode | query | auto, direct, proxy | no | Execution mode. auto (default) routes direct when no wrap/swap is needed, composer otherwise. direct forces vault-direct (returns 400 if ineligible). proxy forces the composer. |
interface | query | erc4626, erc7540, erc7575, hypercore, native-wnlp | no | Vault interface. Auto-detected via ERC-165 when omitted (erc4626/erc7540/erc7575), or from the savings registry for Native wNLP (native-wnlp → depositAndWrap, which also fills in underlying — wNLP has no asset() to probe). Pass hypercore explicitly for HyperLiquid (USD multi-leg). LST share tokens are routed by registry regardless of this param. |
action | query | requestDeposit, claimDeposit | no | interface=erc7540 only — requestDeposit (default) escrows assets; claimDeposit mints once fulfilled. |
controller | query | string | no | interface=erc7540 controller, when not operator. |
validatorGroup | query | string | no | StakedCelo (stCELO) only — validator group to vote for. A changeStrategy(group) step is prepended (account-wide). Auto-selected when omitted and the caller is on the (reverting) default strategy; pass the zero address to force the default. Other LST options (poolId, kind, referral, …) from /vaults/lst are also accepted here. |
minUsddOut | query | string | no | sUSDD PSM zap only (payAsset = USDT/USDC into the sUSDD vault) — the 18-decimal USDD amount the deposit leg uses after the PSM swap. AUTO-QUOTED when omitted: the route reads the PSM’s live tin fee and the gem decimals and computes amount·10^(18−dec) − fee. Pass explicitly to pin a quote. |
source | query | hypercore-perp, hypercore-spot, hyperevm, arbitrum | no | interface=hypercore deposit funding origin. |
hyperEvmUsdc | query | string | no | interface=hypercore, source=hyperevm — the HyperEVM USDC token address. |
Response 200
| Field | Type | Description |
|---|---|---|
success | True | |
data | object | Informational data (quotes, simulation results, etc.) |
actions | object | Transaction calldata and approvals. Null for quote-only responses (no account provided). |
actions.transactions | object[] | Pre-trade setup transactions (e.g. e-mode switch, collateral enable). Execute these before the main swap. Empty when no setup is needed. |
actions.transactions[].to | string | Target contract address |
actions.transactions[].data | string | Encoded calldata |
actions.transactions[].value | string | ETH value to send with the transaction |
actions.transactions[].description | string | Human-readable label. For alternatives, this is the aggregator name (e.g. "Paraswap"). For transactions, describes the setup action (e.g. "Switch e-mode to 1"). |
actions.alternatives | object[] | DEX aggregator swap transactions sorted by best output (descending). Each entry's description is the aggregator name. The client should pick one to execute. Present on loop action endpoints. |
actions.alternatives[].to | string | Target contract address |
actions.alternatives[].data | string | Encoded calldata |
actions.alternatives[].value | string | ETH value to send with the transaction |
actions.alternatives[].description | string | Human-readable label. For alternatives, this is the aggregator name (e.g. "Paraswap"). For transactions, describes the setup action (e.g. "Switch e-mode to 1"). |
actions.permissions | object[] | Approval/delegation transactions that must execute before both transactions and alternatives. Includes ERC20 allowances (targeting the composer contract) and lender borrow/withdrawal delegations (targeting the lending protocol contract directly). Filtered against on-chain state so only missing approvals are returned. Null when no approvals are needed. |
actions.permissions[].to | string | Target contract address |
actions.permissions[].data | string | Encoded calldata |
actions.permissions[].value | string | ETH value |
actions.permissions[].description | string | Human-readable description of the approval (e.g. "Approve borrow for AAVE_V3", "Approve ERC20") |
actions.permissions[].spender | string | ERC-20 approve spender (x-chain permissions). Match it against the selected quote's approvalTarget — several bridges can share one spender, so do not match by description. |
Example response
{
"success": true,
"data": {},
"actions": {
"transactions": [
{
"to": "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2",
"data": "0x617ba037000000000000000000000000c02aaa39b2",
"value": "0",
"description": "string"
}
],
"alternatives": [
{
"to": "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2",
"data": "0x617ba037000000000000000000000000c02aaa39b2",
"value": "0",
"description": "string"
}
],
"permissions": [
{
"to": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"data": "0x617ba037000000000000000000000000c02aaa39b2",
"value": "0",
"description": "string",
"spender": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
}
]
}
}
Request
Responses
- 200
- 400
- 429
- 500
- 502
Transaction calldata + approval(s) for the vault deposit. interface=hypercore returns a structured legs[] route instead of transactions[].
Validation error
Rate limited. Unauthenticated callers share a per-IP budget; send an x-api-key header to lift it. Retry with exponential backoff.
Unexpected server error. Safe to retry with backoff.
An upstream data source or protocol origin failed (error.code is ORIGIN_FAILED). error.details carries the per-origin status. This is also what a missing or malformed required parameter currently returns, rather than a 400.