Send a Payout
Sending a payout takes two calls: create a Payout Request, then execute it. Then you track its status until the funds reach the recipient.
The Organization must be approved (kycStatus.type is approved), and so must its Parent Organization if it has one. Otherwise both create and execute return a 403 KycApprovalRequiredException.
Create the Payout Request
Use the create Payout Request endpoint with the on-behalf-of header. Use the Account you funded as sourceAccountId. The example pays 40 USDC to a bank account in Colombia, in Colombian Pesos (COP).
Each fiat rail has its own request body. Set the rail in the type field of fiatAndRailDetails. For the supported rails, see Fiat Rail Codes.
In production, create a Counterparty and Payout Method for your recipient instead of sending all the recipient details in each request.
Example request
curl --request POST \
--url https://api-staging.muralpay.com/api/payouts/payout \
--header "accept: application/json" \
--header "authorization: Bearer $MURAL_API_KEY" \
--header "content-type: application/json" \
--header "on-behalf-of: $ORGANIZATION_ID" \
--data @- <<EOF
{
"sourceAccountId": "$ACCOUNT_ID",
"memo": "December contract",
"payouts": [
{
"amount": {
"tokenSymbol": "USDC",
"tokenAmount": 40
},
"payoutDetails": {
"type": "fiat",
"bankName": "Bancamia S.A.",
"bankAccountOwner": "Javier Gomez",
"fiatAndRailDetails": {
"type": "cop",
"symbol": "COP",
"accountType": "CHECKING",
"phoneNumber": "+57 601 555 5555",
"bankAccountNumber": "1234567890123456",
"documentNumber": "1234563",
"documentType": "NATIONAL_ID"
}
},
"recipientInfo": {
"type": "individual",
"firstName": "Javier",
"lastName": "Gomez",
"email": "[email protected]",
"physicalAddress": {
"address1": "Cra. 37 #10A 29",
"country": "CO",
"state": "Antioquia",
"city": "Medellin",
"zip": "050015"
}
}
}
]
}
EOFThe new Payout Request has statusV2.type awaitingExecution. Save its id from the response:
export PAYOUT_REQUEST_ID="<id from the response>"Execute the Payout Request
Use the execute Payout Request endpoint with the transfer-api-key header. The source Account must hold enough to cover the full Payout Request, or execution fails.
Example request
curl --request POST \
--url https://api-staging.muralpay.com/api/payouts/payout/$PAYOUT_REQUEST_ID/execute \
--header "accept: application/json" \
--header "authorization: Bearer $MURAL_API_KEY" \
--header "on-behalf-of: $ORGANIZATION_ID" \
--header "transfer-api-key: $MURAL_TRANSFER_API_KEY"The Payout Request is now processing. In the sandbox, no funds move and the payout completes on its own. To test failed and slow payouts, see Simulated Payments.
Get the Payout Request status
Use the get Payout Request endpoint to track the Payout Request and each payout in it.
Example request
curl --request GET \
--url https://api-staging.muralpay.com/api/payouts/payout/$PAYOUT_REQUEST_ID \
--header "accept: application/json" \
--header "authorization: Bearer $MURAL_API_KEY" \
--header "on-behalf-of: $ORGANIZATION_ID"Payout Request statuses
statusV2.type covers the start of every payout in the Payout Request. executed does not mean each recipient has received the funds. For that, check the status of each payout in payouts. The status field is deprecated; use statusV2.
awaitingExecution: the Payout Request was created and is waiting to be executed.pending: the Payout Request is being executed.executed: the Payout Request was executed and the funds left your Account. Blockchain payouts are complete. Fiat payouts have started and are pending delivery. Terminal.failed: execution failed. Terminal.canceled: the Payout Request was canceled. Terminal.
Fiat payout statuses
Each fiat payout reports its status in details.fiatPayoutStatus.type:
created: the payout was created but not executed.pending: the local banking provider received the funds and is processing them.on-hold: the payout is on hold for compliance review. To resolve it, contact [email protected].refundInProgress: the payout failed and a refund has started.refunded: the payout failed and the refund is complete. Terminal.completed: the funds were sent to the recipient. Terminal.failed: the payout failed. The response has the details. Terminal.canceled: the payout was canceled. The response has the details. Terminal.
Blockchain payout statuses
Each blockchain payout reports its status in details.status:
AWAITING_EXECUTION: the transaction was created and is waiting to be executed.PENDING: the transaction is being executed.EXECUTED: the transaction was executed. Terminal.FAILED: the transaction failed. Terminal.CANCELED: the transaction was canceled. Terminal.
Updated 8 days ago

