# Scheduled Withdrawals

For amounts that don't clear instantly, use the three-step scheduled flow. It spans up to \~24 hours end-to-end.

### Who does what

| Step       | Actor       | Action                                                             |
| ---------- | ----------- | ------------------------------------------------------------------ |
| 1. Request | Vault owner | Call `requestShares` on the vault's `WithdrawManager`              |
| 2. Release | Tesseract   | Prepare liquidity in the background and release funds              |
| 3. Claim   | Vault owner | Call `redeemFromRequest` on the vault within the withdrawal window |

Each vault has its own `WithdrawManager` — its address is in the `VaultDeployed` event from when the vault was deployed, and discoverable via the [Public API](/dedicated-client-vaults/reference/public-api.md).

### Step 1 — Request shares

Approve your shares to be spent by the vault, then call `requestShares`:

```ts
const vaultErc20Abi = [{
  type: 'function', stateMutability: 'nonpayable', name: 'approve',
  inputs: [{type: 'address'}, {type: 'uint256'}],
  outputs: [{type: 'bool'}],
}] as const

// Shares are ERC-20 on the vault itself — approve the vault
await walletClient.writeContract({
  address: vault, abi: vaultErc20Abi, functionName: 'approve',
  args: [vault, shares],
})

const withdrawManagerAbi = [{
  type: 'function', stateMutability: 'nonpayable', name: 'requestShares',
  inputs: [{name: 'shares', type: 'uint256'}], outputs: [],
}] as const

await walletClient.writeContract({
  address: withdrawManager,
  abi: withdrawManagerAbi,
  functionName: 'requestShares',
  args: [shares],
})
```

Your shares are now locked and a withdrawal window is opened on the `WithdrawManager`.

### Step 2 — Wait for release

Tesseract's operations prepare liquidity by exiting positions as needed and call `releaseFunds` on the `WithdrawManager` when ready. This typically takes minutes to hours and is capped by the release SLA.

Tesseract sends the client an email notification as soon as the funds are released and the claim window opens — for retail users, this is usually enough. Integrators that can't rely on email (custodial, headless, automated flows) should poll release status on-chain:

```ts
const wmViewAbi = [
  {type: 'function', stateMutability: 'view', name: 'getLastReleaseFundsTimestamp',
   inputs: [], outputs: [{type: 'uint256'}]},
  {type: 'function', stateMutability: 'view', name: 'getWithdrawWindow',
   inputs: [], outputs: [{type: 'uint256'}]},
  {type: 'function', stateMutability: 'view', name: 'requestInfo',
   inputs: [{name: 'account', type: 'address'}],
   outputs: [/* WithdrawRequestInfo struct */]},
] as const

const releaseTs = await client.readContract({
  address: withdrawManager, abi: wmViewAbi, functionName: 'getLastReleaseFundsTimestamp',
})
```

Once `releaseTs` advances past your request timestamp, your request is ready to claim.

### Step 3 — Redeem from request

While the window is still open, call `redeemFromRequest` on the **vault** (not the `WithdrawManager`):

```ts
const vaultClaimAbi = [{
  type: 'function', stateMutability: 'nonpayable', name: 'redeemFromRequest',
  inputs: [
    {name: 'shares',   type: 'uint256'},
    {name: 'receiver', type: 'address'},
    {name: 'owner',    type: 'address'},
  ],
  outputs: [{name: 'assets', type: 'uint256'}],
}] as const

await walletClient.writeContract({
  address: vault,
  abi: vaultClaimAbi,
  functionName: 'redeemFromRequest',
  args: [shares, receiver, owner],
})
```

The underlying asset is transferred to `receiver` and the shares are burned.

### If the window expires

If you don't claim before the window closes, the request is effectively cancelled and you need to start over from Step 1. Poll the release timestamp and submit the claim as soon as funds are available to avoid this.

### Partial claims

You can request a single large amount and claim it in multiple smaller calls to `redeemFromRequest`, as long as each claim stays within the window. The `WithdrawManager` tracks the remaining unclaimed shares of your request.

***

Continue to [**Strategy Assignment**](/dedicated-client-vaults/integration-guide/scenario-a/strategy-assignment.md) if you haven't assigned a strategy yet, or [**Reading Vault Data**](/dedicated-client-vaults/integration-guide/scenario-a/reading-vault-data.md) for reporting.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tesseract.fi/dedicated-client-vaults/integration-guide/scenario-a/scheduled-withdrawals.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
