> ## 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 Story Protocol with the P2P.org Staking API.

The withdrawal process on the Story Protocol using the Staking API consists of two main steps:

1. Create an unstaking request.
2. Create a withdrawal request.

After each operation, [sign and broadcast the transaction](/docs/signing-transaction-solana) to the Story network.

<Note>
  **Please note**

  The unstaking process may take some time depending on the staking configuration. Make sure the lock-up period has passed before attempting to withdraw.
</Note>

<Steps>
  <Step title="Create unstaking request">
    1. Send a POST request to [/api/v1/story/\{network}/staking/unstake](/reference/story-staking-unstake).

       Example request (for `aeneid` network):

    <CodeGroup>
      ```bash curl theme={null}
      curl --request POST \
           --url https://api-test.p2p.org/api/v1/story/aeneid/staking/unstake \
           --header 'accept: application/json' \
           --header 'authorization: Bearer <token>' \
           --header 'content-type: application/json' \
           --data '{
             "delegatorAddress": "0x3202B5B0602274197CcB22B8c02CEC9539990c7c",
             "amount": 512,
             "gas": {
               "maxFeePerGas": 100,
               "maxPriorityFeePerGas": 1,
               "gasLimit": 21000
             }
           }'
      ```

      ```typescript TypeScript theme={null}
      const response = await fetch("https://api-test.p2p.org/api/v1/story/aeneid/staking/unstake", {
        method: "POST",
        headers: {
          "Authorization": "Bearer <token>",
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          "delegatorAddress": "0x3202B5B0602274197CcB22B8c02CEC9539990c7c",
          "amount": 512,
          "gas": {
            "maxFeePerGas": 100,
            "maxPriorityFeePerGas": 1,
            "gasLimit": 21000
          }
        }),
      });
      const data = await response.json();
      console.log(data);
      ```

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

      response = requests.post(
          "https://api-test.p2p.org/api/v1/story/aeneid/staking/unstake",
          headers={
              "Authorization": "Bearer <token>",
              "Content-Type": "application/json",
          },
          json={
              "delegatorAddress": "0x3202B5B0602274197CcB22B8c02CEC9539990c7c",
              "amount": 512,
              "gas": {
                  "maxFeePerGas": 100,
                  "maxPriorityFeePerGas": 1,
                  "gasLimit": 21000
              }
          },
      )
      print(response.json())
      ```

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

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

      func main() {
      	payload := map[string]interface{}{
      		"delegatorAddress": "0x3202B5B0602274197CcB22B8c02CEC9539990c7c",
      		"amount": 512,
      		"gas": map[string]interface{}{
      			"maxFeePerGas": 100,
      			"maxPriorityFeePerGas": 1,
      			"gasLimit": 21000,
      		},
      	}
      	body, _ := json.Marshal(payload)
      	req, _ := http.NewRequest("POST", "https://api-test.p2p.org/api/v1/story/aeneid/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>

    * `delegatorAddress` — delegator EVM Story account address.

    * `amount` — amount of tokens to unstake in IP.

    * `gas` — optional gas settings to execute the transaction:

      * `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined 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 block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
      * `gasLimit` — maximum gas limit for the transaction.

    Example response:

    <CodeGroup>
      ```json theme={null}
      {
          "result": {
            "unsignedTransaction": "0xf86e808504a817c80082520894c32e3d7c7e6e53d16b9a48d0ae76c70e6adf09f080801ba0f31401df9e6f6d861fdf09d1e69b5f51855f4f63b0179033a6c3871c05ec93da03e0f7d7eab4a3179b29b416d6c75dbe53de763153b7ed9e2c49883c8fca1ef29c",
            "createdAt": "2025-07-22T12:34:56.789Z"
          }
        }
      ```
    </CodeGroup>

    * `unsignedTransaction` — serialized unsigned transaction in the hexadecimal format (RLP-encoded). Sign the transaction and submit it to the blockchain to perform the called action. Note that it must be signed and broadcasted within \~1 minute.

    * `createdAt` — timestamp of the transaction in the ISO 8601 format.

    2. Use `unsignedTransaction` to [sign and send](/docs/signing-transaction-story) the signed transaction to the Story network.
  </Step>

  <Step title="Create withdrawal request">
    1. Send a POST request to [/api/v1/story/\{network}/staking/withdraw](ref:).

       Example request (for `aeneid` network):

    <CodeGroup>
      ```bash curl theme={null}
      curl --request POST \
           --url https://api-test.p2p.org/api/v1/story/aeneid/staking/withdraw \
           --header 'Authorization: Bearer <token>' \
           --header 'Content-Type: application/json' \
           --data '{
             "delegatorAddress": "0x3202B5B0602274197CcB22B8c02CEC9539990c7c",
             "amount": 512,
             "gas": {
               "maxFeePerGas": 100,
               "maxPriorityFeePerGas": 1,
               "gasLimit": 21000
             }
           }'
      ```

      ```typescript TypeScript theme={null}
      const response = await fetch("https://api-test.p2p.org/api/v1/story/aeneid/staking/withdraw", {
        method: "POST",
        headers: {
          "Authorization": "Bearer <token>",
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          "delegatorAddress": "0x3202B5B0602274197CcB22B8c02CEC9539990c7c",
          "amount": 512,
          "gas": {
            "maxFeePerGas": 100,
            "maxPriorityFeePerGas": 1,
            "gasLimit": 21000
          }
        }),
      });
      const data = await response.json();
      console.log(data);
      ```

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

      response = requests.post(
          "https://api-test.p2p.org/api/v1/story/aeneid/staking/withdraw",
          headers={
              "Authorization": "Bearer <token>",
              "Content-Type": "application/json",
          },
          json={
              "delegatorAddress": "0x3202B5B0602274197CcB22B8c02CEC9539990c7c",
              "amount": 512,
              "gas": {
                  "maxFeePerGas": 100,
                  "maxPriorityFeePerGas": 1,
                  "gasLimit": 21000
              }
          },
      )
      print(response.json())
      ```

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

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

      func main() {
      	payload := map[string]interface{}{
      		"delegatorAddress": "0x3202B5B0602274197CcB22B8c02CEC9539990c7c",
      		"amount": 512,
      		"gas": map[string]interface{}{
      			"maxFeePerGas": 100,
      			"maxPriorityFeePerGas": 1,
      			"gasLimit": 21000,
      		},
      	}
      	body, _ := json.Marshal(payload)
      	req, _ := http.NewRequest("POST", "https://api-test.p2p.org/api/v1/story/aeneid/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>

    * `delegatorAddress` — delegator EVM Story account address.

    * `amount` — amount of tokens to withdraw in IP.

    * `gas` — optional gas settings to execute the transaction:

      * `maxFeePerGas` — maximum price per unit of gas this transaction will pay for the combined 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 block's base fee. This added fee is used to incentivize miners to prioritize this transaction.
      * `gasLimit` — maximum gas limit for the transaction.

    Example response:

    <CodeGroup>
      ```json theme={null}
      {
          "result": {
            "unsignedTransaction": "0xf86e808504a817c80082520894c32e3d7c7e6e53d16b9a48d0ae76c70e6adf09f080801ba0f31401df9e6f6d861fdf09d1e69b5f51855f4f63b0179033a6c3871c05ec93da03e0f7d7eab4a3179b29b416d6c75dbe53de763153b7ed9e2c49883c8fca1ef29c",
            "createdAt": "2025-07-22T12:45:00.123Z"
          }
        }
      ```
    </CodeGroup>

    * `unsignedTransaction` — serialized unsigned transaction in the hexadecimal format (RLP-encoded). Sign the transaction and submit it to the blockchain to perform the called action. Note that it must be signed and broadcasted within \~1 minute.

    * `createdAt` — timestamp of the transaction in the ISO 8601 format.

    2. Use `unsignedTransaction` to [sign and send](/docs/signing-transaction-story) the signed transaction to the Story Protocol network.
  </Step>
</Steps>


## Related topics

- [Staking API reference](/reference/story-staking-stake.md)
