API reference
Payouts API: M-Pesa B2C payouts and reversals
POST /payout to send money out (B2C) and POST /reversal to refund a completed transaction.
Both endpoints move money out of your shortcode. Both endpoints are asynchronous. The HTTP call acknowledges with 202. paylod delivers the final result to your webhook. For both endpoints you must set the application's Initiator Name and Initiator Password.
On a production application you cannot reverse these two operations. Put your own authorisation in front of them. Never expose them to a client.
POST /payout
B2C payout — send money from your shortcode to a customer.
POST https://paylod.dev/functions/v1/payoutBody
| Field | Type | Required | Description |
|---|---|---|---|
amount | integer | Required | Whole KES to send, 1–150000. |
phone | string | Required | Recipient MSISDN (0712…, 254712…, +254712…). paylod normalises it for you. |
commandId | string | Optional | SalaryPayment, BusinessPayment, or PromotionPayment. Defaults to BusinessPayment. |
remarks | string | Optional | Free-text remarks. Up to 100 chars. |
occasion | string | Optional | Occasion label. Up to 100 chars. |
Example
[!note] No paylod SDK wraps /payout yet. The SDKs cover collect and status only. Call this endpoint with the HTTP client of your language, as below.
const res = await fetch("https://paylod.dev/functions/v1/payout", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAYLOD_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
amount: 2500,
phone: "254712345678",
commandId: "BusinessPayment",
remarks: "Payout for July",
}),
});
const { disbursementId, conversationId } = await res.json();{
"disbursementId": "d3f1a2b3-…",
"conversationId": "AG_20260707_0000c1d2e3f4",
"status": "pending"
}paylod sends the final result to your webhook as an HMAC-signed payout.result event. Correlate that event with disbursementId or conversationId.
POST /reversal
Reverse or refund a completed transaction to the customer.
POST https://paylod.dev/functions/v1/reversalBody
| Field | Type | Required | Description |
|---|---|---|---|
transactionId | string | Required | The M-Pesa receipt to reverse. |
amount | integer | Required | Whole KES, 1–150000. Must match the original transaction amount. |
remarks | string | Optional | Free-text remarks. Up to 100 chars. |
occasion | string | Optional | Occasion label. Up to 100 chars. |
Example
const res = await fetch("https://paylod.dev/functions/v1/reversal", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAYLOD_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
transactionId: "UG1F3A1U7J",
amount: 2500,
remarks: "Customer refund",
}),
});
const { disbursementId, conversationId } = await res.json();{
"disbursementId": "f7e6d5c4-…",
"conversationId": "AG_20260707_0000a9b8c7d6",
"status": "pending"
}paylod sends the result to your webhook as an HMAC-signed refund.result event.