> ## Documentation Index
> Fetch the complete documentation index at: https://core.vanish.trade/llms.txt
> Use this file to discover all available pages before exploring further.

# Lending

> Open a lending position, use the advanced funds, and settle it via the Vanish Core API on behalf of your platform users.

Lending advances funds from Vanish's trading accounts into a one-time wallet and runs your own instructions against them in the same transaction - deploying into any lending provider you choose. Unlike a trade, the wallet is reused for the life of the position.

A position is [**opened**](#open-a-position), then [**settled**](#settle) when you are done. There is no deposit step of its own - the funds are advanced by Vanish. Initiate still validates balances before it signs anything, and rejects with a `400` if there is insufficient balance for the token. Every request except the commit needs a signature - see [Signing](/guide/integration/signing).

<Info>
  Lending endpoints are namespaced under `/borrow` in the API - the paths are the API's own names, and the flow is the one described here.
</Info>

***

## Open a Position

<Steps>
  <Step title="Get a one-time wallet for the position">
    ```json POST /borrow/smart-wallet theme={null}
    {
      "user_address":   "<user's Solana wallet address>",
      "protocol_label": "kamino-lend-v2",
      "timestamp":      "<unix milliseconds>",
      "user_signature": "<one-time wallet signing format>"
    }
    ```

    ```json Response theme={null}
    {
      "smart_wallet_id": 4821,
      "address":         "7yQmA1p9K4xTb3dRfN2sVzE6uYhLc8jWq5vXgMn3v3Nf"
    }
    ```

    `protocol_label` is free-form text identifying the provider this position belongs to - any lending provider works, since your instructions are passed through unchanged. Store `smart_wallet_id` against the position: every later call identifies it by that, and the wallet is provisioned once, not per action.
  </Step>

  <Step title="Build your instructions">
    Assemble your own deposit or open instructions into a single **unsigned** transaction, with the wallet `address` as the **signer and fee payer**. Base64-encode it as `main_tx`.

    Vanish appends its own instruction, signs the result, and simulates it before returning. A transaction that fails simulation is rejected rather than submitted.
  </Step>

  <Step title="Open the position">
    ```json POST /borrow/initiate theme={null}
    {
      "smart_wallet_id":      4821,
      "user_address":         "<user's Solana wallet address>",
      "source_token_address": "<token mint>",
      "amount":               "250000000",
      "loan_additional_sol":  "2200000",
      "jito_tip_amount":      "10000",
      "main_tx":              "<base64-encoded unsigned transaction>",
      "timestamp":            "<unix milliseconds>",
      "user_signature":       "<lending signing format>"
    }
    ```

    | Field                 | Guidance                                                                                                                                                                           |
    | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `amount`              | Amount to advance, in lamports or SPL base units. Must be greater than `0`.                                                                                                        |
    | `loan_additional_sol` | Covers ATA creation in the wallet. It starts empty, so budget `2039280` lamports per token account the first time a position uses that token. Pass `0` once it holds enough.       |
    | `jito_tip_amount`     | Only applied if the wrapped transaction exceeds Solana's size limit and a two-transaction bundle is used - but always required, since it is part of the signed message either way. |

    ```json Response theme={null}
    {
      "action_id":      88213,
      "tx_id":          "<transaction signature>",
      "transaction":    "<base64-encoded signed transaction>",
      "jito_bundle_id": null
    }
    ```

    Vanish picks the route by transaction size: a signed `transaction` for you to broadcast, or - if it is too large - a two-transaction Jito bundle Vanish submits itself, in which case `transaction` is `null` and `jito_bundle_id` is set.
  </Step>

  <Step title="Broadcast if needed, then commit">
    Broadcast `transaction` if it is non-null; if `jito_bundle_id` is set instead, Vanish has already submitted it. Then commit either way:

    ```json POST /borrow/commit theme={null}
    { "tx_id": "<transaction signature from /borrow/initiate>" }
    ```

    ```json Response theme={null}
    {
      "status":            "completed",
      "action_type":       "borrow",
      "already_processed": false,
      "balance_changes": [
        { "token_address": "<string>", "change": "<string>" }
      ],
      "vanish_fee":   0,
      "tx_fee":       5000,
      "completed_at": "2026-08-31T18:22:04.112Z"
    }
    ```

    <Warning>
      `/borrow/commit` must be called for every lending action - success, failure, or expiry. Until it is, the action stays in a pending state. Lending returns the same statuses as a trade except `rejected`, which applies to deposits only - see [Commit Status](/guide/handling#commit-status).
    </Warning>

    The funds now sit in the one-time wallet and the position is open. Advancing more into the same position repeats these steps with the same `smart_wallet_id`.
  </Step>
</Steps>

**Reference:** [Create One-Time Wallet](/api-reference/lending/smart-wallet) · [Open Position](/api-reference/lending/initiate) · [Commit Lending Action](/api-reference/lending/commit)

***

## Settle

Settling returns the advanced funds to Vanish's trading accounts, wrapped around your own withdraw or close instructions. Check [Position State](#position-state) first.

<Steps>
  <Step title="Settle the position">
    Build `main_tx` exactly as when opening - unsigned, with the position's one-time wallet as signer - using your close instructions.

    ```json POST /borrow/settle theme={null}
    {
      "smart_wallet_id":      4821,
      "user_address":         "<user's Solana wallet address>",
      "token_address":        "<token mint>",
      "amount":               "253000000",
      "loan_additional_sol":  "0",
      "cleanup_leftover_sol": true,
      "main_tx":              "<base64-encoded unsigned transaction>",
      "timestamp":            "<unix milliseconds>",
      "user_signature":       "<settle signing format>"
    }
    ```

    | Field                  | Guidance                                                                                                                                                                                                                       |
    | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
    | `amount`               | Amount landing back in the wallet from your instructions. Must be greater than `0`.                                                                                                                                            |
    | `loan_additional_sol`  | Covers ATA creation during the settle if the wallet is running low. Pass `0` when it already holds enough.                                                                                                                     |
    | `cleanup_leftover_sol` | `true` returns any leftover SOL to Vanish's trading accounts, credits it to the user, and closes the position. Set it only on the settle that fully unwinds the position - a partial withdrawal still needs the remaining SOL. |

    Settle always returns a signed `transaction` and `jito_bundle_id` is always `null` - there is no bundle route here, so you always broadcast it yourself.
  </Step>

  <Step title="Broadcast and commit">
    ```json POST /borrow/commit theme={null}
    { "tx_id": "<transaction signature from /borrow/settle>" }
    ```

    The response matches the commit above with `action_type` set to `settle`. Once a settle with `cleanup_leftover_sol` is committed, the position's `status` becomes `closed`.
  </Step>
</Steps>

**Reference:** [Settle Position](/api-reference/lending/settle) · [Commit Lending Action](/api-reference/lending/commit)

***

## Position State

[`POST /borrow/positions`](/api-reference/lending/positions) returns every one-time wallet a user holds a position in, with balances read live from chain. It is read-only.

```json Response theme={null}
[
  {
    "smart_wallet_id":    4821,
    "address":            "7yQmA1p9K4xTb3dRfN2sVzE6uYhLc8jWq5vXgMn3v3Nf",
    "protocol_label":     "kamino-lend-v2",
    "status":             "open",
    "created_at":         "2026-08-31T18:20:11",
    "closed_at":          null,
    "balances": [
      { "token_address": "<string>", "balance": "<string>", "program_id": "<string>" }
    ],
    "has_active_balance": true
  }
]
```

`status` is `open` until a settle with `cleanup_leftover_sol` is committed. Filter on `has_active_balance` rather than a dust threshold of your own - it is `true` only when the wallet holds a non-SOL token with a positive balance.

<Info>
  If the on-chain balance lookup fails for a wallet, its `balances` comes back as an empty array rather than the whole call failing. Treat an empty list as unknown, not as a confirmed zero balance.
</Info>

**Reference:** [Get Positions](/api-reference/lending/positions) · [Get Pending Lending Actions](/api-reference/lending/pending)

***

## Next Steps

* [Trading](/guide/integration/trading) - Execute a private swap against a funded balance.
* [Error Handling](/guide/handling) - Commit statuses and recovering interrupted flows.
