Withdrawal

To initiate a withdrawal from a Morpho's vault using the DeFi API, follow these steps:

  1. Retrieve the schema with the step list to check which transactions are required.
  2. Prepare the withdrawal transaction.
  3. Sign and broadcast the withdrawal transaction to the network.

Both partial and full withdrawal are possible.

Request examples are provided using cURL.

1. Get schema

To retrieve a list of steps required to perform a withdrawal, send a GET request to /api/defi/v1/transactions/schema.

Example request (for base chain and Steakhouse USDC strategy):

curl --request GET \
     --url GET 'https://edge.p2p.org/api/defi/v1/transactions/schema?action=withdraw&chain=base&protocol=morpho&strategy=Steakhouse%20USDC' \
     --header 'accept: application/json' \
     --header 'authorization: Bearer <token>'
  • action — operation type; in this case withdraw.
  • chain — blockchain network, e.g., base.
  • protocol— integration name, e.g., morpho.
  • strategy — vault name, e.g., Steakhouse USDC.
  • x-client-hash — unique identifier of the user or merchant participating in the integration; obtained with the authentication token.

Example response:

{
  "error": null,
  "result": {
    "action": "withdraw",
    "steps": [
      {
        "index": 0,
        "name": "finalWithdrawTransaction",
        "description": "Create final withdraw transaction",
        "inputs": [
          {
            "key": "amount",
            "type": "string",
            "description": "Withdraw amount in token smallest unit",
            "required": true
          },
          {
            "key": "asset",
            "type": "string",
            "description": "Asset symbol (e.g., USDC, USDT)",
            "required": true
          },
          {
            "key": "proxyAddress",
            "type": "string",
            "description": "P2P Proxy address",
            "required": true
          }
        ],
        "outputs": [
          {
            "key": "json",
            "type": "object",
            "description": "Built withdraw transaction data (to, data, value, chainId)"
          },
          {
            "key": "encoded",
            "type": "string",
            "description": "Built withdraw transaction as encoded function data"
          }
        ],
        "groupId": 0,
        "canExecuteInParallel": false,
        "isUnsignedTransaction": true
      }
    ],
    "stepGroups": [
      [
        0
      ]
    ]
  },
  "meta": {
    "time": 18,
    "requestId": "5406b88f-b94d-4027-97cd-29af077cbef1"
  }
}
  • action — operation type.
  • steps — schema with the list of steps describing which transactions you have to construct using the Craft Transaction Step endpoint.
    • index — step number in the execution order.
    • name — transaction type corresponding to the stepName request parameter of the Craft Transaction Step endpoint.
    • description — detailed information on the step purpose.
    • inputs — list of request parameters required to construct a transaction, e.g., wallet address, amount of tokens, etc. It can include the transactions that require a signature as well.
      • key — parameter name.
      • type — parameter object format.
      • description — detailed information on the parameter.
      • required — boolean flag indicating if this parameter is necessary for the request.
    • outputs — list of fields expected in the transaction response.
      • key — raw transaction payload ready for signing which is encoded or an optionaljson.
      • type — transaction payload format.
      • description — detailed information on the payload contents.
    • groupID — identifier of the group to which this step belongs.
    • canExecuteInParallel — boolean flag indicating if it is possible to perform this step asynchronously. By executing in parallel, you can initiate the construction of multiple transactions at the same time.
      • true — step can be performed asynchronously.
      • false — step can only be performed synchronously.
    • isUnsignedTransaction — boolean flag indicating if the result of the step is a transaction that must be signed and broadcasted.
  • stepGroups — groups of steps that can be executed in parallel; currently is not operational.
  • meta — API request attributes:
    • time — request execution time in ms.
    • requestId — unique identifier of the request.
👍

Summary

In this schema example, the steps response array includes one step called finalWithdrawTransaction.

It means that to withdraw funds from the vault, you have to prepare only one transaction and then sign and broadcast it.

2. Prepare withdrawal transaction

To withdraw funds from the vault, send a POST request to /api/defi/v1/transactions/steps/craft.

Example request (for base chain and Steakhouse USDC strategy):

