# Vault deposit

Endpoint reference for the 1delta API. Index: https://docs.1delta.io/llms.txt · every endpoint: https://docs.1delta.io/llms-full.txt

---

### GET /v1/actions/vaults/deposit

- operationId: `vault-deposit`
- docs: https://docs.1delta.io/1delta-api/vault-deposit/
- markdown: https://docs.1delta.io/1delta-api/vault-deposit.md
- tags: Vaults (Actions)

Vault 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.deposit` when 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 `vault` and built via the protocol's mint path, including protocol-specific prep (e.g. StakedCelo validator-group selection — see `validatorGroup`).
- **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` + `operator` call 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. `payAsset` is free (defaults to the PT's underlying); the chosen trade is in `transactions`, every quote in `alternatives`. This is what `/v1/data/earn` marks `via: '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](https://docs.1delta.io/1delta-api/vaults-gmx/), Hypercore via `interface=hypercore` below. Passing one to the auto path returns `UNRESOLVED_UNDERLYING`.
>
> `/v1/actions/vaults/lst` and `/v1/actions/vaults/savings` remain as back-compatible aliases for their specific flows.

**Execution mode** (`mode` query param, ERC-4626 path)

- `auto` (default) — direct when `payAsset === underlying` and not native, otherwise composer.
- `direct` — force direct; returns 400 when not eligible (e.g. native `payAsset`).
- `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) then `action=claimDeposit` (mint once fulfilled). Pass `controller` when it isn't `operator`. Track the pending request via [/v1/data/vaults/withdrawals](https://docs.1delta.io/1delta-api/vaults-withdrawals/).
- `erc7575` — **multi-asset** vaults (share ≠ entry token). `isShares` switches deposit-by-assets vs mint-by-shares.
- `hypercore` — **HyperLiquid** multi-leg deposit route (explicit only). `amount` is uint64 micro-USD (USDC); `source` picks the funding origin and the response is a structured `legs[]` array (each with its own `chainId`/`async`) rather than `transactions[]`.

**Parameters**

| Name | 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`** — Transaction calldata + approval(s) for the vault deposit. `interface=hypercore` returns a structured `legs[]` route instead of `transactions[]`.

| 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**

```json
{
  "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"
      }
    ]
  }
}
```

**Response `400`** — Validation error

**Response `429`** — Rate limited. Unauthenticated callers share a per-IP budget; send an `x-api-key` header to lift it. Retry with exponential backoff.

**Response `500`** — Unexpected server error. Safe to retry with backoff.

**Response `502`** — 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.
