> ## Documentation Index
> Fetch the complete documentation index at: https://docs.privy.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Withdraw assets

> Withdraw deposited assets with accrued yield from a vault.

Redeem vault shares and return assets — plus any accrued yield — to the wallet using the [withdraw](/api-reference/wallets/earn/withdraw) endpoint. The returned `amount` reflects the original deposit plus yield earned.

<Info>
  View the full [API reference](/api-reference/wallets/earn/withdraw) for the withdraw endpoint.
</Info>

<Tip>
  If your app has gas sponsorship configured, usage of the `/earn/ethereum/withdraw` endpoint will
  be [gas-sponsored by default](/wallets/actions/overview#gas-management). There is no need to
  specify additional parameters for sponsorship.
</Tip>

## Withdrawal amount

Your app can withdraw any amount up to the wallet's current `assets_in_vault` balance. To withdraw everything, query the wallet's [position](/wallets/actions/earn/get-vault-position) first and pass the full `assets_in_vault` value as the `raw_amount`.

Because yield accrues continuously, the redeemable balance may be slightly higher at withdrawal time than when the position was last queried.

<Tip>
  For a full withdrawal, your app can read the wallet's `assets_in_vault` from the position endpoint
  and pass that value directly. Any additional yield accrued between the query and the withdrawal
  will remain in the vault as residual shares.
</Tip>

## Liquidity considerations

Withdrawals depend on available liquidity in the underlying vault. Your app should check the vault's `available_liquidity_usd` from the [get vault details](/api-reference/wallets/earn/get-vault-details) endpoint before initiating large withdrawals.

## Usage

<Tabs>
  <Tab title="Node SDK">
    Use the `withdraw` convenience method on the earn ethereum service to withdraw assets from a vault.

    ```typescript theme={"system"}
    const response = await privy.wallets().earn().ethereum().withdraw('insert-wallet-id', {
      vault_id: '<your-vault-id>',
      amount: '1.05',
      authorization_context: {
        authorization_private_keys: ['<authorization-private-key>'],
      },
    });
    ```

    The method returns an `EarnWithdrawActionResponse` with the pending wallet action. Poll the status with [get wallet action](/api-reference/wallets/actions/get), or listen for the [`wallet_action.earn_withdraw.succeeded`](/api-reference/webhooks/wallet-action/earn-withdraw/succeeded) webhook.
  </Tab>

  <Tab title="REST API">
    To withdraw funds via REST API, make a `POST` request to:

    ```bash theme={"system"}
    https://auth.privy.io/api/v1/wallets/{wallet_id}/earn/ethereum/withdraw
    ```

    ### Parameters

    <ParamField path="vault_id" type="string" required>
      The unique identifier for the vault.
    </ParamField>

    <ParamField path="amount" type="string">
      Human-readable decimal amount to withdraw (e.g. `"1.5"` for 1.5 USDC). Exactly one of `amount` or `raw_amount` must be provided.
    </ParamField>

    <ParamField path="raw_amount" type="string">
      Amount to withdraw in the token's smallest unit (e.g. `"1500000"` for 1.5 USDC with 6 decimals). Exactly one of `amount` or `raw_amount` must be provided.
    </ParamField>

    <Info>
      Wallets with `owner_id` present must provide an [authorization
      signature](/api-reference/authorization-signatures) as a request header for withdraw operations.
    </Info>

    ### Returns

    <ResponseField name="id" type="string">
      The wallet action ID. Use this to poll status with [get wallet action](/api-reference/wallets/actions/get).
    </ResponseField>

    <ResponseField name="wallet_id" type="string">
      The ID of the wallet receiving the withdrawn funds.
    </ResponseField>

    <ResponseField name="type" type="string">
      The action type. Always `"earn_withdraw"` for this endpoint.
    </ResponseField>

    <ResponseField name="status" type="'pending' | 'succeeded' | 'rejected' | 'failed'">
      The current status of the withdrawal action.
    </ResponseField>

    <ResponseField name="caip2" type="string">
      CAIP-2 chain identifier for the withdrawal (e.g. `"eip155:8453"`).
    </ResponseField>

    <ResponseField name="vault_id" type="string">
      The ID of the vault being withdrawn from.
    </ResponseField>

    <ResponseField name="vault_address" type="string">
      The ERC-4626 vault contract address.
    </ResponseField>

    <ResponseField name="asset_address" type="string">
      The address of the underlying asset token.
    </ResponseField>

    <ResponseField name="raw_amount" type="string">
      Amount withdrawn in the token's smallest unit.
    </ResponseField>

    <ResponseField name="amount" type="string | undefined">
      Human-readable decimal amount (e.g. `"1.5"`). Only present when the token is known in the asset registry.
    </ResponseField>

    <ResponseField name="asset" type="string | undefined">
      Asset identifier (e.g. `"usdc"`). Only present when the token is known in the asset registry.
    </ResponseField>

    <ResponseField name="decimals" type="number | undefined">
      Number of decimals for the underlying asset. Only present when the token is known in the asset registry.
    </ResponseField>

    <ResponseField name="share_amount" type="string | null">
      Vault shares redeemed in base units. `null` until the action succeeds.
    </ResponseField>

    <ResponseField name="created_at" type="string">
      ISO 8601 timestamp of when the action was created.
    </ResponseField>

    <ResponseField name="steps" type="array | undefined">
      The execution steps. Only returned if `?include=steps` is provided on a GET request.
    </ResponseField>

    ### Example

    ```bash theme={"system"}
    curl -X POST https://auth.privy.io/api/v1/wallets/{wallet_id}/earn/ethereum/withdraw \
      -H "privy-app-id: <your-app-id>" \
      -H "Authorization: Basic <credentials>" \
      -H "Content-Type: application/json" \
      -d '{
        "vault_id": "<your-vault-id>",
        "amount": "1.05"
      }'
    ```

    ```json Example response theme={"system"}
    {
      "id": "<action-id>",
      "wallet_id": "<your-wallet-id>",
      "type": "earn_withdraw",
      "status": "pending",
      "caip2": "eip155:8453",
      "vault_id": "<your-vault-id>",
      "vault_address": "0x5224d0c05698eD4a97C771B62095929F293f1D60",
      "asset_address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "raw_amount": "1050000",
      "amount": "1.05",
      "asset": "usdc",
      "decimals": 6,
      "share_amount": null,
      "created_at": "2025-04-01T12:00:00.000Z"
    }
    ```
  </Tab>
</Tabs>

<Tip>
  Track the withdrawal by polling [get wallet action](/api-reference/wallets/actions/get) or
  listening for the
  [`wallet_action.earn_withdraw.succeeded`](/api-reference/webhooks/wallet-action/earn-withdraw/succeeded)
  webhook.
</Tip>

## Claim reward incentives

Some vaults distribute additional token incentives on top of base yield. Collect these with the [claim](/api-reference/wallets/earn/incentive-claim) endpoint. Claims operate at the chain level — pass a chain name rather than a vault ID. For apps with multiple vaults on the same chain, a single claim collects rewards across all vaults.

### Usage

<Tabs>
  <Tab title="Node SDK">
    Use the `claim` convenience method on the earn ethereum incentive service to claim reward incentives.

    ```typescript theme={"system"}
    const response = await privy.wallets().earn().ethereum().incentive().claim('insert-wallet-id', {
      chain: 'base',
      authorization_context: {
        authorization_private_keys: ['<authorization-private-key>'],
      },
    });
    ```

    The method returns an `EarnIncentiveClaimActionResponse` with the pending wallet action. Claims operate at the chain level and collect rewards across all vaults on the specified chain.
  </Tab>

  <Tab title="REST API">
    To claim rewards via REST API, make a `POST` request to:

    ```bash theme={"system"}
    https://auth.privy.io/api/v1/wallets/{wallet_id}/earn/ethereum/incentive/claim
    ```

    #### Parameters

    <ParamField path="chain" type="string" required>
      The blockchain network on which to perform the incentive claim (e.g. `"base"`, `"ethereum"`, `"arbitrum"`). Claims collect rewards across all vaults on the specified chain.
    </ParamField>

    <Info>
      Wallets with `owner_id` present must provide an [authorization
      signature](/api-reference/authorization-signatures) as a request header for claim operations.
    </Info>

    #### Returns

    <ResponseField name="id" type="string">
      The wallet action ID. Use this to poll status with [get wallet action](/api-reference/wallets/actions/get).
    </ResponseField>

    <ResponseField name="wallet_id" type="string">
      The ID of the wallet claiming rewards.
    </ResponseField>

    <ResponseField name="type" type="string">
      The action type. Always `"earn_incentive_claim"` for this endpoint.
    </ResponseField>

    <ResponseField name="status" type="'pending' | 'succeeded' | 'rejected' | 'failed'">
      The current status of the claim action.
    </ResponseField>

    <ResponseField name="chain" type="string">
      The chain name for the claim.
    </ResponseField>

    <ResponseField name="rewards" type="array | null">
      List of rewards claimed, each with `token_address`, `token_symbol`, `token_decimals`, and `amount`. Populated after the preparation step fetches claimable rewards.
    </ResponseField>

    <ResponseField name="created_at" type="string">
      ISO 8601 timestamp of when the action was created.
    </ResponseField>

    <ResponseField name="steps" type="array | undefined">
      The execution steps. Only returned if `?include=steps` is provided on a GET request.
    </ResponseField>

    #### Example

    ```bash theme={"system"}
    curl -X POST https://auth.privy.io/api/v1/wallets/{wallet_id}/earn/ethereum/incentive/claim \
      -H "privy-app-id: <your-app-id>" \
      -H "Authorization: Basic <credentials>" \
      -H "Content-Type: application/json" \
      -d '{
        "chain": "base"
      }'
    ```

    ```json Example response theme={"system"}
    {
      "id": "<action-id>",
      "wallet_id": "<your-wallet-id>",
      "type": "earn_incentive_claim",
      "status": "pending",
      "chain": "base",
      "rewards": [
        {
          "token_address": "0x1234567890abcdef1234567890abcdef12345678",
          "token_symbol": "MORPHO",
          "token_decimals": 18,
          "amount": "115631364898103632676"
        }
      ],
      "created_at": "2025-04-01T12:00:00.000Z"
    }
    ```
  </Tab>
</Tabs>

<Info>
  A `rejected` status means the action failed before any transaction was signed or broadcast — for
  example, due to insufficient balance or a policy violation. Your app can safely retry the request.
  A `failed` status means a transaction was broadcast but reverted onchain. Inspect the action's
  `steps` for details.
</Info>

## Next steps

<Card title="Claim rewards" icon="gift" href="/wallets/actions/earn/claim" arrow>
  Collect additional token incentives distributed by the vault.
</Card>
