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

# Withdrawal

> Withdraw staked assets on Polygon with the P2P.org Staking API.

The withdrawal process in the Polygon network using the Staking API can be done following these steps:

1. Undelegate staked tokens.
2. Unstake tokens — available after the undelegate period.
3. Withdraw unstaked tokens.

After each operation, [sign and send the transaction](/docs/signing-transaction-polygon) to the Polygon network.

<Steps>
  <Step title="Undelegate staked tokens">
    Prepare previously staked tokens to unstake by sending a POST request to [​/api​/v1​/polygon​/staking​/undelegate](/reference/polygon-staking-undelegate).

    Example request:

    <CodeGroup>
      ```bash curl theme={null}
      curl --request POST \
      		 --url https://api.p2p.org/api/v1/polygon/staking/undelegate \
           --head 'accept: application/json' \
           --head 'Authorization: Bearer <token>' \
           --head 'Content-Type: application/json' \
           --data '
      {
        "amount": "100000000000000000",
        "stakerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17"
      }
      '
      ```

      ```typescript TypeScript theme={null}
      const response = await fetch("https://api.p2p.org/api/v1/polygon/staking/undelegate", {
        method: "POST",
        headers: {
          "Authorization": "Bearer <token>",
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          "amount": "100000000000000000",
          "stakerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17"
        }),
      });
      const data = await response.json();
      console.log(data);
      ```

      ```python Python theme={null}
      import requests

      response = requests.post(
          "https://api.p2p.org/api/v1/polygon/staking/undelegate",
          headers={
              "Authorization": "Bearer <token>",
              "Content-Type": "application/json",
          },
          json={
              "amount": "100000000000000000",
              "stakerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17"
          },
      )
      print(response.json())
      ```

      ```go Go theme={null}
      package main

      import (
      	"bytes"
      	"encoding/json"
      	"fmt"
      	"io"
      	"net/http"
      )

      func main() {
      	payload := map[string]interface{}{
      		"amount": "100000000000000000",
      		"stakerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
      	}
      	body, _ := json.Marshal(payload)
      	req, _ := http.NewRequest("POST", "https://api.p2p.org/api/v1/polygon/staking/undelegate", bytes.NewBuffer(body))
      	req.Header.Set("Authorization", "Bearer <token>")
      	req.Header.Set("Content-Type", "application/json")
      	resp, _ := http.DefaultClient.Do(req)
      	defer resp.Body.Close()
      	respBody, _ := io.ReadAll(resp.Body)
      	fmt.Println(string(respBody))
      }
      ```
    </CodeGroup>

    * `amount` — amount of tokens in Wei (1 POL = 10¹⁸ Wei) to undelegate.
    * `stakerAddress` — staker account address.

    Example response:

    <CodeGroup>
      ```json theme={null}
      {
          "result": {
            "serializeTx": "0x02f86505800214830186a094499d11e0b6eac7c0593d8fb292dcbbf815fb29ae80b844095ea7b300000000000000000000000000200ea4ee292e253e6ca07dba5edc07c8aa37a3000000000000000000000000000000000000000000000000016345785d8a0000c0",
            "to": "0x499d11E0b6eAC7c0593d8Fb292DCBbF815Fb29Ae",
            "gasLimit": "0.0000000000001",
            "data": "0x095ea7b300000000000000000000000000200ea4ee292e253e6ca07dba5edc07c8aa37a3000000000000000000000000000000000000000000000000016345785d8a0000",
            "value": "0.0",
            "chainId": 1,
            "type": 2,
            "maxFeePerGas": "0.00000000000000002",
            "maxPriorityFeePerGas": "2"
          }
        }
      ```
    </CodeGroup>

    * `serializeTx` — serialized unsigned transaction.
    * `to` — recipient address for this transaction.
    * `gasLimit` — maximum gas limit for this block.
    * `data` — transaction data.
    * `value` — amount this transaction is sending in Wei.
    * `chainId` — chain ID this transaction is authorized on, as specified by [EIP-155](https://eips.ethereum.org/EIPS/eip-155).
    * `type` — [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) type of this transaction envelope.
    * `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee and this transaction's priority fee in Wei.
    * `maxPriorityFeePerGas` — price per unit of gas in Wei, which is added to the [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) block's base fee. This added fee is used to incentivize miners to prioritize this transaction.

    <Note>
      It takes up to 3-4 days to prepare your tokens for unstaking as Polygon uses a system of <Tooltip tip="On Polygon, a means of measure for the undelegate period. 1 checkpoint takes approximately 3 hours. However, some checkpoints could be delayed due to congestion on Ethereum. This period applies to the originally delegated amount and re-delegated amounts. It does not apply to any rewards that were not re-delegated.">checkpoints</Tooltip>. The average undelegate period on Polygon is 80 checkpoints.
    </Note>
  </Step>

  <Step title="Unstake tokens">
    After the undelegate period on Polygon is complete, unstake your tokens by sending a POST request to [/api/v1/polygon/staking/unstake](/reference/polygon-staking-unstake).

    Example request:

    <CodeGroup>
      ```bash curl theme={null}
      curl --request POST \
      		 --url https://api.p2p.org/api/v1/polygon/staking/unstake \
           --head 'accept: application/json' \
           --head 'Authorization: Bearer <token>' \
           --head 'Content-Type: application/json' \
           --data '
      {
        "unbondNonce": "100",
        "stakerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17"
      }
      '
      ```

      ```typescript TypeScript theme={null}
      const response = await fetch("https://api.p2p.org/api/v1/polygon/staking/unstake", {
        method: "POST",
        headers: {
          "Authorization": "Bearer <token>",
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          "unbondNonce": "100",
          "stakerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17"
        }),
      });
      const data = await response.json();
      console.log(data);
      ```

      ```python Python theme={null}
      import requests

      response = requests.post(
          "https://api.p2p.org/api/v1/polygon/staking/unstake",
          headers={
              "Authorization": "Bearer <token>",
              "Content-Type": "application/json",
          },
          json={
              "unbondNonce": "100",
              "stakerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17"
          },
      )
      print(response.json())
      ```

      ```go Go theme={null}
      package main

      import (
      	"bytes"
      	"encoding/json"
      	"fmt"
      	"io"
      	"net/http"
      )

      func main() {
      	payload := map[string]interface{}{
      		"unbondNonce": "100",
      		"stakerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
      	}
      	body, _ := json.Marshal(payload)
      	req, _ := http.NewRequest("POST", "https://api.p2p.org/api/v1/polygon/staking/unstake", bytes.NewBuffer(body))
      	req.Header.Set("Authorization", "Bearer <token>")
      	req.Header.Set("Content-Type", "application/json")
      	resp, _ := http.DefaultClient.Do(req)
      	defer resp.Body.Close()
      	respBody, _ := io.ReadAll(resp.Body)
      	fmt.Println(string(respBody))
      }
      ```
    </CodeGroup>

    * `unbondNonce` — unique identifier (<Tooltip tip="In cryptography, a value that can only be used once. An account nonce is a transaction counter in each account, which is used to prevent replay attacks.">nonce</Tooltip>) of the undelegate request.
    * `stakerAddress` — staker account address.

    Example response is the same as in the undelegate staked tokens step.
  </Step>

  <Step title="Withdraw unstaked tokens">
    Send a POST request to [/api/v1/polygon/staking/withdraw](/reference/polygon-staking-withdraw).

    Example request:

    <CodeGroup>
      ```bash curl theme={null}
      curl --request POST \
      		 --url https://api.p2p.org/api/v1/polygon/staking/withdraw \
           --head 'accept: application/json' \
           --head 'Authorization: Bearer <token>' \
           --head 'Content-Type: application/json' \
           --data '
      {
        "stakerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17"
      }
      '
      ```

      ```typescript TypeScript theme={null}
      const response = await fetch("https://api.p2p.org/api/v1/polygon/staking/withdraw", {
        method: "POST",
        headers: {
          "Authorization": "Bearer <token>",
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          "stakerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17"
        }),
      });
      const data = await response.json();
      console.log(data);
      ```

      ```python Python theme={null}
      import requests

      response = requests.post(
          "https://api.p2p.org/api/v1/polygon/staking/withdraw",
          headers={
              "Authorization": "Bearer <token>",
              "Content-Type": "application/json",
          },
          json={
              "stakerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17"
          },
      )
      print(response.json())
      ```

      ```go Go theme={null}
      package main

      import (
      	"bytes"
      	"encoding/json"
      	"fmt"
      	"io"
      	"net/http"
      )

      func main() {
      	payload := map[string]interface{}{
      		"stakerAddress": "0x39D02C253dA1d9F85ddbEB3B6Dc30bc1EcBbFA17",
      	}
      	body, _ := json.Marshal(payload)
      	req, _ := http.NewRequest("POST", "https://api.p2p.org/api/v1/polygon/staking/withdraw", bytes.NewBuffer(body))
      	req.Header.Set("Authorization", "Bearer <token>")
      	req.Header.Set("Content-Type", "application/json")
      	resp, _ := http.DefaultClient.Do(req)
      	defer resp.Body.Close()
      	respBody, _ := io.ReadAll(resp.Body)
      	fmt.Println(string(respBody))
      }
      ```
    </CodeGroup>

    * `stakerAddress` — staker account address.

    Example response is the same as in the two previous steps.

    To complete the withdrawal, [sign and send](/docs/signing-transaction-polygon) the transaction to the Polygon network.
  </Step>
</Steps>


## Related topics

- [Getting Started](/docs/staking-polygon.md)
- [Staking API reference](/reference/polygon-staking-approve.md)
