Withdrawal
To initiate a withdrawal from a Morpho's vault using the DeFi API, follow these steps:
- Retrieve the schema with the step list to check which transactions are required.
- Prepare the withdrawal transaction.
- 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 casewithdraw.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 thestepNamerequest 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 isencodedor 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.
SummaryIn this schema example, the
stepsresponse array includes one step calledfinalWithdrawTransaction.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'scanExecuteInParallelfield.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 thenameresponse field of the Get Transaction Step Schema endpoint. In this case, it isfinalWithdrawTransaction.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_SIGNorDONE.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 thenameresponse 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:encodedandjson(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 inencodedorjson(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
- Sign the final
jsonorencodedtransaction object from theresult.payloadfield. - Broadcast it to the network by sending a POST request to /api/defi/v1/transactions/steps/broadcast.
What's next?
- Sign and Broadcast Transaction
- DeFi API reference