> ## 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.

# Integration

> Execute deposits, withdrawals, and private trades via the Vanish Core API on behalf of your platform users.

**Base URL:** `https://core-api.vanish.trade`

**SOL Native Address:** `11111111111111111111111111111111`

**Authentication:** All endpoints require an `x-api-key` header.

The Vanish Core injection process adds approximately **200ms** to trade finality. Your swap instructions are injected into Vanish's transaction wrapper, keeping you in full control over route, slippage, and execution.

<Info>
  We recommend `12,000,000` lamports (`0.012 SOL`) for `loan_additional_sol` - this covers the cost of any token account (ATA) creation during the trade. Any unused amount is automatically refunded after settlement.
</Info>

This page covers the three core flows: [**Deposit**](#deposit-flow), [**Trade**](#trade-flow), and [**Withdraw**](#withdraw-flow) - plus signing, compliance rules, interrupted flow recovery, and routing guidance.

***

## How It Works

Before trading, your Vanish account must have a funded balance - see the [Deposit](/guide/integration#deposit) section to fund it first.

When a trade is submitted, Vanish:

1. **Advances funds** from its trading accounts to a one-time use wallet to execute the swap.
2. **Wraps your swap transaction** - your swap instructions are passed through unchanged, with settlement instructions added around them.
3. **Routes the transaction** via Jito bundle (default) or returns a signed payload for self-broadcast.
4. **Settles atomically** at the end. If any instruction fails, everything reverts - failed transactions only cost the base network fee.
   <Check>
     Vanish Core automatically deducts a **50bps protocol fee** at trade settlement. If you would like to enable fees, speak to the Vanish team.
   </Check>

***

## Compliance

Vanish operates on a **same wallet in, same wallet out** model. Your connected wallet is the fixed origin for all fund movements - it is the only address from which you can deposit and the only address to which withdrawals are returned. This is enforced at the protocol level and cannot be bypassed.

<Warning>
  If a deposit commit returns `rejected`, the transaction failed compliance or risk screening. Funds will be refunded to the originating wallet after extended screening is completed. Do not re-attempt until the refund is confirmed.
</Warning>

***

## Signing Requests

Write and read endpoints require a signed message proving ownership of `user_address`. Sign with the user's Solana keypair (Ed25519) and base64-encode the result. Use the current Unix timestamp in milliseconds - stale timestamps are rejected.

<Tabs>
  <Tab title="Read Signing Format">
    Used by: [`/account/balances`](/api-reference/account/get_balances), [`/account/pending`](/api-reference/account/get_pending_actions), [`/account/points`](/api-reference/account/get_points), and all position/transaction endpoints.

    Pass the result as `signature`.

    ```text theme={null}
    By signing, I hereby agree to Vanish's Terms of Service and agree to be bound by them (docs.vanish.trade/legal/TOS)

    Details: read:{timestamp}
    ```

    <CodeGroup>
      ```typescript TypeScript theme={null}
      import * as nacl from 'tweetnacl';
      import { Keypair } from '@solana/web3.js';

      function readSignature(timestamp: string, keypair: Keypair): string {
        const message = [
          "By signing, I hereby agree to Vanish's Terms of Service and agree to be bound by them (docs.vanish.trade/legal/TOS)",
          "",
          `Details: read:${timestamp}`,
        ].join('\n');
        const sig = nacl.sign.detached(new TextEncoder().encode(message), keypair.secretKey);
        return Buffer.from(sig).toString('base64');
      }
      ```

      ```rust Rust theme={null}
      use solana_sdk::signature::{Keypair, Signer};
      use base64::{engine::general_purpose, Engine as _};

      fn read_signature(timestamp: &str, keypair: &Keypair) -> String {
          let message = format!(
              "By signing, I hereby agree to Vanish's Terms of Service and agree to be bound by them (docs.vanish.trade/legal/TOS)\n\nDetails: read:{timestamp}"
          );
          let sig = keypair.sign_message(message.as_bytes());
          general_purpose::STANDARD.encode(sig.as_ref())
      }
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Trade Signing Format">
    Used by: [`POST /trade/create`](/api-reference/trade/create)

    Pass the result as `user_signature`.

    ```text theme={null}
    By signing, I hereby agree to Vanish's Terms of Service and agree to be bound by them (docs.vanish.trade/legal/TOS)

    Details: trade:{source_token_address}:{target_token_address}:{amount}:{loan_additional_sol}:{timestamp}:{jito_tip_amount}
    ```

    <CodeGroup>
      ```typescript TypeScript theme={null}
      function tradeSignature(
        source: string, target: string, amount: string,
        loanSol: string, timestamp: string, jitoTip: string,
        keypair: Keypair
      ): string {
        const message = [
          "By signing, I hereby agree to Vanish's Terms of Service and agree to be bound by them (docs.vanish.trade/legal/TOS)",
          "",
          `Details: trade:${source}:${target}:${amount}:${loanSol}:${timestamp}:${jitoTip}`,
        ].join('\n');
        const sig = nacl.sign.detached(new TextEncoder().encode(message), keypair.secretKey);
        return Buffer.from(sig).toString('base64');
      }
      ```

      ```rust Rust theme={null}
      fn trade_signature(
          source: &str, target: &str, amount: &str,
          loan_sol: &str, timestamp: &str, jito_tip: &str,
          keypair: &Keypair,
      ) -> String {
          let message = format!(
              "By signing, I hereby agree to Vanish's Terms of Service and agree to be bound by them (docs.vanish.trade/legal/TOS)\n\nDetails: trade:{source}:{target}:{amount}:{loan_sol}:{timestamp}:{jito_tip}"
          );
          let sig = keypair.sign_message(message.as_bytes());
          general_purpose::STANDARD.encode(sig.as_ref())
      }
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Withdraw Signing Format">
    Used by: [`POST /withdraw/create`](/api-reference/funds/withdraw)

    Pass the result as `user_signature`.

    ```text theme={null}
    By signing, I hereby agree to Vanish's Terms of Service and agree to be bound by them (docs.vanish.trade/legal/TOS)

    Details: withdraw:{token_address}:{amount}:{additional_sol}:{timestamp}
    ```

    <CodeGroup>
      ```typescript TypeScript theme={null}
      function withdrawSignature(
        token: string, amount: string,
        additionalSol: string, timestamp: string,
        keypair: Keypair
      ): string {
        const message = [
          "By signing, I hereby agree to Vanish's Terms of Service and agree to be bound by them (docs.vanish.trade/legal/TOS)",
          "",
          `Details: withdraw:${token}:${amount}:${additionalSol}:${timestamp}`,
        ].join('\n');
        const sig = nacl.sign.detached(new TextEncoder().encode(message), keypair.secretKey);
        return Buffer.from(sig).toString('base64');
      }
      ```

      ```rust Rust theme={null}
      fn withdraw_signature(
          token: &str, amount: &str,
          additional_sol: &str, timestamp: &str,
          keypair: &Keypair,
      ) -> String {
          let message = format!(
              "By signing, I hereby agree to Vanish's Terms of Service and agree to be bound by them (docs.vanish.trade/legal/TOS)\n\nDetails: withdraw:{token}:{amount}:{additional_sol}:{timestamp}"
          );
          let sig = keypair.sign_message(message.as_bytes());
          general_purpose::STANDARD.encode(sig.as_ref())
      }
      ```
    </CodeGroup>
  </Tab>
</Tabs>

***

## Deposit Flow

<Steps>
  <Step title="Get a deposit address">
    See the full reference for [Get Deposit Address](/api-reference/funds/deposit_address).

    ```bash theme={null}
    GET /deposit_address?token_address={token_address}
    ```

    Pass the token mint you want to deposit. Use `11111111111111111111111111111111` for native SOL.

    ```json Response theme={null}
    {
      "address": "7ozoNcVqgptbAUHjLR1vNHgEfKiE5aYufStEHzJhxKeG"
    }
    ```
  </Step>

  <Step title="Transfer funds on-chain">
    Send tokens to the returned `address`. Wait for on-chain confirmation before continuing.
  </Step>

  <Step title="Commit the deposit">
    See the full reference for [Commit Action](/api-reference/commit).

    ```bash theme={null}
    POST /commit
    ```

    ```json Request body theme={null}
    {
      "tx_id": "<confirmed on-chain transaction signature>"
    }
    ```

    | Status      |                                                                                                                                      |
    | ----------- | ------------------------------------------------------------------------------------------------------------------------------------ |
    | `completed` | Deposit successfully processed - the user's Vanish balance has been updated                                                          |
    | `rejected`  | Deposit failed compliance or risk screening - funds will be refunded to the originating wallet after extended screening is completed |
    | `pending`   | Waiting for the transaction to land on-chain or undergo compliance screening - check back shortly                                    |
    | `failed`    | The transaction was rejected on-chain - the user's balance is no longer in a pending state                                           |
    | `expired`   | The transaction was not confirmed within the required window - the user's balance is no longer in a pending state                    |

    Call [/account/balances](/api-reference/account/get_balances) after a `completed` status to verify the updated balance.
  </Step>
</Steps>

***

## Trade Flow

<Steps>
  <Step title="Get a one-time wallet">
    See the full reference for [Get One-Time Wallet](/api-reference/trade/one-time-wallet).

    ```bash theme={null}
    GET /trade/one-time-wallet
    ```

    ```json Response theme={null}
    {
      "address": "<one-time wallet address>"
    }
    ```

    This wallet is for a single trade only - **never reuse it.** Set the returned address as the signer for all swap instructions in your (unsigned) transaction.
  </Step>

  <Step title="Prepare your swap transaction">
    1. Fetch a route from Titan or another DEX aggregator.
    2. Assemble all swap instructions into a single **unsigned** transaction.
    3. Set the one-time wallet address as the **signer** for all swap instructions.
  </Step>

  <Step title="Create the trade">
    <Check>
      Vanish Core automatically deducts a **50bps protocol fee** at trade settlement. If you would like to enable fees, speak to the Vanish team.
    </Check>

    See the full reference for [Create Trade](/api-reference/trade/create).

    ```bash theme={null}
    POST /trade/create
    ```

    <ParamField body="user_address" type="string" required>
      The user's Solana wallet address.
    </ParamField>

    <ParamField body="source_token_address" type="string" required>
      Input token mint. Use `11111111111111111111111111111111` for SOL.
    </ParamField>

    <ParamField body="target_token_address" type="string" required>
      Output token mint.
    </ParamField>

    <ParamField body="amount" type="string" required>
      Input amount in lamports or SPL base units.
    </ParamField>

    <ParamField body="swap_transaction" type="string" required>
      Base64-encoded **unsigned** swap transaction.
    </ParamField>

    <ParamField body="one_time_wallet" type="string" required>
      Address returned by [`GET /trade/one-time-wallet`](/api-reference/trade/one-time-wallet).
    </ParamField>

    <ParamField body="loan_additional_sol" type="string" required>
      Amount to cover ATA creation during the trade. We recommend `12000000` (0.012 SOL) - unused amount is automatically refunded.
    </ParamField>

    <ParamField body="jito_tip_amount" type="string" required>
      Tip in lamports. Minimum recommended: `1000000` (0.001 SOL). Only applied on the Jito route.
    </ParamField>

    <ParamField body="split_repay" type="integer" required>
      Number of Trading Accounts to distribute purchased tokens across. Max `9`. Use `1` when `amount_out` is less than 0.5% of total supply.
    </ParamField>

    <ParamField body="timestamp" type="string" required>
      Unix timestamp in milliseconds.
    </ParamField>

    <ParamField body="user_signature" type="string" required>
      See the [Trade Signing Format](#signing-requests) above.
    </ParamField>

    <ParamField body="prefer_non_jito" type="object">
      Compute budget for self-broadcast. **Omit entirely** to route via Jito (default).

      <Expandable title="prefer_non_jito fields">
        <ParamField body="compute_unit_price" type="string">
          Micro-lamports per compute unit.
        </ParamField>

        <ParamField body="compute_unit_limit" type="string">
          Max compute units for the transaction.
        </ParamField>

        <ParamField body="custom_tip_address" type="string">
          Optional custom tip recipient address.
        </ParamField>

        <ParamField body="custom_tip_amount" type="string">
          Optional custom tip amount in lamports.
        </ParamField>
      </Expandable>
    </ParamField>

    <Tabs>
      <Tab title="Jito (default)">
        Omit `prefer_non_jito`. Vanish Core builds, signs, and broadcasts via Jito bundle - no further action needed.

        **Response:** `tx_id` + `jito_bundle_id` - `transaction` is `null`
      </Tab>

      <Tab title="Non-Jito">
        Provide the `prefer_non_jito` object. Vanish Core returns the fully-signed transaction for self-broadcast.

        **Response:** signed `transaction` - `jito_bundle_id` is `null`

        The response wraps your original swap instructions unchanged. Works best with low `split_repay` values - smaller transactions are more likely to fit in a single transaction without Jito bundling.
      </Tab>
    </Tabs>

    All operations revert atomically on failure. Failed transactions only cost the base network fee.
  </Step>

  <Step title="Broadcast (non-Jito only), then commit">
    If using non-Jito, broadcast the returned `transaction` through your RPC. Then commit regardless of route or outcome:

    ```bash theme={null}
    POST /commit
    ```

    ```json Request body theme={null}
    {
      "tx_id": "<on-chain transaction signature>"
    }
    ```

    ```json Response theme={null}
    {
      "status":            "completed",
      "action_type":       "trade",
      "already_processed": false,
      "vanish_fee":        "5000",
      "tx_fee":            "5000",
      "user_address":      "<string>",
      "balance_changes": [
        { "token_address": "<string>", "change": "<string>" }
      ]
    }
    ```

    <Warning>
      `/commit` must be called for every transaction - success, failure, or expiry. Balances in a pending state are only resolved once commit is received.
    </Warning>

    <Info>
      If `already_processed` is `true`, this `tx_id` was already committed in a previous call. The response still contains the correct `status` and `balance_changes` - safe to use for idempotency checks.
    </Info>
  </Step>
</Steps>

***

## Withdraw Flow

<Steps>
  <Step title="Create the withdrawal">
    Verify the user's balance via [`/account/balances`](/api-reference/account/get_balances) before proceeding. See the full reference for [Withdraw](/api-reference/funds/withdraw).

    ```bash theme={null}
    POST /withdraw/create
    ```

    <ParamField body="user_address" type="string" required>
      The user's Solana wallet address.
    </ParamField>

    <ParamField body="token_address" type="string" required>
      Token mint to withdraw.
    </ParamField>

    <ParamField body="amount" type="string" required>
      Amount in base units.
    </ParamField>

    <ParamField body="additional_sol" type="string" required>
      Lamports for destination ATA creation, if required.
    </ParamField>

    <ParamField body="timestamp" type="string" required>
      Unix timestamp in milliseconds.
    </ParamField>

    <ParamField body="user_signature" type="string" required>
      See the [Withdraw Signing Format](#signing-requests) above.
    </ParamField>

    ```json Response theme={null}
    {
      "tx_id":            "<string>",
      "transaction_data": "<serialized withdrawal transaction>"
    }
    ```

    `transaction_data` is routed through the user's initial deposit wallet for compliant fund flow. Broadcast this via your RPC.
  </Step>

  <Step title="Broadcast and commit">
    Broadcast `transaction_data` through your RPC or node, then commit:

    ```bash theme={null}
    POST /commit
    ```

    ```json Request body theme={null}
    {
      "tx_id": "<on-chain transaction signature>"
    }
    ```

    <Warning>
      `/commit` must be called for every transaction - success, failure, or expiry. Balances in a pending state are only resolved once commit is received.
    </Warning>
  </Step>
</Steps>

***

## Handling Interrupted Flows

If a transaction is submitted but `/commit` is never called - due to a crash, timeout, or network issue - the user's balance remains in a pending state.

Use [`/account/pending`](/api-reference/account/get_pending_actions) to detect and recover these states:

```bash theme={null}
POST /account/pending
```

```json Request body theme={null}
{
  "user_address": "<user's wallet address>",
  "timestamp":    "<unix ms>",
  "signature":    "<Read Signing Format>"
}
```

```json Response theme={null}
[
  {
    "tx_id":                  "<string>",
    "action_type":            "trade",
    "status":                 "pending",
    "created_at":             "2025-01-01T00:00:00Z",
    "frozen_balance_changes": [{ "token_address": "<string>", "change": "<string>" }]
  }
]
```

Call [`/commit`](/api-reference/commit) with each returned `tx_id` to resolve balances from their pending state - whether the original transaction succeeded or failed on-chain. `/commit` is idempotent, so it is safe to retry.

***

## Routing Guidance

<AccordionGroup>
  <Accordion title="When to use Jito vs non-Jito">
    **Use Jito (default)** when:

    * You want Vanish Core to handle broadcasting entirely
    * You are trading high-value amounts where MEV protection matters
    * Simplicity is preferred over control

    **Use non-Jito** when:

    * You have your own RPC infrastructure optimised for low latency
    * You want full control over broadcasting and retry logic
    * Transaction size is small (low `split_repay`) and atomic execution is likely
  </Accordion>

  <Accordion title="Choosing split_repay">
    `split_repay` controls how many Trading Accounts purchased tokens are distributed across. Lower values mean fewer account metas and instructions, a smaller overall transaction, and a higher likelihood of atomic execution without Jito bundling.

    **Start with `1`** for most trades. Only increase if `amount_out` exceeds 0.5% of total token supply, which may require spreading holdings to reduce per-wallet concentration. Maximum value is `9`.
  </Accordion>

  <Accordion title="Setting loan_additional_sol">
    We recommend `12000000` lamports (`0.012 SOL`) for `loan_additional_sol` - this covers ATA creation costs during the trade. Any unused amount is automatically refunded after settlement.

    If the target token's ATA already exists in the user's wallet, a lower value may be sufficient - but the recommended value is safe for all cases.
  </Accordion>
</AccordionGroup>

***

## Lamport Reference

All amounts are denominated in **lamports** - the smallest unit of SOL (1 SOL = 1,000,000,000 lamports). SPL token amounts use the token's own decimal precision.

| Amount                                   | Lamports        |
| ---------------------------------------- | --------------- |
| 1 SOL                                    | `1,000,000,000` |
| 0.012 SOL (loan\_additional\_sol)        | `12,000,000`    |
| 0.001 SOL (minimum recommended Jito tip) | `1,000,000`     |

***

## Next Steps

* New to Vanish? Start with the [Quickstart](/guide/quickstart) for working code examples.
* Hitting errors? See [Error Handling](/guide/handling) for status codes, commit statuses, and debugging.
* Have questions? The [FAQ](/guide/faq) covers common integration questions.
