> For the complete documentation index, see [llms.txt](https://docs.kpk.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kpk.io/funds/integration/redemption-request.md).

# Redemption request

Redeeming is a single step — no approval is needed, because the shares contract pulls the shares you already hold into escrow:

```solidity
function requestRedemption(
    uint256 sharesIn,       // amount of shares to redeem
    uint256 minAssetsOut,   // slippage protection, applied AFTER the redemption fee
    address redemptionAsset,// must be approved for redemptions (canRedeem = true)
    address receiver        // who receives the assets
) external returns (uint256 requestId);
```

{% hint style="warning" %}
`minAssetsOut` is **slippage protection** measured **after** the redemption fee. The operator's settlement must yield at least `minAssetsOut` assets or the request fails. Derive it with `previewRedemption`, which already deducts the fee — see [Calculate share price](/funds/integration/calculate-share-price.md).
{% endhint %}

## Example

Redeeming **500 shares** (18 decimals) for USDC, with a 0.5% slippage tolerance.

{% tabs %}
{% tab title="viem" %}

```typescript
import { createWalletClient, createPublicClient, http, parseAbi, parseUnits } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { mainnet } from "viem/chains";

const SHARES = "0x...";  // fund shares contract
const USDC   = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";

const sharesAbi = parseAbi([
  "function previewRedemption(uint256 shares, uint256 sharesPrice, address redemptionAsset) view returns (uint256)",
  "function requestRedemption(uint256 sharesIn, uint256 minAssetsOut, address redemptionAsset, address receiver) returns (uint256)",
]);

const account = privateKeyToAccount("0x...");
const pub = createPublicClient({ chain: mainnet, transport: http() });
const wallet = createWalletClient({ account, chain: mainnet, transport: http() });

const sharesIn = parseUnits("500", 18); // 500 shares

// Estimate assets out (net of the redemption fee) at the last settled price, then apply slippage.
const expectedAssets = await pub.readContract({
  address: SHARES, abi: sharesAbi, functionName: "previewRedemption",
  args: [sharesIn, 0n, USDC],
});
const minAssetsOut = (expectedAssets * 9950n) / 10000n;

const hash = await wallet.writeContract({
  address: SHARES, abi: sharesAbi, functionName: "requestRedemption",
  args: [sharesIn, minAssetsOut, USDC, account.address],
});
```

{% endtab %}

{% tab title="ethers.js" %}

```typescript
import { ethers } from "ethers";

const SHARES = "0x...";  // fund shares contract
const USDC   = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";

const sharesAbi = [
  "function previewRedemption(uint256 shares, uint256 sharesPrice, address redemptionAsset) view returns (uint256)",
  "function requestRedemption(uint256 sharesIn, uint256 minAssetsOut, address redemptionAsset, address receiver) returns (uint256)",
];

const provider = new ethers.JsonRpcProvider("https://eth.llamarpc.com");
const signer = new ethers.Wallet("0x...", provider);
const shares = new ethers.Contract(SHARES, sharesAbi, signer);

const sharesIn = ethers.parseUnits("500", 18);

const expectedAssets = await shares.previewRedemption(sharesIn, 0n, USDC);
const minAssetsOut = (expectedAssets * 9950n) / 10000n; // 0.5% slippage

const tx = await shares.requestRedemption(sharesIn, minAssetsOut, USDC, await signer.getAddress());
await tx.wait();
```

{% endtab %}

{% tab title="Python" %}

```python
from web3 import Web3

SHARES = "0x..."  # fund shares contract
USDC   = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"

shares_abi = [
    {"name": "previewRedemption", "type": "function", "stateMutability": "view",
     "inputs": [{"name": "shares", "type": "uint256"}, {"name": "sharesPrice", "type": "uint256"},
                {"name": "redemptionAsset", "type": "address"}],
     "outputs": [{"type": "uint256"}]},
    {"name": "requestRedemption", "type": "function", "stateMutability": "nonpayable",
     "inputs": [{"name": "sharesIn", "type": "uint256"}, {"name": "minAssetsOut", "type": "uint256"},
                {"name": "redemptionAsset", "type": "address"}, {"name": "receiver", "type": "address"}],
     "outputs": [{"type": "uint256"}]},
]

w3 = Web3(Web3.HTTPProvider("https://eth.llamarpc.com"))
acct = w3.eth.account.from_key("0x...")
shares = w3.eth.contract(address=SHARES, abi=shares_abi)

shares_in = 500 * 10**18  # 500 shares

expected_assets = shares.functions.previewRedemption(shares_in, 0, USDC).call()
min_assets_out = expected_assets * 9950 // 10000  # 0.5% slippage

req = shares.functions.requestRedemption(
    shares_in, min_assets_out, USDC, acct.address
).build_transaction({"from": acct.address})
# ... sign & send req ...
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}

## Events

Creating a redemption request emits a `RedemptionRequest` event containing the `requestId`, `cancelableFrom`, and `expiryAt`. Track it as described in [Monitor a request](/funds/integration/monitor-a-request.md).
{% endhint %}

<figure><picture><source srcset="/files/QZEgPpXU4vmjED4jf0xO" media="(prefers-color-scheme: dark)"><img src="/files/DcnbnOsML7CKAO6Oa6xU" alt=""></picture><figcaption><p>Redemption flow example</p></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.kpk.io/funds/integration/redemption-request.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
