> For the complete documentation index, see [llms.txt](https://docs.diversifi.trade/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.diversifi.trade/diversifi-for-partners/integration-guide/deposits-and-withdrawals.md).

# Deposits & withdrawals

### 9. Authentication

All deposit and withdrawal operations go through the DiversiFi API. You will need an API key to interact with these endpoints.

Contact the DiversiFi team to obtain an API key. Keys are prefixed with `dfi_` and must be sent as a Bearer token on every request:

```
Authorization: Bearer dfi_your_api_key_here
```

**Rate limit:** 120 requests per minute per API key.

**Required permission scope:** `position_management` (for deposits, withdrawals, and refunds). Read-only endpoints require only `read_only`.

***

### 10. Deposit Flow

Depositing USDC into a basket is a two-step process:

1. **Get an unsigned transaction** from the API — the server builds and returns a base64-encoded Solana transaction.
2. **Sign and submit it** with the user's wallet, then **confirm** it with the API.

#### Step 1 — Get the unsigned deposit transaction

```shellscript
GET /v1/positions/open/tx
```

| Parameter        | Type   | Required | Description                                           |
| ---------------- | ------ | -------- | ----------------------------------------------------- |
| `basket_address` | string | Yes      | The basket address / Index PDA (base58)               |
| `amount`         | number | Yes      | USDC amount to deposit (human-readable, e.g. `100.5`) |

**Response:**

```typespec
{
  "success": true,
  "data": {
    "unsignedTxs": ["<base64-encoded transaction>"]
  }
}
```

`unsignedTxs` is an array. Sign and submit each transaction in order.

**Error responses:**

| `message`                                       | Cause                               |
| ----------------------------------------------- | ----------------------------------- |
| `"Basket not found"`                            | Invalid `basket_address`            |
| `"Minimum deposit for <BasketName> is X USDC."` | Amount below the per-basket minimum |
| `"Basket operations are currently paused"`      | Basket temporarily disabled         |

#### Step 2 — Sign, submit, and confirm

After signing and submitting the transaction to the Solana network, pass the resulting signature back to the API:

```shellscript
GET /v1/positions/open/confirm
```

| Parameter        | Type   | Required | Description                        |
| ---------------- | ------ | -------- | ---------------------------------- |
| `basket_address` | string | Yes      | Same basket address used in step 1 |
| `signature`      | string | Yes      | The Solana transaction signature   |

**Response:**

```typescript
{
  "success": true,
  "message": "Transaction executed.",
  "data": { "executedAt": "2025-03-24T12:34:56.789Z" }
}
```

Once confirmed, the DiversiFi backend automatically executes the Jupiter swaps and mints LP tokens to the user's wallet.

***

### 11. Withdrawal Flow

Withdrawing converts LP tokens back to USDC. Same two-step pattern as deposits.

#### Step 1 — Get the unsigned withdrawal transaction

```shellscript
GET /v1/positions/close/tx
```

| Parameter        | Type   | Required | Description                                  |
| ---------------- | ------ | -------- | -------------------------------------------- |
| `basket_address` | string | Yes      | The basket address / Index PDA (base58)      |
| `amount`         | number | Yes      | LP token amount to withdraw (human-readable) |

**Response:** Same shape as the deposit response — `unsignedTxs` array.

#### Step 2 — Sign, submit, and confirm

```shellscript
GET /v1/positions/close/confirm
```

| Parameter        | Type   | Required | Description                      |
| ---------------- | ------ | -------- | -------------------------------- |
| `basket_address` | string | Yes      |                                  |
| `signature`      | string | Yes      | The Solana transaction signature |

After confirmation, the backend swaps each constituent token back to USDC. Fees are deducted at this stage. USDC lands in the user's wallet automatically.

***

### 12. Cancelling Pending Operations

If a deposit or withdrawal is stuck, users can cancel and reclaim their locked tokens.

#### Check refund eligibility

```shellscript
GET /v1/positions/refund/check
```

| Parameter        | Type   | Required |
| ---------------- | ------ | -------- |
| `basket_address` | string | Yes      |

**Response:**

```typescript
{
  "success": true,
  "data": {
    "canRefund": true,
    "refundType": "deposit",
    "deposit": { "hasPending": true, "hasBalance": true, "balance": 100.5, "canRefund": true },
    "withdrawal": { "hasPending": false, "hasBalance": false, "balance": 0, "canRefund": false }
  }
}
```

`refundType` is `"deposit"`, `"withdrawal"`, or `null`.

> **Note:** `refund/check` returns `"withdrawal"` (with -al) but `refund/tx` accepts `"withdraw"` (without). Normalize before passing: `refundType === "withdrawal" ? "withdraw" : refundType`.

#### Get the unsigned refund transaction

```shellscript
GET /v1/positions/refund/tx
```

| Parameter        | Type   | Required | Description                 |
| ---------------- | ------ | -------- | --------------------------- |
| `basket_address` | string | Yes      |                             |
| `refund_type`    | string | Yes      | `"deposit"` or `"withdraw"` |

**Response:**

```typescript
{
  "success": true,
  "data": {
    "unsignedTx": "<base64-encoded transaction>",
    "transactionType": "deposit"
  }
}
```

#### Sign, submit, and confirm the refund

```shellscript
GET /v1/positions/refund/confirm
```

| Parameter          | Type   | Required | Description                      |
| ------------------ | ------ | -------- | -------------------------------- |
| `basket_address`   | string | Yes      |                                  |
| `refund_signature` | string | Yes      | The refund transaction signature |

Only the unprocessed portion of a deposit/withdrawal is refunded. If the backend partially executed swaps before the cancel, those cannot be reversed.

***

### 13. Reading Positions and History

These endpoints require only `read_only` permission.

#### User positions

```shellscript
GET /v1/positions/
```

Returns all open and closed positions for the authenticated wallet, including current value, ROI, PnL, and refund eligibility.

#### Portfolio summary

```shellscript
GET /v1/portfolio
```

Returns an aggregate summary across all positions: total invested, total current value, total ROI.

#### Transaction history

```shellscript
GET /v1/positions/transactions
```

| Parameter   | Type   | Required | Description                       |
| ----------- | ------ | -------- | --------------------------------- |
| `basket_id` | string | No       | Filter by basket                  |
| `limit`     | number | No       | Max results (default 50, max 200) |

Each transaction includes its type (`Deposit`, `Withdrawal`, `Refund`), status (`completed`, `processing`, `partially_completed`, `failed`, `refunded`, `pending`), amounts, timestamps, and the individual swap signatures.

***

### 14. Example TypeScript Implementation

See [`deposit_withdraw_example.ts`](https://docs.diversifi.trade/~/revisions/ZF6Hb4ijE6lwNA3OwEft/diversifi-for-partners/integration-guide/deposits-and-withdrawals/deposit_withdraw_example.ts) for a complete working example of the deposit and withdrawal flows using the API.