curl --request GET \
  --url GET 'https://edge.p2p.org/api/defi/v1/transactions/steps/craft' \
  --header 'accept: application/json' \
  --header 'authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
  "chain": "base",
  "action": "withdraw",
  "protocol": "morpho",
  "strategy": "Steakhouse USDC",
  "userAddress": "0x0000000000000000000000000000000000000001",
  "options": {
    "executionMode": "sync"
  },
  "stepName": "finalWithdrawTransaction",
  "payload": {
    "amount": "100000",
    "asset": "USDC",
    "proxyAddress": "0x0000000000000000000000000000000000000001"
  }
}'
  • chain — blockchain network.
  • action — operation type.
  • protocol— integration name.
  • strategy — vault name.
  • userAddress — user wallet address.
  • options.executeMode — DeFi API request processing mode. The recommended value can be found in the schema's canExecuteInParallel field.
    • sync — synchronous; default for some networks so that the blockchain does not reverse the block in which the transaction is included. In this mode, before continuing with other steps, you have to wait until the API operation is fully completed and the transaction is returned.
    • async — asynchronous. In this mode, after sending the request, you can continue with other steps according to the schema and periodically check the request status with the Get Step Crafting Status endpoint.
  • stepName — step name corresponding to the name response field of the Get Transaction Step Schema endpoint. In this case, it is finalWithdrawTransaction.
  • payload — transaction data:
    • amount — amount of tokens to withdraw.
    • asset — token denomination, e.g., USDC.
    • proxyAddress — P2P.ORG proxy address used to perform the deposit. To retrieve this address, send a GET response to the Get User Positions endpoint.

Example response:

{
  "error": null,
  "result": {
    "operationId": "mock-operation-id-abc123",
    "chain": "base",
    "action": "withdraw",
    "status": "READY_FOR_SIGN",
    "protocol": "morpho",
    "strategy": "Steakhouse USDC",
    "userAddress": "0x0000000000000000000000000000000000000001",
    "stepList": [
      {
        "index": 0,
        "type": "transaction",
        "name": "finalWithdrawTransaction",
        "description": "Create final withdraw transaction",
        "payload": {
          "json": {
            "chainId": 8453,
            "to": "0x0000000000000000000000000000000000000002",
            "nonce": 0,
            "value": "0",
            "data": "0xdeadbeef",
            "maxFeePerGas": "1000000000",
            "maxPriorityFeePerGas": "100000000",
            "gas": "300000",
            "type": "eip1559"
          },
          "encoded": "0x02f8..."
        },
        "verifierMeta": {
          "signature": "0x0000000000000000000000000000000000000000000000000000000000000000"
        }
      }
    ],
    "payload": {
      "json": {
        "chainId": 8453,
        "to": "0x0000000000000000000000000000000000000002",
        "nonce": 0,
        "value": "0",
        "data": "0xdeadbeef",
        "maxFeePerGas": "1000000000",
        "maxPriorityFeePerGas": "100000000",
        "gas": "300000",
        "type": "eip1559"
      },
      "encoded": "0x02f8..."
    },
    "verifierMeta": {
      "signature": "0x0000000000000000000000000000000000000000000000000000000000000000"
    },
    "createdAt": "2026-02-13T12:00:00.000Z",
    "updatedAt": "2026-02-13T12:00:00.000Z"
  },
  "meta": {
    "time": 100,
    "requestId": "mock-request-id-xyz789"
  }
}
  • operationId — unique identifier of the transaction.
  • chain — blockchain network.
  • action — operation type.
  • status — current transaction status: AWAITING_CRAFT, IN_PROGRESS, READY_FOR_SIGN or DONE.
  • protocol— integration name.
  • strategy — vault name.
  • userAddress — user wallet address.
  • stepList — list of fields with the step results obtained according to the schema:
    • index — step number in the execution order.
    • type — field object format.
    • name — step name corresponding to the name response field of the Get Transaction Step Schema endpoint.
    • description — detailed information on the step purpose.
    • payload — raw transaction object ready for signing represented in two formats: encoded and json (optional).
    • verifierMeta — data object received from P2P.ORG's verifier module.
      • signature — signature provided by the verifier module, which confirms that the transaction was crafted and then cryptographically verified by P2P.ORG.
  • payload — final transaction payload represented either in encoded or json (optional) format.
  • verifierMeta — final transaction data object received from the verifier module.
  • createdAt — timestamp of the transaction creation in the ISO 8601 format.
  • updatedAt — timestamp of the transaction update in the ISO 8601 format.
  • meta — API request attributes:
    • time — request execution time in ms.
    • requestId — unique identifier of the request.

3. Sign and broadcast transaction

  1. Sign the final json or encoded transaction object from the result.payload field.
  2. Broadcast it to the network by sending a POST request to /api/defi/v1/transactions/steps/broadcast.

What's next?