# TypeScript SDK — Account Services: Withdrawals & Transfers

Withdraw crypto, transfer between accounts, estimate gas fees, and review transfer history. All methods are on `client.transfers`.

See the [API specifications](/api-specifications) for full request/response schemas and the [authentication guide](/tools/typescript-sdk/authentication) for setup.

## Methods

### withdrawCryptoFunds

`POST /v2/withdraw/{network}/{ticker}` · Authenticated

Initiates a cryptocurrency withdrawal. This is a security-sensitive mutation — the request is [validated client-side](/tools/typescript-sdk/deep-dives/request-validation) before sending. The SDK enforces:

- `network`, `ticker` — required strings
- `address` — required string
- `amount` — required decimal string
- `clientTransferId` — optional UUID
- `memo` — optional string

```ts
const withdrawal = await client.transfers.withdrawCryptoFunds({
  network: "ethereum",
  ticker: "ETH",
  address: "0x1234567890abcdef1234567890abcdef12345678",
  amount: "1.5",
  clientTransferId: "550e8400-e29b-41d4-a716-446655440000",
});
```

This is a POST mutation — never automatically retried. The optional `clientTransferId` (UUID) provides withdrawal idempotency: duplicate requests with the same ID do not create additional withdrawals. The destination must be on your [approved address list](/tools/typescript-sdk/reference/account-services/addresses-and-deposits). Amounts are decimal strings, not numbers.

### transferBetweenAccounts

`POST /v1/account/transfer/{currency}` · Authenticated

Transfers funds between accounts within the same master group. The request is [validated client-side](/tools/typescript-sdk/deep-dives/request-validation). The SDK enforces:

- `currency` — required string
- `sourceAccount`, `targetAccount` — required strings
- `amount` — required decimal string
- `clientTransferId` — optional UUIDv4

```ts
const transfer = await client.transfers.transferBetweenAccounts({
  currency: "btc",
  sourceAccount: "primary",
  targetAccount: "trading",
  amount: "0.25",
  clientTransferId: "550e8400-e29b-41d4-a716-446655440000",
});

console.log(transfer.message); // "Success, transfer completed."
```

> **Tip:** When provided, `clientTransferId` must be a UUIDv4. It identifies the transfer request; the API documentation does not promise duplicate suppression, so confirm the transfer status before retrying an uncertain request.

### getGasFeeEstimation

`POST /v2/withdraw/{network}/{ticker}/feeEstimate` · Authenticated

Returns an estimated gas fee for a withdrawal without actually executing it.

```ts
const estimate = await client.transfers.getGasFeeEstimation({
  network: "ethereum",
  ticker: "ETH",
  address: "0x1234567890abcdef1234567890abcdef12345678",
  amount: "1.0",
});

// fee is a number, not a string
console.log(`Estimated fee: ${estimate.fee} ${estimate.currency}`);
console.log(`Free withdrawals remaining: ${estimate.monthlyRemaining}`);
```

> **Tip:** Call this before `withdrawCryptoFunds` to show users the expected fee. The `fee` field is a **number** (not a string). `monthlyLimit` and `monthlyRemaining` track free withdrawal allowances.

### listPastTransfers

`POST /v2/transfers` · Authenticated

Returns a history of past transfers (deposits, withdrawals, and internal transfers). The response is a bare array of `V2Transfer` objects.

```ts
const transfers = await client.transfers.listPastTransfers({});

for (const t of transfers) {
  // t.eid may be bigint
  console.log(`${t.type}: ${t.amount} ${t.currency} (eid: ${t.eid})`);
}
```

> **Tip:** The `eid` field in the response may be a `bigint`. The request body accepts optional `timestamp` (bigint/number) for pagination.

### getTransactionHistory

`POST /v1/transactions` · Authenticated

Returns detailed transaction history with filtering support. The response is a **wrapper object** with a `results` array. Response fields like `eid`, `tid`, `orderId`, and other IDs may be `bigint`.

```ts
const history = await client.transfers.getTransactionHistory({
  limit: 50,
});

for (const tx of history.results ?? []) {
  // Transaction entries are either trade or transfer records, with
  // operation-specific fields. IDs may be bigint.
  const currency = "currency" in tx ? tx.currency : "symbol" in tx ? tx.symbol : undefined;
  const eventId = "eid" in tx ? tx.eid : undefined;
  console.log(`${tx.amount ?? ""} ${currency ?? ""} (eid: ${eventId ?? "n/a"})`);
}
```

> **Tip:** The `timestamp_nanos` request field accepts `bigint` for nanosecond-precision filtering. Use `continuation_token` from the response for pagination. Many response ID fields are `bigint` — see [Data Types](/tools/typescript-sdk/deep-dives/data-types).

### listCustodyFeeTransfers

`POST /v1/custodyaccountfees` · Authenticated

Returns custody fee transfers for custody accounts. The request body accepts an optional `timestamp` field (bigint or number) for filtering. The response is a bare array.

```ts
const fees = await client.transfers.listCustodyFeeTransfers({});

for (const fee of fees) {
  console.log(`${fee.feeAmount} ${fee.feeCurrency} — ${fee.eventType}`);
}
```

> **Tip:** Fee amounts are decimal strings. Pass `timestamp` as a bigint or number to filter results — the API returns records **on or after** the given timestamp (lower bound, forward paging), not backward.

## What's next

- [Addresses & Deposits](/tools/typescript-sdk/reference/account-services/addresses-and-deposits) — managing deposit and approved withdrawal addresses
- [Balances & Account](/tools/typescript-sdk/reference/account-services/balances-and-account) — checking balances
- [Request Validation](/tools/typescript-sdk/deep-dives/request-validation) — how client-side validation catches errors early
- [Data Types](/tools/typescript-sdk/deep-dives/data-types) — decimal strings and bigint fields
